Exemple #1
0
        public void TestPushIndexAndMember()
        {
            var obj = new Class {
                ListMember = { new Class(), new Class(), new Class() }
            };
            var nodeContainer = new NodeContainer();
            var rootNode      = nodeContainer.GetOrCreateNode(obj);
            var path          = new GraphNodePath(rootNode);

            path.PushMember(nameof(Class.ListMember));
            path.PushTarget();
            path.PushIndex(new NodeIndex(1));
            path.PushMember(nameof(Class.IntMember));
            var targetNode = nodeContainer.GetNode(obj.ListMember[1]);
            var intNode    = targetNode[nameof(Class.IntMember)];
            var nodes      = new IGraphNode[] { rootNode, rootNode[nameof(Class.ListMember)], rootNode[nameof(Class.ListMember)].Target, targetNode, intNode };

            Assert.NotNull(targetNode);
            Assert.NotNull(intNode);
            Assert.False(path.IsEmpty);
            AssertAreEqual(rootNode, path.RootNode);
            AssertAreEqual(intNode, path.GetNode());
            var i = 0;

            foreach (var node in path)
            {
                AssertAreEqual(nodes[i++], node);
            }
            AssertAreEqual(nodes.Length, i);
        }
Exemple #2
0
 public void TestCloneNewRoot()
 {
     var obj1 = new Class { ClassMember = new Class(), ListMember = { new Class(), new Class(), new Class() } };
     var obj2 = new Class { ClassMember = new Class(), ListMember = { new Class(), new Class(), new Class() } };
     var nodeContainer = new NodeContainer();
     var newRoot = nodeContainer.GetOrCreateNode(obj2);
     var path1 = new GraphNodePath(nodeContainer.GetOrCreateNode(obj1));
     var clone = path1.Clone(newRoot);
     Assert.AreNotEqual(newRoot, path1.RootNode);
     Assert.AreEqual(newRoot, clone.RootNode);
     Assert.AreEqual(path1.IsValid, clone.IsValid);
     Assert.AreEqual(path1.IsEmpty, clone.IsEmpty);
     var path2 = path1.PushMember(nameof(Class.ClassMember)).PushTarget().PushMember(nameof(Class.IntMember));
     clone = path2.Clone(newRoot);
     Assert.AreNotEqual(newRoot, path2.RootNode);
     Assert.AreEqual(newRoot, clone.RootNode);
     Assert.AreEqual(path2.IsValid, clone.IsValid);
     Assert.AreEqual(path2.IsEmpty, clone.IsEmpty);
     var path3 = path1.PushMember(nameof(Class.ListMember)).PushIndex(new Index(1)).PushMember(nameof(Class.IntMember));
     clone = path3.Clone(newRoot);
     Assert.AreNotEqual(newRoot, path3.RootNode);
     Assert.AreEqual(newRoot, clone.RootNode);
     Assert.AreEqual(path3.IsValid, clone.IsValid);
     Assert.AreEqual(path3.IsEmpty, clone.IsEmpty);
 }
Exemple #3
0
        public void TestCloneNewRoot()
        {
            var obj1 = new Class {
                ClassMember = new Class(), ListMember = { new Class(), new Class(), new Class() }
            };
            var obj2 = new Class {
                ClassMember = new Class(), ListMember = { new Class(), new Class(), new Class() }
            };
            var nodeContainer = new NodeContainer();
            var newRoot       = nodeContainer.GetOrCreateNode(obj2);
            var path1         = new GraphNodePath(nodeContainer.GetOrCreateNode(obj1));
            var clone         = path1.Clone(newRoot);

            Assert.AreNotEqual(newRoot, path1.RootNode);
            Assert.AreEqual(newRoot, clone.RootNode);
            Assert.AreEqual(path1.IsValid, clone.IsValid);
            Assert.AreEqual(path1.IsEmpty, clone.IsEmpty);
            var path2 = path1.PushMember(nameof(Class.ClassMember)).PushTarget().PushMember(nameof(Class.IntMember));

            clone = path2.Clone(newRoot);
            Assert.AreNotEqual(newRoot, path2.RootNode);
            Assert.AreEqual(newRoot, clone.RootNode);
            Assert.AreEqual(path2.IsValid, clone.IsValid);
            Assert.AreEqual(path2.IsEmpty, clone.IsEmpty);
            var path3 = path1.PushMember(nameof(Class.ListMember)).PushIndex(new Index(1)).PushMember(nameof(Class.IntMember));

            clone = path3.Clone(newRoot);
            Assert.AreNotEqual(newRoot, path3.RootNode);
            Assert.AreEqual(newRoot, clone.RootNode);
            Assert.AreEqual(path3.IsValid, clone.IsValid);
            Assert.AreEqual(path3.IsEmpty, clone.IsEmpty);
        }
        public void TestClone()
        {
            var obj = new Class {
                ClassMember = new Class(), ListMember = { new Class(), new Class(), new Class() }
            };
            var nodeContainer = new NodeContainer();
            var path1         = new GraphNodePath(nodeContainer.GetOrCreateNode(obj));
            var clone         = path1.Clone();

            AssertAreEqual(path1, clone);
            AssertAreEqual(path1.GetHashCode(), clone.GetHashCode());
            AssertAreEqual(path1.RootNode, clone.RootNode);
            AssertAreEqual(path1.IsValid, clone.IsValid);
            AssertAreEqual(path1.IsEmpty, clone.IsEmpty);
            AssertAreEqual(path1.GetNode(), clone.GetNode());
            var path2 = path1.PushMember(nameof(Class.ClassMember)).PushTarget().PushMember(nameof(Class.IntMember));

            clone = path2.Clone();
            AssertAreEqual(path2, clone);
            AssertAreEqual(path2.RootNode, clone.RootNode);
            AssertAreEqual(path2.IsValid, clone.IsValid);
            AssertAreEqual(path2.IsEmpty, clone.IsEmpty);
            AssertAreEqual(path2.GetNode(), clone.GetNode());
            var path3 = path1.PushMember(nameof(Class.ListMember)).PushIndex(new Index(1)).PushMember(nameof(Class.IntMember));

            clone = path3.Clone();
            AssertAreEqual(path3, clone);
            AssertAreEqual(path3.RootNode, clone.RootNode);
            AssertAreEqual(path3.IsValid, clone.IsValid);
            AssertAreEqual(path3.IsEmpty, clone.IsEmpty);
            AssertAreEqual(path3.GetNode(), clone.GetNode());
        }
Exemple #5
0
        public void TestPushStructMember()
        {
            var obj = new Class {
                StructMember = { StringMember = "aa" }
            };
            var nodeContainer = new NodeContainer();
            var rootNode      = nodeContainer.GetOrCreateNode(obj);
            var path          = new GraphNodePath(rootNode);

            path.PushMember(nameof(Class.StructMember));
            path.PushTarget();
            path.PushMember(nameof(Struct.StringMember));
            var structNode = rootNode[nameof(Class.StructMember)];
            var targetNode = rootNode[nameof(Class.StructMember)].Target;
            var memberNode = rootNode[nameof(Class.StructMember)].Target[nameof(Struct.StringMember)];
            var nodes      = new IGraphNode[] { rootNode, structNode, targetNode, memberNode };

            Assert.NotNull(targetNode);
            Assert.NotNull(memberNode);
            Assert.False(path.IsEmpty);
            AssertAreEqual(rootNode, path.RootNode);
            AssertAreEqual(memberNode, path.GetNode());
            var i = 0;

            foreach (var node in path)
            {
                AssertAreEqual(nodes[i++], node);
            }
            AssertAreEqual(nodes.Length, i);
        }
Exemple #6
0
        public void TestGetParent()
        {
            var obj = new Class {
                StructMember = { StringMember = "aa" }, ClassMember = new Class(), ListMember = { new Class(), new Class(), new Class() }
            };
            var nodeContainer = new NodeContainer();
            var rootNode      = nodeContainer.GetOrCreateNode(obj);

            var path = new GraphNodePath(rootNode);

            path.PushMember(nameof(Class.IntMember));
            var parentPath = new GraphNodePath(rootNode);

            AssertAreEqual(parentPath, path.GetParent());

            path = new GraphNodePath(rootNode);
            path.PushMember(nameof(Class.StructMember));
            path.PushMember(nameof(Struct.StringMember));
            parentPath = new GraphNodePath(rootNode);
            parentPath.PushMember(nameof(Class.StructMember));
            AssertAreEqual(parentPath, path.GetParent());

            path = new GraphNodePath(rootNode);
            path.PushMember(nameof(Class.ClassMember));
            path.PushTarget();
            parentPath = new GraphNodePath(rootNode);
            parentPath.PushMember(nameof(Class.ClassMember));
            AssertAreEqual(parentPath, path.GetParent());

            path = new GraphNodePath(rootNode);
            path.PushMember(nameof(Class.ClassMember));
            path.PushTarget();
            path.PushMember(nameof(Class.IntMember));
            parentPath = new GraphNodePath(rootNode);
            parentPath.PushMember(nameof(Class.ClassMember));
            parentPath.PushTarget();
            AssertAreEqual(parentPath, path.GetParent());

            path = new GraphNodePath(rootNode);
            path.PushMember(nameof(Class.ListMember));
            path.PushIndex(new NodeIndex(1));
            parentPath = new GraphNodePath(rootNode);
            parentPath.PushMember(nameof(Class.ListMember));
            AssertAreEqual(parentPath, path.GetParent());

            path = new GraphNodePath(rootNode);
            path.PushMember(nameof(Class.ListMember));
            path.PushIndex(new NodeIndex(1));
            path.PushMember(nameof(Class.IntMember));
            parentPath = new GraphNodePath(rootNode);
            parentPath.PushMember(nameof(Class.ListMember));
            parentPath.PushIndex(new NodeIndex(1));
            AssertAreEqual(parentPath, path.GetParent());
        }
Exemple #7
0
        /// <inheritdoc/>
        public override GraphNodePath GetNodePath()
        {
            var path = new GraphNodePath(Editor.NodeContainer.GetNode(Asset.Asset));

            path.PushMember(nameof(EntityHierarchy.Hierarchy));
            path.PushTarget();
            path.PushMember(nameof(EntityHierarchy.Hierarchy.Parts));
            path.PushTarget();
            path.PushIndex(new NodeIndex(Id.ObjectId));
            path.PushMember(nameof(EntityDesign.Entity));
            path.PushTarget();
            return(path);
        }
        /// <inheritdoc/>
        GraphNodePath IAssetPropertyProviderViewModel.GetAbsolutePathToRootNode()
        {
            var asset = Method.Editor.Asset.Asset;
            var path  = new GraphNodePath(Method.Editor.Session.AssetNodeContainer.GetNode(asset));

            path.PushMember(nameof(VisualScriptAsset.Methods));
            path.PushTarget();
            path.PushIndex(new NodeIndex(asset.Methods.IndexOf(Method.Method.Method)));
            path.PushMember(nameof(Scripts.Method.Links));
            path.PushTarget();
            path.PushIndex(new NodeIndex(link.Id));
            path.PushTarget();
            return(path);
        }
Exemple #9
0
        public void TestPushTarget()
        {
            var obj = new Class {
                ClassMember = new Class()
            };
            var nodeContainer = new NodeContainer();
            var rootNode      = nodeContainer.GetOrCreateNode(obj);
            var path          = new GraphNodePath(rootNode);

            path.PushMember(nameof(Class.ClassMember));
            path.PushTarget();
            var targetNode = nodeContainer.GetNode(obj.ClassMember);
            var nodes      = new IGraphNode[] { rootNode, rootNode[nameof(Class.ClassMember)], targetNode };

            Assert.NotNull(targetNode);
            Assert.False(path.IsEmpty);
            AssertAreEqual(rootNode, path.RootNode);
            AssertAreEqual(targetNode, path.GetNode());
            var i = 0;

            foreach (var node in path)
            {
                AssertAreEqual(nodes[i++], node);
            }
            AssertAreEqual(nodes.Length, i);
        }
 public void TestClone()
 {
     var obj = new Class { ClassMember = new Class(), ListMember = { new Class(), new Class(), new Class() } };
     var nodeContainer = new NodeContainer();
     var path1 = new GraphNodePath(nodeContainer.GetOrCreateNode(obj));
     var clone = path1.Clone();
     AssertAreEqual(path1, clone);
     AssertAreEqual(path1.GetHashCode(), clone.GetHashCode());
     AssertAreEqual(path1.RootNode, clone.RootNode);
     AssertAreEqual(path1.IsValid, clone.IsValid);
     AssertAreEqual(path1.IsEmpty, clone.IsEmpty);
     AssertAreEqual(path1.GetNode(), clone.GetNode());
     var path2 = path1.PushMember(nameof(Class.ClassMember)).PushTarget().PushMember(nameof(Class.IntMember));
     clone = path2.Clone();
     AssertAreEqual(path2, clone);
     AssertAreEqual(path2.RootNode, clone.RootNode);
     AssertAreEqual(path2.IsValid, clone.IsValid);
     AssertAreEqual(path2.IsEmpty, clone.IsEmpty);
     AssertAreEqual(path2.GetNode(), clone.GetNode());
     var path3 = path1.PushMember(nameof(Class.ListMember)).PushIndex(new Index(1)).PushMember(nameof(Class.IntMember));
     clone = path3.Clone();
     AssertAreEqual(path3, clone);
     AssertAreEqual(path3.RootNode, clone.RootNode);
     AssertAreEqual(path3.IsValid, clone.IsValid);
     AssertAreEqual(path3.IsEmpty, clone.IsEmpty);
     AssertAreEqual(path3.GetNode(), clone.GetNode());
 }
Exemple #11
0
        /// <inheritdoc/>
        public override GraphNodePath GetNodePath()
        {
            var path = new GraphNodePath(Editor.NodeContainer.GetNode(Asset.Asset));

            path.PushMember(nameof(UIAsset.Hierarchy));
            path.PushTarget();
            return(path);
        }
Exemple #12
0
        /// <inheritdoc />
        protected override GraphNodePath GetNodePath()
        {
            var path = new GraphNodePath(Editor.Session.AssetNodeContainer.GetNode(Editor.Asset.Asset));

            path.PushMember(nameof(GraphicsCompositorAsset.Cameras));
            path.PushTarget();
            path.PushIndex(new Index(Editor.Asset.Asset.Cameras.IndexOf(CameraSlot)));
            return(path);
        }
Exemple #13
0
        /// <inheritdoc />
        protected override GraphNodePath GetNodePath()
        {
            var path = new GraphNodePath(Editor.Session.AssetNodeContainer.GetNode(Editor.Asset.Asset));

            path.PushMember(nameof(GraphicsCompositorAsset.SharedRenderers));
            path.PushTarget();
            path.PushIndex(new NodeIndex(Editor.Asset.Asset.SharedRenderers.IndexOf(sharedRenderer)));
            return(path);
        }
Exemple #14
0
        GraphNodePath IAssetPropertyProviderViewModel.GetAbsolutePathToRootNode()
        {
            var path = new GraphNodePath(Editor.Session.AssetNodeContainer.GetNode(Editor.Asset.Asset));

            path.PushMember(nameof(SpriteSheetAsset.Sprites));
            path.PushIndex(new NodeIndex(Index));
            path.PushTarget();
            return(path);
        }
Exemple #15
0
        public void TestSimpleObjectInitialPath()
        {
            var nodeContainer = new NodeContainer();
            var instance      = new SimpleClass {
                Member1 = 3, Member2 = new SimpleClass()
            };
            var rootNode  = nodeContainer.GetOrCreateNode(instance);
            var container = new SimpleClass {
                Member2 = instance
            };
            var containerNode = nodeContainer.GetOrCreateNode(container);
            var initialPath   = new GraphNodePath(containerNode);

            initialPath.PushMember(nameof(SimpleClass.Member2));
            initialPath.PushTarget();
            var visitor = new TestVisitor();

            visitor.Visit(rootNode, null, initialPath);
            var expectedNodes = new IGraphNode[]
            {
                rootNode,
                rootNode[nameof(SimpleClass.Member1)],
                rootNode[nameof(SimpleClass.Member2)],
                rootNode[nameof(SimpleClass.Member2)].Target,
                rootNode[nameof(SimpleClass.Member2)].Target[nameof(SimpleClass.Member1)],
                rootNode[nameof(SimpleClass.Member2)].Target[nameof(SimpleClass.Member2)],
            };
            var expectedPaths = new GraphNodePath[6];

            expectedPaths[0] = initialPath.Clone();
            expectedPaths[1] = initialPath.Clone();
            expectedPaths[1].PushMember(nameof(SimpleClass.Member1));
            expectedPaths[2] = initialPath.Clone();
            expectedPaths[2].PushMember(nameof(SimpleClass.Member2));
            expectedPaths[3] = expectedPaths[2].Clone();
            expectedPaths[3].PushTarget();
            expectedPaths[4] = expectedPaths[3].Clone();
            expectedPaths[4].PushMember(nameof(SimpleClass.Member1));
            expectedPaths[5] = expectedPaths[3].Clone();
            expectedPaths[5].PushMember(nameof(SimpleClass.Member2));
            VerifyNodesAndPath(expectedNodes, expectedPaths, visitor);
        }
Exemple #16
0
        private void GenerateChildren(IGraphNode targetNode, GraphNodePath targetNodePath)
        {
            // Node representing a member with a reference to another object
            if (SourceNode != targetNode && SourceNode.Content.IsReference)
            {
                var objectReference = SourceNode.Content.Reference as ObjectReference;
                // Discard the children of the referenced object if requested by the property provider
                if (objectReference != null && !Owner.PropertiesProvider.ShouldExpandReference(SourceNode.Content as MemberContent, objectReference))
                {
                    return;
                }

                var refEnum = SourceNode.Content.Reference as ReferenceEnumerable;
                if (refEnum != null)
                {
                    foreach (var reference in refEnum)
                    {
                        // Discard the children of the referenced object if requested by the property provider
                        if (reference != null && !Owner.PropertiesProvider.ShouldExpandReference(SourceNode.Content as MemberContent, reference))
                        {
                            return;
                        }
                    }
                }
            }

            var dictionary = targetNode.Content.Descriptor as DictionaryDescriptor;
            var list       = targetNode.Content.Descriptor as CollectionDescriptor;

            // Node containing a collection of references to other objects
            if (SourceNode == targetNode && targetNode.Content.IsReference)
            {
                var referenceEnumerable = targetNode.Content.Reference as ReferenceEnumerable;
                if (referenceEnumerable != null)
                {
                    // We create one node per item of the collection, unless requested by the property provide to not expand the reference.
                    foreach (var reference in referenceEnumerable)
                    {
                        // The type might be a boxed primitive type, such as float, if the collection has object as generic argument.
                        // In this case, we must set the actual type to have type converter working, since they usually can't convert
                        // a boxed float to double for example. Otherwise, we don't want to have a node type that is value-dependent.
                        var type           = reference.TargetNode != null && reference.TargetNode.Content.IsPrimitive ? reference.TargetNode.Content.Type : reference.Type;
                        var observableNode = Owner.ObservableViewModelService.ObservableNodeFactory(Owner, null, false, targetNode, targetNodePath, type, reference.Index);
                        AddChild(observableNode);
                        observableNode.Initialize();
                    }
                }
            }
            // Node containing a dictionary of primitive values
            else if (dictionary != null && targetNode.Content.Value != null)
            {
                // TODO: there is no way to discard items of such collections, without discarding the collection itself. Could this be needed at some point?
                // We create one node per item of the collection.
                foreach (var key in dictionary.GetKeys(targetNode.Content.Value))
                {
                    var index           = new Index(key);
                    var observableChild = Owner.ObservableViewModelService.ObservableNodeFactory(Owner, null, true, targetNode, targetNodePath, dictionary.ValueType, index);
                    AddChild(observableChild);
                    observableChild.Initialize();
                }
            }
            // Node containing a list of primitive values
            else if (list != null && targetNode.Content.Value != null)
            {
                // TODO: there is no way to discard items of such collections, without discarding the collection itself. Could this be needed at some point?
                // We create one node per item of the collection.
                for (int i = 0; i < list.GetCollectionCount(targetNode.Content.Value); ++i)
                {
                    var index           = new Index(i);
                    var observableChild = Owner.ObservableViewModelService.ObservableNodeFactory(Owner, null, true, targetNode, targetNodePath, list.ElementType, index);
                    AddChild(observableChild);
                    observableChild.Initialize();
                }
            }
            // Node containing a single non-reference primitive object
            else
            {
                foreach (var child in targetNode.Children)
                {
                    var memberContent    = (MemberContent)child.Content;
                    var descriptor       = (MemberDescriptorBase)memberContent.Member;
                    var displayAttribute = TypeDescriptorFactory.Default.AttributeRegistry.GetAttribute <DisplayAttribute>(descriptor.MemberInfo);
                    if (displayAttribute == null || displayAttribute.Browsable)
                    {
                        // The path is the source path here - the target path might contain the target resolution that we don't want at that point
                        if (Owner.PropertiesProvider.ShouldConstructMember(memberContent))
                        {
                            var childPath       = targetNodePath.PushMember(child.Name);
                            var observableChild = Owner.ObservableViewModelService.ObservableNodeFactory(Owner, child.Name, child.Content.IsPrimitive, child, childPath, child.Content.Type, Index.Empty);
                            AddChild(observableChild);
                            observableChild.Initialize();
                        }
                    }
                }
            }
        }
Exemple #17
0
        private void GenerateChildren(IContentNode targetNode, GraphNodePath targetNodePath, Index index)
        {
            // Set the default policy for expanding reference children.
            ExpandReferencePolicy = ExpandReferencePolicy.Full;

            // Node representing a member with a reference to another object
            if (SourceNode != targetNode && SourceNode.IsReference)
            {
                var objectReference = SourceNode.TargetReference ?? SourceNode.ItemReferences?[index];
                // Discard the children of the referenced object if requested by the property provider
                if (objectReference != null)
                {
                    ExpandReferencePolicy = Owner.PropertiesProvider.ShouldExpandReference(SourceNode as MemberContent, objectReference);
                    if (ExpandReferencePolicy == ExpandReferencePolicy.None)
                    {
                        return;
                    }
                }
            }

            var dictionary          = targetNode.Descriptor as DictionaryDescriptor;
            var list                = targetNode.Descriptor as CollectionDescriptor;
            var initializedChildren = new List <NodeViewModel>();

            // Node containing a collection of references to other objects
            if (SourceNode == targetNode && targetNode.IsReference)
            {
                var referenceEnumerable = targetNode.ItemReferences;
                if (referenceEnumerable != null)
                {
                    // We create one node per item of the collection, we will check later if the reference should be expanded.
                    foreach (var reference in referenceEnumerable)
                    {
                        // The type might be a boxed primitive type, such as float, if the collection has object as generic argument.
                        // In this case, we must set the actual type to have type converter working, since they usually can't convert
                        // a boxed float to double for example. Otherwise, we don't want to have a node type that is value-dependent.
                        var type  = reference.TargetNode != null && reference.TargetNode.IsPrimitive ? reference.TargetNode.Type : referenceEnumerable.ElementType;
                        var child = Owner.GraphViewModelService.GraphNodeViewModelFactory(Owner, null, false, targetNode, targetNodePath, type, reference.Index);
                        AddChild(child);
                        child.Initialize();
                        initializedChildren.Add(child);
                    }
                }
            }
            // Node containing a dictionary of primitive values
            else if (dictionary != null && targetNode.Value != null)
            {
                // TODO: there is no way to discard items of such collections, without discarding the collection itself. Could this be needed at some point?
                // We create one node per item of the collection.
                foreach (var key in dictionary.GetKeys(targetNode.Value))
                {
                    var newIndex = new Index(key);
                    var child    = Owner.GraphViewModelService.GraphNodeViewModelFactory(Owner, null, true, targetNode, targetNodePath, dictionary.ValueType, newIndex);
                    AddChild(child);
                    child.Initialize();
                    initializedChildren.Add(child);
                }
            }
            // Node containing a list of primitive values
            else if (list != null && targetNode.Value != null)
            {
                // TODO: there is no way to discard items of such collections, without discarding the collection itself. Could this be needed at some point?
                // We create one node per item of the collection.
                for (int i = 0; i < list.GetCollectionCount(targetNode.Value); ++i)
                {
                    var newIndex = new Index(i);
                    var child    = Owner.GraphViewModelService.GraphNodeViewModelFactory(Owner, null, true, targetNode, targetNodePath, list.ElementType, newIndex);
                    AddChild(child);
                    child.Initialize();
                    initializedChildren.Add(child);
                }
            }
            // Node containing a single non-reference primitive object
            else
            {
                var objectContent = (IObjectNode)targetNode;
                foreach (var memberContent in objectContent.Members)
                {
                    var descriptor       = (MemberDescriptorBase)memberContent.MemberDescriptor;
                    var displayAttribute = TypeDescriptorFactory.Default.AttributeRegistry.GetAttribute <DisplayAttribute>(descriptor.MemberInfo);
                    if (displayAttribute == null || displayAttribute.Browsable)
                    {
                        // The path is the source path here - the target path might contain the target resolution that we don't want at that point
                        if (Owner.PropertiesProvider.ShouldConstructMember(memberContent, ExpandReferencePolicy))
                        {
                            var childPath = targetNodePath.PushMember(memberContent.Name);
                            var child     = Owner.GraphViewModelService.GraphNodeViewModelFactory(Owner, memberContent.Name, memberContent.IsPrimitive, memberContent, childPath, memberContent.Type, Index.Empty);
                            AddChild(child);
                            child.Initialize();
                            initializedChildren.Add(child);
                        }
                    }
                }
            }

            // Call FinalizeInitialization on all created nodes after they were all initialized.
            foreach (var child in initializedChildren)
            {
                child.FinalizeInitialization();
            }
        }
Exemple #18
0
 private void GenerateChildren(IGraphNode modelNode, GraphNodePath graphNodePath)
 {
     if (modelNode.Content.IsReference && modelNode.Content.ShouldProcessReference)
     {
         var referenceEnumerable = modelNode.Content.Reference as ReferenceEnumerable;
         if (referenceEnumerable != null)
         {
             // If the reference should not be processed, we still need to create an observable node for each entry of the enumerable.
             // These observable nodes will have the same source node that their parent so we use this information to prevent
             // the infinite recursion that could occur due to the fact that these child nodes will have the same model nodes (like primitive types)
             // while holding an enumerable reference.
             //if (modelNode.Content.ShouldProcessReference || ModelNodeParent.sourceNode != modelNode)
             {
                 // Note: we are making a copy of the reference list because it can be updated from the Initialize method of the
                 // observable node in the case of scene objects. Doing this is a hack, but parts of this framework will be redesigned later to improve this
                 foreach (var reference in referenceEnumerable.ToList())
                 {
                     // The type might be a boxed primitive type, such as float, if the collection has object as generic argument.
                     // In this case, we must set the actual type to have type converter working, since they usually can't convert
                     // a boxed float to double for example. Otherwise, we don't want to have a node type that is value-dependent.
                     var  type            = reference.TargetNode != null && reference.TargetNode.Content.IsPrimitive ? reference.TargetNode.Content.Type : reference.Type;
                     bool shouldConstruct = Owner.PropertiesProvider.ShouldConstructNode(modelNode, reference.Index);
                     if (shouldConstruct)
                     {
                         var observableNode = Owner.ObservableViewModelService.ObservableNodeFactory(Owner, null, false, modelNode, graphNodePath, type, reference.Index);
                         AddChild(observableNode);
                         observableNode.Initialize();
                     }
                 }
             }
         }
     }
     else
     {
         var dictionary = modelNode.Content.Descriptor as DictionaryDescriptor;
         var list       = modelNode.Content.Descriptor as CollectionDescriptor;
         if (dictionary != null && modelNode.Content.Value != null)
         {
             // Dictionary of primitive objects
             foreach (var key in dictionary.GetKeys(modelNode.Content.Value))
             {
                 var  index           = new Index(key);
                 bool shouldConstruct = Owner.PropertiesProvider.ShouldConstructNode(modelNode, index);
                 if (shouldConstruct)
                 {
                     var observableChild = Owner.ObservableViewModelService.ObservableNodeFactory(Owner, null, true, modelNode, graphNodePath, dictionary.ValueType, index);
                     AddChild(observableChild);
                     observableChild.Initialize();
                 }
             }
         }
         else if (list != null && modelNode.Content.Value != null)
         {
             // List of primitive objects
             for (int i = 0; i < list.GetCollectionCount(modelNode.Content.Value); ++i)
             {
                 var  index           = new Index(i);
                 bool shouldConstruct = Owner.PropertiesProvider.ShouldConstructNode(modelNode, index);
                 if (shouldConstruct)
                 {
                     var observableChild = Owner.ObservableViewModelService.ObservableNodeFactory(Owner, null, true, modelNode, graphNodePath, list.ElementType, index);
                     AddChild(observableChild);
                     observableChild.Initialize();
                 }
             }
         }
         else
         {
             // Single non-reference primitive object
             foreach (var child in modelNode.Children)
             {
                 bool shouldConstruct = Owner.PropertiesProvider.ShouldConstructNode(child, Index.Empty);
                 if (shouldConstruct)
                 {
                     var childPath       = graphNodePath.PushMember(child.Name);
                     var observableChild = Owner.ObservableViewModelService.ObservableNodeFactory(Owner, child.Name, child.Content.IsPrimitive, child, childPath, child.Content.Type, Index.Empty);
                     AddChild(observableChild);
                     observableChild.Initialize();
                 }
             }
         }
     }
 }
 public void TestChangeStruct()
 {
     var nodeContainer = new NodeContainer();
     var obj = new[] { new Struct { Member1 = "aa" }, new Struct { Member1 = "bb" }, new Struct { Member1 = "cc" } };
     var instance = new ComplexClass { Member4 = obj[0] };
     var rootNode = nodeContainer.GetOrCreateNode(instance);
     var listener = new GraphNodeChangeListener(rootNode);
     var node = rootNode.GetChild(nameof(ComplexClass.Member4));
     var path = new GraphNodePath(rootNode).PushMember(nameof(ComplexClass.Member4));
     Assert.AreEqual("aa", node.GetChild(nameof(Struct.Member1)).Content.Retrieve());
     TestContentChange(listener, node, ContentChangeType.ValueChange, Index.Empty, obj[0], obj[1], path, () => node.Content.Update(obj[1]));
     Assert.AreEqual("bb", node.GetChild(nameof(Struct.Member1)).Content.Retrieve());
     TestContentChange(listener, node, ContentChangeType.ValueChange, Index.Empty, obj[1], obj[2], path, () => node.Content.Update(obj[2]));
     Assert.AreEqual("cc", node.GetChild(nameof(Struct.Member1)).Content.Retrieve());
     TestContentChange(listener, node.GetChild(nameof(Struct.Member1)), ContentChangeType.ValueChange, Index.Empty, "cc", "dd", path.PushMember(nameof(Struct.Member1)), () => node.GetChild(nameof(Struct.Member1)).Content.Update("dd"));
     Assert.AreEqual("dd", node.GetChild(nameof(Struct.Member1)).Content.Retrieve());
 }
Exemple #20
0
        public void TestEquals()
        {
            // Note: comparing GraphNodePath.GetHashCode() returns true when the root node is equivalent. This is because the root node is the only invariant.

            var obj = new Class {
                StructMember = { StringMember = "aa" }, ClassMember = new Class(), ListMember = { new Class(), new Class(), new Class() }
            };
            var nodeContainer = new NodeContainer();
            var path1         = new GraphNodePath(nodeContainer.GetOrCreateNode(obj));

            path1.PushMember(nameof(Class.IntMember));
            var path2 = new GraphNodePath(nodeContainer.GetOrCreateNode(obj));

            path2.PushMember(nameof(Class.IntMember));
            AssertAreEqual(path1.GetHashCode(), path2.GetHashCode());
            AssertAreEqual(path1, path2);

            path1 = new GraphNodePath(nodeContainer.GetOrCreateNode(obj));
            path1.PushMember(nameof(Class.ClassMember));
            AssertAreEqual(path1.GetHashCode(), path2.GetHashCode());
            AssertAreNotEqual(path1, path2);
            path2 = new GraphNodePath(nodeContainer.GetOrCreateNode(obj));
            path2.PushMember(nameof(Class.ClassMember));
            AssertAreEqual(path1.GetHashCode(), path2.GetHashCode());
            AssertAreEqual(path1, path2);

            path1 = new GraphNodePath(nodeContainer.GetOrCreateNode(obj));
            path1.PushMember(nameof(Class.ClassMember));
            path1.PushTarget();
            AssertAreEqual(path1.GetHashCode(), path2.GetHashCode());
            AssertAreNotEqual(path1, path2);
            path2 = new GraphNodePath(nodeContainer.GetOrCreateNode(obj));
            path2.PushMember(nameof(Class.ClassMember));
            path2.PushTarget();
            AssertAreEqual(path1.GetHashCode(), path2.GetHashCode());
            AssertAreEqual(path1, path2);

            path1 = new GraphNodePath(nodeContainer.GetOrCreateNode(obj));
            path1.PushMember(nameof(Class.ClassMember));
            path1.PushTarget();
            path1.PushMember(nameof(Class.IntMember));
            AssertAreEqual(path1.GetHashCode(), path2.GetHashCode());
            AssertAreNotEqual(path1, path2);
            path2 = new GraphNodePath(nodeContainer.GetOrCreateNode(obj));
            path2.PushMember(nameof(Class.ClassMember));
            path2.PushTarget();
            path2.PushMember(nameof(Class.IntMember));
            AssertAreEqual(path1.GetHashCode(), path2.GetHashCode());
            AssertAreEqual(path1, path2);

            path1 = new GraphNodePath(nodeContainer.GetOrCreateNode(obj));
            path1.PushMember(nameof(Class.ListMember));
            path1.PushIndex(new NodeIndex(0));
            AssertAreEqual(path1.GetHashCode(), path2.GetHashCode());
            AssertAreNotEqual(path1, path2);
            path2 = new GraphNodePath(nodeContainer.GetOrCreateNode(obj));
            path2.PushMember(nameof(Class.ListMember));
            path2.PushIndex(new NodeIndex(0));
            AssertAreEqual(path1.GetHashCode(), path2.GetHashCode());
            AssertAreEqual(path1, path2);

            path2 = new GraphNodePath(nodeContainer.GetOrCreateNode(obj));
            path2.PushMember(nameof(Class.ListMember));
            path2.PushIndex(new NodeIndex(1));
            AssertAreEqual(path1.GetHashCode(), path2.GetHashCode());
            AssertAreNotEqual(path1, path2);
        }
        public void TestChangeStruct()
        {
            var nodeContainer = new NodeContainer();
            var obj           = new[] { new Struct {
                                            Member1 = "aa"
                                        }, new Struct {
                                            Member1 = "bb"
                                        }, new Struct {
                                            Member1 = "cc"
                                        } };
            var instance = new ComplexClass {
                Member4 = obj[0]
            };
            var rootNode = nodeContainer.GetOrCreateNode(instance);
            var listener = new GraphNodeChangeListener(rootNode);
            var node     = rootNode.GetChild(nameof(ComplexClass.Member4));
            var path     = new GraphNodePath(rootNode).PushMember(nameof(ComplexClass.Member4));

            Assert.AreEqual("aa", node.GetChild(nameof(Struct.Member1)).Content.Retrieve());
            TestContentChange(listener, node, ContentChangeType.ValueChange, Index.Empty, obj[0], obj[1], path, () => node.Content.Update(obj[1]));
            Assert.AreEqual("bb", node.GetChild(nameof(Struct.Member1)).Content.Retrieve());
            TestContentChange(listener, node, ContentChangeType.ValueChange, Index.Empty, obj[1], obj[2], path, () => node.Content.Update(obj[2]));
            Assert.AreEqual("cc", node.GetChild(nameof(Struct.Member1)).Content.Retrieve());
            TestContentChange(listener, node.GetChild(nameof(Struct.Member1)), ContentChangeType.ValueChange, Index.Empty, "cc", "dd", path.PushMember(nameof(Struct.Member1)), () => node.GetChild(nameof(Struct.Member1)).Content.Update("dd"));
            Assert.AreEqual("dd", node.GetChild(nameof(Struct.Member1)).Content.Retrieve());
        }