/// <summary> /// Initializes a new instance of the <see cref="NodeConstructingArgs"/> class. /// </summary> /// <param name="containerObjectDescriptor">The descriptor of the container of the member being constructed, or of the object itself it is a root object.</param> /// <param name="memberDescriptor">The member descriptor of the object being constructed if it is a member, or <c>null</c> otherwise.</param> public NodeConstructingArgs(ObjectDescriptor containerObjectDescriptor, MemberDescriptorBase memberDescriptor) { if (containerObjectDescriptor == null) throw new ArgumentNullException("containerObjectDescriptor"); ContainerObjectDescriptor = containerObjectDescriptor; MemberDescriptor = memberDescriptor; ShouldProcessReference = true; }
/// <inheritdoc/> public override void VisitObjectMember(object container, ObjectDescriptor containerDescriptor, IMemberDescriptor member, object value) { if (CurrentPath.Match(MemberPath)) VisitAssetMember(value, member.TypeDescriptor); else base.VisitObjectMember(container, containerDescriptor, member, value); }
/// <inheritdoc /> public override void VisitObject(object obj, ObjectDescriptor descriptor, bool visitMembers) { if (CurrentPath.Match(MemberPath)) VisitAssetMember(obj, descriptor); else base.VisitObject(obj, descriptor, visitMembers); }
internal static void AddSourceHashesMember(ObjectDescriptor objectDescriptor, List<IMemberDescriptor> memberDescriptors) { var type = objectDescriptor.Type; if (!typeof(Asset).IsAssignableFrom(type)) return; memberDescriptors.Add(SourceHashesDynamicMember.Default); }
public override void VisitObject(object obj, ObjectDescriptor descriptor, bool visitMembers) { var reference = obj as IContentReference; if (reference != null) { CollectedGuids.Add(reference.Id); } base.VisitObject(obj, descriptor, visitMembers); }
/// <inheritdoc/> public override void VisitObject(object obj, ObjectDescriptor descriptor, bool visitMembers) { var shouldRemove = context.EnterNode(descriptor.Type); if (context.SerializeAsReference) { Result.Add(new AssetPartReference { AssetPart = obj, Path = CurrentPath.Clone() }); } else { base.VisitObject(obj, descriptor, visitMembers); } context.LeaveNode(descriptor.Type, shouldRemove); }
public override void VisitObjectMember(object container, ObjectDescriptor containerDescriptor, IMemberDescriptor member, object value) { if (!AcceptMember(member)) { return; } var node = stackItems.Peek(); var newNode = new DataVisitMember(value, member); AddMember(node, newNode); stackItems.Push(newNode); base.VisitObjectMember(container, containerDescriptor, member, value); stackItems.Pop(); }
/// <inheritdoc/> public override void VisitObject(object obj, ObjectDescriptor descriptor, bool visitMembers) { ITypeDescriptor currentDescriptor = descriptor; bool isRootNode = contextStack.Count == 0; if (isRootNode) { bool shouldProcessReference; if (!NotifyNodeConstructing(descriptor, out shouldProcessReference)) return; // If we are in the case of a collection of collections, we might have a root node that is actually an enumerable reference // This would be the case for each collection within the base collection. IContent content = descriptor.Type.IsStruct() ? ContentFactory.CreateBoxedContent(this, obj, descriptor, IsPrimitiveType(descriptor.Type)) : ContentFactory.CreateObjectContent(this, obj, descriptor, IsPrimitiveType(descriptor.Type), shouldProcessReference); currentDescriptor = content.Descriptor; rootNode = (GraphNode)NodeFactory(currentDescriptor.Type.Name, content, rootGuid); if (content.IsReference && currentDescriptor.Type.IsStruct()) throw new QuantumConsistencyException("A collection type", "A structure type", rootNode); if (content.IsReference) referenceContents.Add(content); AvailableCommands.Where(x => x.CanAttach(currentDescriptor, null)).ForEach(rootNode.AddCommand); NotifyNodeConstructed(content); if (obj == null) { rootNode.Seal(); return; } PushContextNode(rootNode); } if (!IsPrimitiveType(currentDescriptor.Type)) { base.VisitObject(obj, descriptor, true); } if (isRootNode) { PopContextNode(); rootNode.Seal(); } }
public override void VisitObject(object obj, ObjectDescriptor descriptor, bool visitMembers) { var localInNonIdentifiableType = false; try { if (descriptor.Attributes.OfType<NonIdentifiableCollectionItemsAttribute>().Any()) { localInNonIdentifiableType = true; inNonIdentifiableType++; } base.VisitObject(obj, descriptor, visitMembers); } finally { if (localInNonIdentifiableType) inNonIdentifiableType--; } }
public override void VisitObjectMember(object container, ObjectDescriptor containerDescriptor, IMemberDescriptor member, object value) { if (sourceFiles != null) { if (member.Type == typeof(UFile) && value != null) { var file = (UFile)value; if (!string.IsNullOrWhiteSpace(file.ToString())) { var attribute = member.GetCustomAttributes<SourceFileMemberAttribute>(true).SingleOrDefault(); if (attribute != null) { if (!sourceFiles.ContainsKey(file)) { sourceFiles.Add(file, attribute.UpdateAssetIfChanged); } else if (attribute.UpdateAssetIfChanged) { // If the file has already been collected, just update whether it should update the asset when changed sourceFiles[file] = true; } } } } } if (sourceMembers != null) { if (member.Type == typeof(UFile)) { var attribute = member.GetCustomAttributes<SourceFileMemberAttribute>(true).SingleOrDefault(); if (attribute != null) { sourceMembers[CurrentPath.Clone()] = value as UFile; } } } base.VisitObjectMember(container, containerDescriptor, member, value); }
/// <summary> /// Creates a type descriptor for the specified type. /// </summary> /// <param name="type">The type.</param> /// <returns>An instance of type descriptor.</returns> protected virtual ITypeDescriptor Create(Type type) { ITypeDescriptor descriptor; // The order of the descriptors here is important if (PrimitiveDescriptor.IsPrimitive(type)) { descriptor = new PrimitiveDescriptor(this, type); } else if (DictionaryDescriptor.IsDictionary(type)) // resolve dictionary before collections, as they are also collections { // IDictionary descriptor = new DictionaryDescriptor(this, type); } else if (CollectionDescriptor.IsCollection(type)) { // ICollection descriptor = new CollectionDescriptor(this, type); } else if (type.IsArray) { // array[] descriptor = new ArrayDescriptor(this, type); } else if (NullableDescriptor.IsNullable(type)) { descriptor = new NullableDescriptor(this, type); } else { // standard object (class or value type) descriptor = new ObjectDescriptor(this, type); } return(descriptor); }
public override void VisitObjectMember(object container, ObjectDescriptor containerDescriptor, IMemberDescriptor member, object value) { base.VisitObjectMember(container, containerDescriptor, member, value); var assetReference = value as AssetReference; var assetBase = value as AssetBase; var attachedReference = value != null ? AttachedReferenceManager.GetAttachedReference(value) : null; if (assetReference != null) { AddLink(assetReference, (guid, location) => { var newValue = AssetReference.New(member.Type, guid.HasValue ? guid.Value : assetReference.Id, location); member.Set(container, newValue); return newValue; }); } else if (assetBase != null) { AddLink(assetBase, (guid, location) => { var newValue = new AssetBase(location, assetBase.Asset); member.Set(container, newValue); return newValue; }); } else if (attachedReference != null) { AddLink(attachedReference, (guid, location) => { object newValue = guid.HasValue && guid.Value != Guid.Empty ? AttachedReferenceManager.CreateSerializableVersion(member.Type, guid.Value, location) : null; member.Set(container, newValue); return newValue; }); } else if (value is UFile) { AddLink(value, (guid, location) => { var newValue = new UFile(location); member.Set(container, newValue); return newValue; }); } else if (value is UDirectory) { AddLink(value, (guid, location) => { var newValue = new UDirectory(location); member.Set(container, newValue); return newValue; }); } }
public virtual void VisitObjectMember(object container, ObjectDescriptor containerDescriptor, IMemberDescriptor member, object value) { Visit(value, member.TypeDescriptor); }
public virtual void VisitObject(object obj, ObjectDescriptor descriptor, bool visitMembers) { if (!obj.GetType().IsArray && visitMembers) { foreach (var member in descriptor.Members) { CurrentPath.Push(member); VisitObjectMember(obj, descriptor, member, member.Get(obj)); CurrentPath.Pop(); } } switch (descriptor.Category) { case DescriptorCategory.Array: VisitArray((Array)obj, (ArrayDescriptor)descriptor); break; case DescriptorCategory.Collection: VisitCollection((IEnumerable)obj, (CollectionDescriptor)descriptor); break; case DescriptorCategory.Dictionary: VisitDictionary(obj, (DictionaryDescriptor)descriptor); break; } }
/// <summary> /// Initializes a new instance of the <see cref="NodeConstructingArgs"/> class. /// </summary> /// <param name="containerObjectDescriptor">The descriptor of the container of the member being constructed, or of the object itself it is a root object.</param> /// <param name="memberDescriptor">The member descriptor of the object being constructed if it is a member, or <c>null</c> otherwise.</param> public NodeConstructingArgs(ObjectDescriptor containerObjectDescriptor, MemberDescriptorBase memberDescriptor) { if (containerObjectDescriptor == null) throw new ArgumentNullException(nameof(containerObjectDescriptor)); ContainerObjectDescriptor = containerObjectDescriptor; MemberDescriptor = memberDescriptor; }
/// <summary> /// Creates a type descriptor for the specified type. /// </summary> /// <param name="type">The type.</param> /// <returns>An instance of type descriptor.</returns> protected virtual ITypeDescriptor Create(Type type) { ITypeDescriptor descriptor; // The order of the descriptors here is important if (PrimitiveDescriptor.IsPrimitive(type)) { descriptor = new PrimitiveDescriptor(this, type, emitDefaultValues, namingConvention); } else if (DictionaryDescriptor.IsDictionary(type)) // resolve dictionary before collections, as they are also collections { // IDictionary descriptor = new DictionaryDescriptor(this, type, emitDefaultValues, namingConvention); } else if (CollectionDescriptor.IsCollection(type)) { // ICollection descriptor = new CollectionDescriptor(this, type, emitDefaultValues, namingConvention); } else if (type.IsArray) { // array[] descriptor = new ArrayDescriptor(this, type, emitDefaultValues, namingConvention); } else if (NullableDescriptor.IsNullable(type)) { descriptor = new NullableDescriptor(this, type, emitDefaultValues, namingConvention); } else { // standard object (class or value type) descriptor = new ObjectDescriptor(this, type, emitDefaultValues, namingConvention); } return descriptor; }
public override void VisitObjectMember(object container, ObjectDescriptor containerDescriptor, IMemberDescriptor member, object value) { if (typeof(Asset).IsAssignableFrom(member.DeclaringType) && member.Name == nameof(Asset.Archetype) && value != null) { dependencies.AddBrokenLinkOut((AssetReference)value, ContentLinkType.Inheritance | ContentLinkType.Reference); return; } base.VisitObjectMember(container, containerDescriptor, member, value); }
public override void VisitObject(object obj, ObjectDescriptor descriptor, bool visitMembers) { bool processObject = true; ++scriptComponentDepth; if (componentDepth >= 1) { var entity = obj as Entity; if (entity != null) { Result.EntityReferences.Add(new EntityLink(currentReferencer, entity, CurrentPath.Clone())); processObject = false; } var entityComponent = obj as EntityComponent; if (entityComponent != null) { Result.EntityReferences.Add(new EntityLink(currentReferencer, entityComponent, CurrentPath.Clone())); processObject = false; } } else { var entity = obj as Entity; if (entity != null) currentReferencer = entity; var settings = obj as SceneSettings; if (settings != null) currentReferencer = settings; } if (scriptComponentDepth != 2 && obj is Script) { Result.EntityReferences.Add(new EntityLink(currentReferencer, (Script)obj, CurrentPath.Clone())); processObject = false; } if (obj is EntityComponent || obj is SceneSettings) componentDepth++; if (obj is ScriptComponent) scriptComponentDepth = 0; if (processObject) base.VisitObject(obj, descriptor, visitMembers); if (obj is EntityComponent || obj is SceneSettings) componentDepth--; --scriptComponentDepth; }
/// <summary> /// Raises the <see cref="NodeConstructing"/> event. /// </summary> /// <param name="containerDescriptor">The descriptor of the container of the member being constructed, or of the object itself it is a root object.</param> /// <param name="member">The member descriptor of the member being constructed.</param> /// <param name="shouldProcessReference">Indicates whether the reference that will be created in the node should be processed or not.</param> /// <returns><c>true</c> if the node should be constructed, <c>false</c> if it should be discarded.</returns> /// <remarks>This method is internal so it can be used by the <see cref="ModelConsistencyCheckVisitor"/>.</remarks> internal bool NotifyNodeConstructing(ObjectDescriptor containerDescriptor, IMemberDescriptor member, out bool shouldProcessReference) { var handler = NodeConstructing; if (handler != null) { var args = new NodeConstructingArgs(containerDescriptor, (MemberDescriptorBase)member); handler(this, args); shouldProcessReference = !args.Discard && args.ShouldProcessReference; return !args.Discard; } shouldProcessReference = true; return true; }
/// <inheritdoc/> public override void VisitObject(object obj, ObjectDescriptor descriptor, bool visitMembers) { var node = GetContextNode(); var referenceInfo = GetReferenceInfo(descriptor.Type, obj); if (node.Content.Reference == null) { if (referenceInfo != null && (node != rootNode || referenceInfo.ReferenceType == typeof(ReferenceEnumerable))) throw new QuantumConsistencyException("Content with a reference", "Content without reference", node); var memberCount = descriptor.Members.Count(); if (node.Children.Count != memberCount) throw new QuantumConsistencyException("A node with [{0}] children", memberCount.ToStringSafe(), "A node with [{0}] children", node.Children.Count.ToStringSafe(), node); PushContextNode(node); base.VisitObject(obj, descriptor, true); PopContextNode(); } else { if (referenceInfo == null) throw new QuantumConsistencyException("Content without reference", "Content with a reference", node); if (node.Content.Reference.GetType() != referenceInfo.ReferenceType) throw new QuantumConsistencyException("Content with a [{0}]", referenceInfo.ReferenceType.Name, "Content with a [{0}]", node.Content.Reference.GetType().Name, node); if (!Equals(node.Content.Value, obj)) throw new QuantumConsistencyException("The node content value [{0}]", obj.ToStringSafe(), "The node content value [{0}]", node.Content.Value.ToStringSafe(), node); if (node.Children.Count > 0) throw new QuantumConsistencyException("A node with a reference and no child", null, "A node with a reference and [{0}] children", node.Children.Count.ToStringSafe(), node); AddReference(node, node.Content.Reference); } }
public override void VisitObject(object obj, ObjectDescriptor descriptor, bool visitMembers) { // references and base var reference = obj as IReference; if (reference == null) { var attachedReference = AttachedReferenceManager.GetAttachedReference(obj); if (attachedReference != null && attachedReference.IsProxy) reference = attachedReference; } if (reference != null) { dependencies.AddBrokenLinkOut(reference, ContentLinkType.Reference); } else { base.VisitObject(obj, descriptor, visitMembers); } }
public override void VisitObjectMember(object container, ObjectDescriptor containerDescriptor, IMemberDescriptor member, object value) { // Don't visit base parts as they are visited at the top level. if (typeof(Asset).IsAssignableFrom(member.DeclaringType) && (member.Name == "~BaseParts")) { return; } base.VisitObjectMember(container, containerDescriptor, member, value); }
public override void VisitObjectMember(object container, ObjectDescriptor containerDescriptor, IMemberDescriptor member, object value) { if (ProcessObject(value, member.TypeDescriptor.Type)) return; base.VisitObjectMember(container, containerDescriptor, member, value); }
public override void VisitObject(object obj, ObjectDescriptor descriptor, bool visitMembers) { // references and base var reference = obj as IContentReference; if (reference == null) { var attachedReference = AttachedReferenceManager.GetAttachedReference(obj); if (attachedReference != null && attachedReference.IsProxy) reference = new AttachedContentReference(attachedReference); } if (reference != null) { var isBase = reference is AssetBase; // Don't record base import if (isBase && ((AssetBase)reference).IsRootImport) return; dependencies.AddBrokenLinkOut(reference, (isBase ? ContentLinkType.Inheritance: 0) | ContentLinkType.Reference); } else { base.VisitObject(obj, descriptor, visitMembers); } }
/// <inheritdoc/> public override void VisitObjectMember(object container, ObjectDescriptor containerDescriptor, IMemberDescriptor member, object value) { bool shouldProcessReference; if (!NotifyNodeConstructing(containerDescriptor, member, out shouldProcessReference)) return; // If this member should contains a reference, create it now. GraphNode containerNode = GetContextNode(); IContent content = ContentFactory.CreateMemberContent(this, containerNode.Content, member, IsPrimitiveType(member.Type), value, shouldProcessReference); var node = (GraphNode)NodeFactory(member.Name, content, Guid.NewGuid()); containerNode.AddChild(node); if (content.IsReference) referenceContents.Add(content); PushContextNode(node); if (!(content.Reference is ObjectReference)) { // For enumerable references, we visit the member to allow VisitCollection or VisitDictionary to enrich correctly the node. Visit(content.Value); } PopContextNode(); AvailableCommands.Where(x => x.CanAttach(node.Content.Descriptor, (MemberDescriptorBase)member)).ForEach(node.AddCommand); NotifyNodeConstructed(content); node.Seal(); }
/// <inheritdoc/> public override void VisitObjectMember(object container, ObjectDescriptor containerDescriptor, IMemberDescriptor member, object value) { bool shouldProcessReference; if (!nodeBuilder.NotifyNodeConstructing(containerDescriptor, member, out shouldProcessReference)) return; var node = GetContextNode(); GraphNode child; try { child = (GraphNode)node.Children.Single(x => x.Name == member.Name); } catch (InvalidOperationException) { throw new QuantumConsistencyException("A single child node [{0}]", member.Name, "No child or multiple children [{0}]", member.Name, node); } if (!IsPrimitiveType(child.Content.Type)) { PushContextNode(child); Visit(value); PopContextNode(); } }
public override void VisitObject(object obj, ObjectDescriptor descriptor, bool visitMembers) { if (obj is Asset && !ReferenceEquals(obj, rootAsset)) { assets.Add((Asset)obj); } base.VisitObject(obj, descriptor, visitMembers); }
/// <summary> /// Initializes a new instance of the <see cref="DataVisitObjectNode" /> class. /// </summary> /// <param name="instance">The instance.</param> /// <param name="instanceDescriptor">The instance descriptor.</param> /// <exception cref="System.ArgumentNullException"> /// instance /// or /// instanceDescriptor /// </exception> public DataVisitObjectNode(object instance, ObjectDescriptor instanceDescriptor) : base(instance, instanceDescriptor) { }
/// <summary> /// Raises the <see cref="NodeConstructing"/> event. /// </summary> /// <param name="descriptor">The descriptor of the root object being constructed.</param> /// <param name="shouldProcessReference">Indicates whether the reference that will be created in the node should be processed or not.</param> /// <returns><c>true</c> if the node should be constructed, <c>false</c> if it should be discarded.</returns> /// <remarks>This method is internal so it can be used by the <see cref="ModelConsistencyCheckVisitor"/>.</remarks> internal bool NotifyNodeConstructing(ObjectDescriptor descriptor, out bool shouldProcessReference) { var handler = NodeConstructing; if (handler != null) { var args = new NodeConstructingArgs(descriptor, null); handler(this, args); shouldProcessReference = !args.Discard && args.ShouldProcessReference; return !args.Discard; } shouldProcessReference = true; return true; }