4 using System.Collections;
5 using System.Collections.Generic;
6 using System.Reflection;
8 namespace SiliconStudio.Core.Reflection
15 private readonly HashSet<object> visitedObjects =
new HashSet<object>(ReferenceEqualityComparer<object>.Default);
16 private readonly Dictionary<Type, IDataCustomVisitor> mapTypeToCustomVisitors =
new Dictionary<Type, IDataCustomVisitor>();
42 if (typeDescriptorFactory == null)
throw new ArgumentNullException(
"typeDescriptorFactory");
44 CustomVisitors =
new List<IDataCustomVisitor>();
46 context.Visitor =
this;
60 public List<IDataCustomVisitor> CustomVisitors {
get;
private set; }
85 visitedObjects.Clear();
116 var objectType = obj.GetType();
117 if (descriptor == null || descriptor.
Type != objectType)
119 descriptor = TypeDescriptorFactory.Find(objectType);
124 descriptor = TypeDescriptorFactory.Find(((NullableDescriptor)descriptor).UnderlyingType);
127 context.Instance = obj;
132 case DescriptorCategory.Primitive:
139 if (!mapTypeToCustomVisitors.TryGetValue(objectType, out customVisitor) && CustomVisitors.Count > 0)
141 for (
int i = CustomVisitors.Count - 1; i >= 0; i--)
143 var dataCustomVisitor = CustomVisitors[i];
144 if (dataCustomVisitor.CanVisit(objectType))
146 customVisitor = dataCustomVisitor;
147 mapTypeToCustomVisitors.Add(objectType, dataCustomVisitor);
153 if (customVisitor != null)
155 customVisitor.Visit(ref context);
159 VisitObject(obj, context.Descriptor,
true);
176 if (!obj.GetType().IsArray && visitMembers)
178 foreach (var member
in descriptor.
Members)
180 CurrentPath.Push(member);
181 VisitObjectMember(obj, descriptor, member, member.Get(obj));
188 case DescriptorCategory.Array:
191 case DescriptorCategory.Collection:
194 case DescriptorCategory.Dictionary:
207 for (
int i = 0; i < array.Length; i++)
209 var value = array.GetValue(i);
210 CurrentPath.Push(descriptor, i);
218 Visit(item, itemDescriptor);
224 foreach (var item
in collection)
226 CurrentPath.Push(descriptor, i);
235 Visit(item, itemDescriptor);
240 foreach (var keyValue
in descriptor.GetEnumerator(dictionary))
242 var key = keyValue.Key;
243 var keyDescriptor = keyValue.Key == null ? null : TypeDescriptorFactory.Find(keyValue.Key.GetType());
244 var value = keyValue.Value;
245 var valueDescriptor = keyValue.Value == null ? null : TypeDescriptorFactory.Find(keyValue.Value.GetType());
247 CurrentPath.Push(descriptor, key);
248 VisitDictionaryKeyValue(dictionary, descriptor, key, keyDescriptor, value, valueDescriptor);
255 Visit(key, keyDescriptor);
256 Visit(value, valueDescriptor);
259 private bool CanVisit(
object obj)
262 if (obj.GetType().GetTypeInfo().IsValueType)
267 if (visitedObjects.Contains(obj))
271 visitedObjects.Add(obj);
DescriptorCategory Category
Provides a descriptor for a System.Collections.ICollection.
virtual void VisitArrayItem(Array array, ArrayDescriptor descriptor, int index, object item, ITypeDescriptor itemDescriptor)
Visits an array item.
A default implementation for the ITypeDescriptorFactory.
DescriptorCategory Category
Gets the category of this descriptor.
DataVisitorBase(IAttributeRegistry attributeRegistry)
Initializes a new instance of the DataVisitorBase class.
virtual void VisitArray(Array array, ArrayDescriptor descriptor)
Visits an array.
ITypeDescriptor TypeDescriptor
Default implementation of a ITypeDescriptor.
virtual void VisitDictionaryKeyValue(object dictionary, DictionaryDescriptor descriptor, object key, ITypeDescriptor keyDescriptor, object value, ITypeDescriptor valueDescriptor)
Visits a dictionary key-value.
Type Type
Gets the type described by this instance.
void Visit(object obj)
Visits the specified object.
A visitor for serializable data (binary, yaml and editor).
Describe a member of an object.
Interface for visiting serializable data (binary, yaml and editor).
virtual void VisitCollectionItem(IEnumerable collection, CollectionDescriptor descriptor, int index, object item, ITypeDescriptor itemDescriptor)
Visits a collection item.
Provides a descriptor for a System.Collections.IDictionary.
Describes a descriptor for a primitive (bool, char, sbyte, byte, int, uint, long, ulong...
Describes a descriptor for a nullable type Nullable{T}.
virtual void VisitPrimitive(object primitive, PrimitiveDescriptor descriptor)
Visits a primitive (int, float, string...etc.)
A registry for all attributes.
virtual void VisitObject(object obj, ObjectDescriptor descriptor, bool visitMembers)
Visits an object (either a class or a struct)
virtual void VisitNull()
Visits a null.
Allows to get/set a property/field value on a deeply nested object instance (supporting members...
ITypeDescriptor Find(Type type)
Tries to create an instance of a ITypeDescriptor from the type. Return null if this factory is not ha...
DataVisitorBase(ITypeDescriptorFactory typeDescriptorFactory)
Initializes a new instance of the DataVisitorBase class.
virtual void VisitObjectMember(object container, ObjectDescriptor containerDescriptor, IMemberDescriptor member, object value)
Visits an object member.
A custom visitor used by DataVisitorBase.
IEnumerable< IMemberDescriptor > Members
Provides access members of a type.
SiliconStudio.Core.Reflection.AttributeRegistry AttributeRegistry
virtual void VisitDictionary(object dictionary, DictionaryDescriptor descriptor)
Visits a dictionary.
virtual void Reset()
Resets this instance (clears the cache of visited objects).
A descriptor for an array.
virtual void VisitCollection(IEnumerable collection, CollectionDescriptor descriptor)
Visits a collection.
A factory to create an instance of a ITypeDescriptor
DataVisitorBase()
Initializes a new instance of the DataVisitorBase class.
A default implementation for IAttributeRegistry. This implementation allows to retrieve default attri...
void Visit(object obj, ITypeDescriptor descriptor)
Visits the specified object.