Exemple #1
0
        public void MultiToSingle()
        {
            // Multi            | Single
            // S -> Process -> Sync -> Process -> End

            List <DependentNode> nodes = new List <DependentNode>();
            DependentNode        start = new DependentNode(0, "start"),
                                 sync  = new DependentNode(1, SyncNode.TypeName),
                                 pro1  = new DependentNode(2, "pro"),
                                 pro2  = new DependentNode(3, "pro"),
                                 end   = new DependentNode(4, "end");

            nodes.Add(start);
            nodes.Add(pro1);
            nodes.Add(sync);
            nodes.Add(pro2);
            nodes.Add(end);

            TestHelpers.MatchSlots(start, pro1, 0, 0);
            TestHelpers.MatchSlots(pro1, sync, 0, 0);
            TestHelpers.MatchSlots(sync, pro2, 0, 0);
            TestHelpers.MatchSlots(pro2, end, 0, 0);

            DataStore       staticData = new DataStore(true);
            SpecialNodeData data       =
                SpecialNodeSearch.CheckForSpecialNodes(TestHelpers.ConvertToDictionary(nodes), staticData);

            Assert.AreEqual(1, data.SyncInformation.SyncNodes.Length);
            Assert.AreEqual(0, data.SyncInformation.NodeGroups[0].Dependents.Length);

            Assert.AreEqual(1, data.SyncInformation.NodeGroups[1].CalledBy);
        }
        private void FindLoopEnd(DependentNode node, ref List <int> done)
        {
            if (done.Contains(node.Id))
            {
                return;
            }

            foreach (NodeSlot slot in node.Dependencies)
            {
                DependentNode testNode = dependencyGraph[slot.NodeId];
                if (done.Contains(testNode.Id))
                {
                    continue;
                }

                if (testNode.Type == LoopEnd.TypeName)
                {
                    FindLoopPairs(testNode, ref done);
                }
                else
                {
                    FindLoopEnd(testNode, ref done);
                }
            }

            done.Add(node.Id);
        }
        public void SharedNestedLoopStart()
        {
            //          ᴧ  >>      >>      >>  v
            // S -> LoopStart -> LoopEnd -> LoopEnd -> End
            // 0        1           2          4        3

            List <DependentNode> nodes     = new List <DependentNode>();
            DependentNode        start     = new DependentNode(0, "start"),
                                 loopStart = new DependentNode(1, LoopStart.TypeName),
                                 loopEnd1  = new DependentNode(2, LoopEnd.TypeName),
                                 loopEnd2  = new DependentNode(3, LoopEnd.TypeName),
                                 end       = new DependentNode(4, "end");

            nodes.Add(start);
            nodes.Add(loopStart);
            nodes.Add(loopEnd1);
            nodes.Add(loopEnd2);
            nodes.Add(end);

            TestHelpers.MatchSlots(start, loopStart, 0, 0);
            TestHelpers.MatchSlots(loopStart, loopEnd1, 0, 0);
            TestHelpers.MatchSlots(loopStart, loopEnd1, 2, 2);
            TestHelpers.MatchSlots(loopStart, loopEnd2, 0, 0);
            TestHelpers.MatchSlots(loopEnd1, loopEnd2, 0, 2);
            TestHelpers.MatchSlots(loopEnd2, end, 0, 0);

            Assert.Throws <SlotLimitExceeded>(() => new LoopDetector(TestHelpers.ConvertToDictionary(nodes)).FindLoops());
        }
        /// <summary>
        /// Looks at the dependencies of a node and checks if any match the given types
        /// </summary>
        /// <param name="node">search node</param>
        /// <param name="matchedNode">id of the node that was of the given types, -1 if no match is found</param>
        /// <param name="tested">list of ids that have been checked</param>
        /// <param name="types">the node types that will be looked for</param>
        /// <returns>true if the node has a dependency of 'types'</returns>
        private bool CheckDependenciesFor(DependentNode node, out int matchedNode, List <int> tested, params string[] types)
        {
            if (tested.Contains(node.Id))
            {
                matchedNode = -1;
                return(false);
            }

            foreach (NodeSlot slot in node.Dependencies)
            {
                DependentNode testNode = dependencyGraph[slot.NodeId];

                for (int i = 0; i < types.Length; i++)
                {
                    if (testNode.Type == types[i] && !tested.Contains(testNode.Id))
                    {
                        matchedNode = testNode.Id;
                        return(true);
                    }
                }

                if (CheckDependenciesFor(testNode, out matchedNode, tested, types))
                {
                    return(true);
                }
            }

            tested.Add(node.Id);
            matchedNode = -1;
            return(false);
        }
        public List <LoopPair> FindLoops()
        {
            List <int> done = new List <int>();

            DependentNode[] nodes = dependencyGraph.Values.ToArray();

            //sanity check for existing loops
            bool loopEnds = false;

            foreach (DependentNode node in nodes)
            {
                if (node.Type == LoopEnd.TypeName)
                {
                    loopEnds = true;
                    break;
                }
            }

            if (!loopEnds)
            {
                return(new List <LoopPair>());
            }

            //find end points
            for (int i = nodes.Length - 1; i >= 0; i--)
            {
                DependentNode node = nodes[i];
                if (PluginStore.isOutputPlugin(node.Type))
                {
                    FindLoopEnd(node, ref done);
                }
            }

            return(loopPairs);
        }
        private bool NodeDependentOn(int search, int target, ref List <int> checkedNodes)
        {
            DependentNode node = dependencyGraph[search];

            for (int i = 0; i < node.Dependencies.Length; i++)
            {
                int nodeId = node.Dependencies[i].NodeId;
                if (checkedNodes.Contains(nodeId))
                {
                    continue;
                }

                if (nodeId == target && NodeDependentOn(nodeId, target, ref checkedNodes))
                {
                    return(true);
                }
                if (NodeDependentOn(nodeId, target, ref checkedNodes))
                {
                    return(true);
                }

                checkedNodes.Add(nodeId);
            }

            return(false);
        }
        public void CodependentLoop()
        {
            //                      ᴧ >>       >>       >>  v
            // S -> LoopStart -> LoopStart -> LoopEnd -> LoopEnd -> End
            //          v >>    >>      >>      ᴧ

            List <DependentNode> nodes      = new List <DependentNode>();
            DependentNode        start      = new DependentNode(0, "start"),
                                 loopStart1 = new DependentNode(1, LoopStart.TypeName),
                                 loopEnd1   = new DependentNode(2, LoopEnd.TypeName),
                                 loopStart2 = new DependentNode(3, LoopStart.TypeName),
                                 loopEnd2   = new DependentNode(4, LoopEnd.TypeName),
                                 process    = new DependentNode(6, "pro"),
                                 end        = new DependentNode(5, "end");

            nodes.Add(start);
            nodes.Add(loopStart1);
            nodes.Add(loopStart2);
            nodes.Add(loopEnd1);
            nodes.Add(loopEnd2);
            nodes.Add(process);
            nodes.Add(end);

            TestHelpers.MatchSlots(start, loopStart1, 0, 0);
            TestHelpers.MatchSlots(loopStart1, loopEnd1, 0, 0);
            TestHelpers.MatchSlots(loopStart1, loopStart2, 1, 2);
            TestHelpers.MatchSlots(loopStart2, process, 2, 0);
            TestHelpers.MatchSlots(loopStart2, loopEnd2, 0, 0);
            TestHelpers.MatchSlots(process, loopEnd1, 0, 2);
            TestHelpers.MatchSlots(loopEnd1, loopEnd2, 0, 2);
            TestHelpers.MatchSlots(loopEnd2, end, 0, 0);

            Assert.Throws <CoDependentLoopException>(() => new LoopDetector(TestHelpers.ConvertToDictionary(nodes)).FindLoops());
        }
        public void ImbalancedLoopLinkException()
        {
            List <DependentNode> nodes = new List <DependentNode>();
            { // start node
                DependentNode dep = new DependentNode(0, "start");
                dep.AddDependent(1, 0, 0);
                nodes.Add(dep);
            }
            { // loop start
                DependentNode dep = new DependentNode(1, LoopStart.TypeName);
                dep.AddDependency(0, 0, 0);
                //dep.AddDependent(2, 0, 0);
                dep.AddDependent(2, 2, 0);
                nodes.Add(dep);
            }
            { // first loop end
                DependentNode dep = new DependentNode(2, LoopEnd.TypeName);
                dep.AddDependency(1, 0, 0);
                dep.AddDependency(1, 1, 2);
                dep.AddDependent(3, 0, 0);
                nodes.Add(dep);
            }
            { // end node
                DependentNode dep = new DependentNode(3, "end");
                dep.AddDependency(2, 0, 0);
                nodes.Add(dep);
            }

            MissingLinkException exception = Assert.Throws <MissingLinkException>(() => new LoopDetector(TestHelpers.ConvertToDictionary(nodes)).FindLoops());

            Assert.AreEqual("No link for loop start specified", exception.Message);
        }
        public void SimpleExtendedLoop()
        {
            // S -> LoopStart -> LoopEnd -> Process -> End

            List <DependentNode> nodes     = new List <DependentNode>();
            DependentNode        start     = new DependentNode(0, "start"),
                                 loopStart = new DependentNode(1, LoopStart.TypeName),
                                 loopEnd   = new DependentNode(2, LoopEnd.TypeName),
                                 process   = new DependentNode(3, "pro"),
                                 end       = new DependentNode(4, "end");

            nodes.Add(start);
            nodes.Add(loopStart);
            nodes.Add(loopEnd);
            nodes.Add(process);
            nodes.Add(end);

            TestHelpers.MatchSlots(start, loopStart, 0, 0);
            TestHelpers.MatchSlots(loopStart, loopEnd, 0, 0);
            TestHelpers.MatchSlots(loopStart, loopEnd, 1, 2);
            TestHelpers.MatchSlots(loopEnd, process, 0, 0);
            TestHelpers.MatchSlots(process, end, 0, 0);

            List <LoopPair> loops = new LoopDetector(TestHelpers.ConvertToDictionary(nodes)).FindLoops();

            Assert.AreEqual(1, loops.Count, "incorrect amount of loops detected");
            Assert.AreEqual(0, loops[0].Depth);
        }
Exemple #10
0
        public void NoSync()
        {
            // Multi
            // S -> Process -> Process -> End

            List <DependentNode> nodes = new List <DependentNode>();
            DependentNode        start = new DependentNode(0, "start"),
                                 pro1  = new DependentNode(2, "pro"),
                                 pro2  = new DependentNode(3, "pro"),
                                 end   = new DependentNode(4, "end");

            nodes.Add(start);
            nodes.Add(pro1);
            nodes.Add(pro2);
            nodes.Add(end);

            TestHelpers.MatchSlots(start, pro1, 0, 0);
            TestHelpers.MatchSlots(pro1, pro2, 0, 0);
            TestHelpers.MatchSlots(pro2, end, 0, 0);

            DataStore       staticData = new DataStore(true);
            SpecialNodeData data       =
                SpecialNodeSearch.CheckForSpecialNodes(TestHelpers.ConvertToDictionary(nodes), staticData);

            Assert.AreEqual(0, data.SyncInformation.SyncNodes.Length, "There should not be any sync blocks in this test");
            Assert.AreEqual(null, data.SyncInformation.NodeGroups);
        }
Exemple #11
0
 private bool Insert(Dependent update)
 {
     lock (this)
     {
         bool first = _firstDependent == null;
         _firstDependent = new DependentNode {
             Dependent = new WeakReference(update), Next = _firstDependent
         };
         return(first);
     }
 }
Exemple #12
0
 private bool Contains(Dependent update)
 {
     lock (this)
     {
         for (DependentNode current = _firstDependent; current != null; current = current.Next)
         {
             if (current.Dependent.Target == update)
             {
                 return(true);
             }
         }
         return(false);
     }
 }
        public void MiddleExitLoops()
        {
            //                End
            //                 ᴧ
            // S -> LoopStart -> LoopEnd -> End

            List <DependentNode> nodes = new List <DependentNode>();
            { // start node
                DependentNode dep = new DependentNode(0, "start");
                dep.AddDependent(1, 0, 0);
                nodes.Add(dep);
            }
            { // loop start
                DependentNode dep = new DependentNode(1, LoopStart.TypeName);
                dep.AddDependency(0, 0, 0);
                dep.AddDependent(2, 0, 0);
                dep.AddDependent(2, 2, 1);
                dep.AddDependent(4, 1, 0);
                nodes.Add(dep);
            }
            { // condition for end loop
                DependentNode dep = new DependentNode(5, "condition");
                dep.AddDependent(2, 1, 0);
                nodes.Add(dep);
            }
            { // middle end
                DependentNode dep = new DependentNode(4, "end");
                dep.AddDependency(1, 1, 0);
                nodes.Add(dep);
            }
            { // loop end
                DependentNode dep = new DependentNode(2, LoopEnd.TypeName);
                dep.AddDependency(1, 0, 0);
                dep.AddDependency(5, 0, 1);
                dep.AddDependency(1, 1, 2);
                dep.AddDependent(3, 0, 0);
                nodes.Add(dep);
            }
            { // end node
                DependentNode dep = new DependentNode(3, "end");
                dep.AddDependency(2, 0, 0);
                nodes.Add(dep);
            }

            List <LoopPair> loops = new LoopDetector(TestHelpers.ConvertToDictionary(nodes)).FindLoops();

            Assert.AreEqual(1, loops.Count, "incorrect amount of loops detected");
            Assert.AreEqual(0, loops[0].Depth);
        }
        public SyncNode(DependentNode nodeId, DataStore staticData)
        {
            NodeId          = nodeId.Id;
            graphNode       = nodeId;
            this.staticData = staticData;

            //build dictionary
            foreach (NodeSlot node in nodeId.Dependencies)
            {
                if (data.ContainsKey(node.NodeId))
                {
                    continue;
                }
                data.Add(node.NodeId, new List <byte[]>());
            }
        }
        public void NodeDependencyOrder(int[] slots)
        {
            DependentNode node = new DependentNode(0, "node");

            foreach (int slot in slots)
            {
                node.AddDependency(slot, 0, slot);
            }

            int lastSlot = -1;

            foreach (NodeSlot dependency in node.Dependencies)
            {
                Assert.Greater(dependency.NodeId, lastSlot);
                lastSlot = dependency.SlotPos;
            }
        }
Exemple #16
0
 private Dependent First()
 {
     lock (this)
     {
         while (_firstDependent != null)
         {
             Dependent dependent = (Dependent)_firstDependent.Dependent.Target;
             if (dependent != null)
             {
                 return(dependent);
             }
             else
             {
                 _firstDependent = _firstDependent.Next;
             }
         }
         return(null);
     }
 }
Exemple #17
0
        public void SimpleSlotDependencies()
        {
            List <DependentNode> nodes = new List <DependentNode>();

            DependentNode a = new DependentNode(0, "a"),
                          b = new DependentNode(1, "b"),
                          c = new DependentNode(2, "c");

            nodes.Add(a);
            nodes.Add(b);
            nodes.Add(c);

            TestHelpers.MatchSlots(b, a, 0, 0);
            TestHelpers.MatchSlots(b, c, 1, 0);

            NodeSlot resultSlot = ExecutionHelper.FindFirstNodeSlotInDependents(b, TestHelpers.ConvertToDictionary(nodes), 0);

            Assert.AreEqual(a.Id, resultSlot.NodeId);
        }
Exemple #18
0
        public void MultiToSingleToMulti()
        {
            // Multi            | Single           | Multi
            // S -> Process -> Sync -> Process -> Sync -> Process -> End
            //        v-------------------------------------ᴧ

            List <DependentNode> nodes = new List <DependentNode>();
            DependentNode        start = new DependentNode(0, "start"),
                                 sync  = new DependentNode(1, SyncNode.TypeName),
                                 sync2 = new DependentNode(6, SyncNode.TypeName),
                                 pro1  = new DependentNode(2, "pro"),
                                 pro2  = new DependentNode(3, "pro"),
                                 pro3  = new DependentNode(5, "pro"),
                                 end   = new DependentNode(4, "end");

            nodes.Add(start);
            nodes.Add(pro1);
            nodes.Add(sync);
            nodes.Add(sync2);
            nodes.Add(pro2);
            nodes.Add(pro3);
            nodes.Add(end);

            TestHelpers.MatchSlots(start, pro1, 0, 0);
            TestHelpers.MatchSlots(pro1, sync, 0, 0);
            TestHelpers.MatchSlots(pro1, pro3, 1, 1);
            TestHelpers.MatchSlots(sync, pro2, 0, 0);
            TestHelpers.MatchSlots(pro2, sync2, 0, 0);
            TestHelpers.MatchSlots(sync2, pro3, 0, 0);
            TestHelpers.MatchSlots(pro3, end, 0, 0);

            DataStore       staticData = new DataStore(true);
            SpecialNodeData data       =
                SpecialNodeSearch.CheckForSpecialNodes(TestHelpers.ConvertToDictionary(nodes), staticData);

            Assert.AreEqual(2, data.SyncInformation.SyncNodes.Length);
            Assert.AreEqual(3, data.SyncInformation.NodeGroups.Count);

            Assert.AreEqual(sync.Id, data.SyncInformation.NodeGroups[1].CalledBy);
            Assert.AreEqual(sync2.Id, data.SyncInformation.NodeGroups[2].CalledBy);
            Assert.IsTrue(data.SyncInformation.NodeGroups[0].Dependents.Contains(pro3.Id));
        }
        public void NoLoop()
        {
            // S -> End

            List <DependentNode> nodes = new List <DependentNode>();
            { // start node
                DependentNode dep = new DependentNode(0, "start");
                dep.AddDependent(3, 0, 0);
                nodes.Add(dep);
            }
            { // end node
                DependentNode dep = new DependentNode(3, "end");
                dep.AddDependency(0, 0, 0);
                nodes.Add(dep);
            }

            List <LoopPair> loops = new LoopDetector(TestHelpers.ConvertToDictionary(nodes)).FindLoops();

            Assert.AreEqual(0, loops.Count, "incorrect amount of loops detected");
        }
        public void SyncGeneratorInputException()
        {
            // S -> Sync -> End
            //Gen->

            List <DependentNode> nodes = new List <DependentNode>();
            DependentNode        start = new DependentNode(0, "start"),
                                 gen   = new DependentNode(1, "gen"),
                                 sync2 = new DependentNode(6, SyncNode.TypeName);

            nodes.Add(start);
            nodes.Add(gen);
            nodes.Add(sync2);

            TestHelpers.MatchSlots(start, sync2, 0, 0);
            TestHelpers.MatchSlots(gen, sync2, 0, 1);

            DataStore staticData = new DataStore(true);

            Assert.Throws <InvalidConnectionException>(() => SpecialNodeSearch.CheckForSpecialNodes(TestHelpers.ConvertToDictionary(nodes), staticData));
        }
        public void InvalidLoopStartConnection()
        {
            List <DependentNode> nodes = new List <DependentNode>();
            { // start node
                DependentNode dep = new DependentNode(0, "start");
                dep.AddDependent(1, 0, 0);
                nodes.Add(dep);
            }
            { // loop start
                DependentNode dep = new DependentNode(1, LoopStart.TypeName);
                dep.AddDependency(0, 0, 0);
                dep.AddDependent(2, 0, 0);
                dep.AddDependent(3, 0, 0); //Can't connect to non Loop End node
                dep.AddDependent(2, 2, 1);
                nodes.Add(dep);
            }
            { // condition for end loop
                DependentNode dep = new DependentNode(5, "condition");
                dep.AddDependent(2, 1, 0);
                nodes.Add(dep);
            }
            { // loop end
                DependentNode dep = new DependentNode(2, LoopEnd.TypeName);
                dep.AddDependency(1, 0, 0);
                dep.AddDependency(5, 0, 1);
                dep.AddDependency(1, 1, 2);
                dep.AddDependent(3, 0, 0);
                nodes.Add(dep);
            }
            { // end node
                DependentNode dep = new DependentNode(3, "end");
                dep.AddDependency(1, 0, 1);
                dep.AddDependency(2, 0, 0);
                nodes.Add(dep);
            }

            InvalidNodeException exception = Assert.Throws <InvalidNodeException>(() => new LoopDetector(TestHelpers.ConvertToDictionary(nodes)).FindLoops());

            Assert.AreEqual("Loop Start Link (slot 0) cannot link to anything but a Loop End", exception.Message);
        }
Exemple #22
0
 private bool Delete(Dependent dependent)
 {
     lock (this)
     {
         int           count = 0;
         DependentNode prior = null;
         for (DependentNode current = _firstDependent; current != null; current = current.Next)
         {
             object target = current.Dependent.Target;
             if (target == null || target == dependent)
             {
                 if (target == null)
                 {
                     System.Diagnostics.Debug.WriteLine(String.Format("Dead reference {0}", _referenceCount++));
                 }
                 if (target == dependent)
                 {
                     ++count;
                 }
                 if (prior == null)
                 {
                     _firstDependent = current.Next;
                 }
                 else
                 {
                     prior.Next = current.Next;
                 }
             }
             else
             {
                 prior = current;
             }
         }
         if (count != 1)
         {
             Debug.Assert(false, String.Format("Expected 1 dependent, found {0}.", count));
         }
         return(_firstDependent == null);
     }
 }
        public void NestedLoop2()
        {
            // S -> LoopStart -> LoopStart -> Process -> LoopEnd -> LoopEnd -> End

            List <DependentNode> nodes          = new List <DependentNode>();
            DependentNode        start          = new DependentNode(0, "start"),
                                 outerLoopStart = new DependentNode(1, LoopStart.TypeName),
                                 innerLoopStart = new DependentNode(2, LoopStart.TypeName),
                                 process        = new DependentNode(3, ""),
                                 innerLoopEnd   = new DependentNode(4, LoopEnd.TypeName),
                                 outerLoopEnd   = new DependentNode(5, LoopEnd.TypeName),
                                 end            = new DependentNode(6, "end");

            nodes.Add(start);
            nodes.Add(outerLoopEnd);
            nodes.Add(innerLoopEnd);
            nodes.Add(innerLoopStart);
            nodes.Add(outerLoopStart);
            nodes.Add(process);
            nodes.Add(end);

            TestHelpers.MatchSlots(start, outerLoopStart, 0, 0);
            TestHelpers.MatchSlots(outerLoopStart, outerLoopEnd, 0, 0);
            TestHelpers.MatchSlots(outerLoopStart, innerLoopStart, 2, 2);
            TestHelpers.MatchSlots(innerLoopStart, innerLoopEnd, 0, 0);
            TestHelpers.MatchSlots(innerLoopStart, process, 2, 0);
            TestHelpers.MatchSlots(process, innerLoopEnd, 0, 2);
            TestHelpers.MatchSlots(innerLoopEnd, outerLoopEnd, 0, 2);
            TestHelpers.MatchSlots(outerLoopEnd, end, 0, 0);

            List <LoopPair> loops = new LoopDetector(TestHelpers.ConvertToDictionary(nodes)).FindLoops();

            Assert.AreEqual(2, loops.Count, "incorrect amount of loops detected");
            Assert.AreEqual(1, loops[0].Depth);
            Assert.AreEqual(0, loops[1].Depth);
            Assert.AreNotSame(loops[0].Id, loops[1].Id);
            Assert.AreNotSame(loops[0].End.NodeId, loops[1].End.NodeId);
        }
        public void SplitLoops()
        {
            //                -> LoopEnd -> End
            // S -> LoopStart
            //                -> LoopEnd -> End

            List <DependentNode> nodes = new List <DependentNode>();

            DependentNode start     = new DependentNode(0, "start"),
                          loopStart = new DependentNode(1, LoopStart.TypeName),
                          loopEnd1  = new DependentNode(2, LoopEnd.TypeName),
                          loopEnd2  = new DependentNode(3, LoopEnd.TypeName),
                          end1      = new DependentNode(4, "end"),
                          end2      = new DependentNode(5, "end");

            nodes.Add(start);
            nodes.Add(loopStart);
            nodes.Add(loopEnd1);
            nodes.Add(loopEnd2);
            nodes.Add(end1);
            nodes.Add(end2);

            TestHelpers.MatchSlots(start, loopStart, 0, 0);
            TestHelpers.MatchSlots(loopStart, loopEnd1, 0, 0);
            TestHelpers.MatchSlots(loopStart, loopEnd1, 1, 2);
            TestHelpers.MatchSlots(loopEnd1, end1, 0, 0);
            TestHelpers.MatchSlots(loopStart, loopEnd2, 0, 0);
            TestHelpers.MatchSlots(loopStart, loopEnd2, 1, 2);
            TestHelpers.MatchSlots(loopEnd2, end2, 0, 0);

            Assert.Throws <SlotLimitExceeded>(() => new LoopDetector(TestHelpers.ConvertToDictionary(nodes)).FindLoops());

            /*List<LoopPair> loops = pipe.getLoops();
             * Assert.AreEqual(2, loops.Count, "incorrect amount of loops detected");
             * Assert.AreEqual(0, loops[0].Depth);
             * Assert.AreEqual(0, loops[1].Depth);
             * Assert.AreNotSame(loops[0].Id, loops[1].Id);*/
        }
        public void PartialLoopLinksException()
        {
            List <DependentNode> nodes = new List <DependentNode>();

            { // start node
                DependentNode dep = new DependentNode(0, "start");
                dep.AddDependent(1, 0, 0);
                nodes.Add(dep);
            }
            { // loop start
                DependentNode dep = new DependentNode(1, LoopStart.TypeName);
                dep.AddDependency(0, 0, 0);
                dep.AddDependent(2, 0, 0); // Loop start only linked to first loop end
                nodes.Add(dep);
            }
            { // first loop end
                DependentNode dep = new DependentNode(2, LoopEnd.TypeName);
                dep.AddDependency(1, 0, 0);
                dep.AddDependency(1, 1, 2);
                dep.AddDependent(3, 0, 0);
                nodes.Add(dep);
            }
            { // random loop end
                DependentNode dep = new DependentNode(4, LoopEnd.TypeName);
                dep.AddDependency(1, 0, 0);
                dep.AddDependency(1, 1, 2);
                dep.AddDependent(3, 1, 0);
                nodes.Add(dep);
            }
            { // end node
                DependentNode dep = new DependentNode(3, "end");
                dep.AddDependency(2, 0, 0);
                dep.AddDependency(4, 0, 1);
                nodes.Add(dep);
            }

            Assert.Throws <MissingLinkException>(() => new LoopDetector(TestHelpers.ConvertToDictionary(nodes)).FindLoops());
        }
Exemple #26
0
        public void MultiSlotDependents()
        {
            List <DependentNode> nodes = new List <DependentNode>();

            DependentNode a = new DependentNode(0, "a"),
                          b = new DependentNode(1, "b"),
                          c = new DependentNode(2, "c"),
                          d = new DependentNode(3, "d");

            nodes.Add(a);
            nodes.Add(b);
            nodes.Add(c);
            nodes.Add(d);

            TestHelpers.MatchSlots(a, b, 0, 0);
            TestHelpers.MatchSlots(b, c, 1, 0);
            TestHelpers.MatchSlots(b, d, 1, 0);

            NodeSlot[] resultSlots = ExecutionHelper.FindAllNodeSlotsInDependents(b, TestHelpers.ConvertToDictionary(nodes), 1);

            Assert.AreEqual(2, resultSlots.Length);
            Assert.AreEqual(c.Id, resultSlots[0].NodeId);
            Assert.AreEqual(d.Id, resultSlots[1].NodeId);
        }
        private List <NodeSlot> FindContainingNodeIds(int loopStart, int loopEnd)
        {
            DependentNode   start = dependencyGraph[loopStart];
            List <NodeSlot> ids   = new List <NodeSlot>();

            for (int i = 0; i < start.Dependents.Length; i++)
            {
                if (start.Dependents[i].NodeId == loopEnd)
                {
                    continue;
                }

                List <NodeSlot> id = new List <NodeSlot>();
                id.Add(start.Dependents[i]);

                Tuple <bool, List <NodeSlot> > traversed = TraverseNodeDependents(id, start.Dependents[i].NodeId, loopEnd);
                if (traversed.Item1)
                {
                    ids.AddRange(traversed.Item2);
                }
            }

            return(ids);
        }
Exemple #28
0
 private bool Delete(Dependent dependent)
 {
     lock (this)
     {
         int count = 0;
         DependentNode prior = null;
         for (DependentNode current = _firstDependent; current != null; current = current.Next)
         {
             object target = current.Dependent.Target;
             if (target == null || target == dependent)
             {
                 if (target == null)
                     System.Diagnostics.Debug.WriteLine(String.Format("Dead reference {0}", _referenceCount++));
                 if (target == dependent)
                     ++count;
                 if (prior == null)
                     _firstDependent = current.Next;
                 else
                     prior.Next = current.Next;
             }
             else
                 prior = current;
         }
         if (count != 1) Debug.Assert(false, String.Format("Expected 1 dependent, found {0}.", count));
         return _firstDependent == null;
     }
 }
Exemple #29
0
 private Dependent First()
 {
     lock (this)
     {
         while (_firstDependent != null)
         {
             Dependent dependent = (Dependent)_firstDependent.Dependent.Target;
             if (dependent != null)
                 return dependent;
             else
                 _firstDependent = _firstDependent.Next;
         }
         return null;
     }
 }
Exemple #30
0
 private bool Insert(Dependent update)
 {
     lock (this)
     {
         bool first = _firstDependent == null;
         _firstDependent = new DependentNode { Dependent = new WeakReference(update), Next = _firstDependent };
         return first;
     }
 }
        private void FindLoopPairs(DependentNode loopEnd, ref List <int> foundEnds, int depth = 0)
        {
            LoopPair instance = new LoopPair();

            instance.Id = loopIdCount++;

            if (loopEnd.Type == LoopEnd.TypeName)
            {
                instance.End   = new LoopEnd(loopEnd, instance);
                instance.Depth = depth;

                int startNode = ExecutionHelper.FindFirstNodeSlotInDependencies(loopEnd, dependencyGraph, 0).NodeId;
                if (startNode == -1)
                {
                    throw new MissingLinkException("No link for loop start specified");
                }
                DependentNode loopStart = dependencyGraph[startNode];

                //try to keep one instance per unique loop start node Id
                if (loopStarts.ContainsKey(startNode))
                {
                    instance.Start = loopStarts[startNode];
                }
                else
                {
                    instance.Start = new LoopStart(loopStart);
                    loopStarts.Add(startNode, instance.Start);
                }

                //ensure that only the start and end nodes are linked
                if (loopStart.Dependents.Where((testSlot, b) =>
                {
                    bool incorrectType = dependencyGraph[testSlot.NodeId].Type != LoopEnd.TypeName;

                    foreach (NodeSlot slot in dependencyGraph[testSlot.NodeId].Dependencies)
                    {
                        if (slot.NodeId == loopStart.Id && slot.SlotPos == 0)
                        {
                            if (incorrectType)
                            {
                                return(true);
                            }
                        }
                    }

                    return(false);
                }).Any())
                {
                    throw new InvalidNodeException("Loop Start Link (slot 0) cannot link to anything but a Loop End");
                }

                //find out how many loops the "LoopStart" node is directly responsible for
                int loopCount;
                {
                    List <int> matched = new List <int>();
                    loopCount = loopStart.Dependents.Where((testSlot, b) =>
                    {
                        if (matched.Contains(testSlot.NodeId))
                        {
                            return(false);
                        }

                        foreach (NodeSlot slot in dependencyGraph[testSlot.NodeId].Dependencies)
                        {
                            if (slot.NodeId == loopStart.Id && slot.SlotPos == 0)
                            {
                                matched.Add(testSlot.NodeId);
                                return(true);
                            }
                        }

                        return(false);
                    }).Count();
                }

                if (loopCount > 1)
                {
                    throw new SlotLimitExceeded("Loop Start may only have one loop end, use multiple loop starts for nesting or branching");

                    #region
                    //multiple nodes linked so there must be nested loops sharing this start position

                    /*int[] ids = new int[loopCount];
                     * for (int i = 0, c = 0; i < loopStart.Dependents.Length; i++)
                     *  if (loopStart.Dependents[i].SlotPos == 0)
                     *      ids[c++] = loopStart.Dependents[i].NodeId;
                     *
                     * //check if co dependent nodes exist
                     * List<int> dependencies = new List<int>();
                     * for (int a = 0; a < ids.Length; a++)
                     * {
                     *  for (int b = 0; b < ids.Length; b++)
                     *  {
                     *      if (a == b) continue;
                     *
                     *      bool aTob = NodeDependentOn(ids[a], ids[b]),
                     *          bToa = NodeDependentOn(ids[b], ids[a]);
                     *
                     *      if (aTob && bToa) throw new CoDependentLoopException
                     *          ("Node " + ids[a] + " and " + ids[b] + "Are dependent on each other and can't loop!");
                     *
                     *      if (aTob && !dependencies.Contains(a)) dependencies.Add(ids[a]);
                     *  }
                     * }
                     *
                     * //check non dependent nodes for internal loops
                     * foreach (int id in ids)
                     * {
                     *  if (dependencies.Contains(id)) continue;
                     *
                     *  LoopPair subPair = new LoopPair();
                     *  subPair.Id = loopIdCount++;
                     *  subPair.Depth = depth;
                     *  subPair.End = new LoopEnd(dependencyGraph[id], subPair);
                     *  if (loopStarts.ContainsKey(loopEnd.Dependencies[0].NodeId))
                     *      subPair.Start = loopStarts[loopEnd.Dependencies[0].NodeId];
                     *  else
                     *  {
                     *      instance.Start = new LoopStart(dependencyGraph[loopEnd.Dependencies[0].NodeId]);
                     *      loopStarts.Add(loopEnd.Dependencies[0].NodeId, subPair.Start);
                     *  }
                     *
                     *  int foundEnd;
                     *  if (ContainsLoop(instance, out foundEnd))
                     *      //contains internal loop
                     *      FindLoopPairs(dependencyGraph[foundEnd], ref foundEnds, subPair.Depth + 1);
                     *
                     *  foundEnds.Add(subPair.End.NodeId);
                     *  subPair.Start.AddLoopPair(ref subPair);
                     *  loopPairs.Add(subPair);
                     * }
                     *
                     * //go back and handle the nodes which are dependent on each other
                     * if (dependencies.Count > 1)
                     * {
                     *  throw new NotImplementedException();
                     *  //todo
                     * }*/
                    #endregion
                }
                else
                {
                    NodeSlot startLink = ExecutionHelper.FindFirstNodeSlotInDependents(loopStart, dependencyGraph, 0);

                    if (startLink.NodeId == -1)
                    {
                        throw new MissingLinkException("No link for loop start specified");
                    }
                    if (startLink.NodeId != loopEnd.Id)
                    {
                        throw new MissingLinkException(StartEndIdMismatch);
                    }

                    int foundEnd;
                    //contains internal loop?
                    if (ContainsLoop(instance, out foundEnd))
                    {
                        FindLoopPairs(dependencyGraph[foundEnd], ref foundEnds, instance.Depth + 1);
                    }

                    instance.ContainedNodes = FindContainingNodeIds(instance.Start.NodeId, instance.End.NodeId);

                    int start = 0, end = 0;
                    foreach (NodeSlot nodes in instance.ContainedNodes)
                    {
                        if (dependencyGraph[nodes.NodeId].Type == LoopStart.TypeName)
                        {
                            start += 1;
                        }
                        else if (dependencyGraph[nodes.NodeId].Type == LoopEnd.TypeName)
                        {
                            end += 1;
                        }
                    }
                    if (start != end)
                    {
                        throw new CoDependentLoopException();
                    }

                    foundEnds.Add(instance.End.NodeId);
                    instance.Start.AddLoopPair(ref instance);
                    loopPairs.Add(instance);
                }
            }
            else if (loopEnd.Type == LoopStart.TypeName)
            {
                //abort as you are in the middle of a loop rather than at the end
                if (instance.End == null)
                {
                    return;
                }
            }
        }
Exemple #32
0
 public static void MatchSlots(DependentNode a, DependentNode b, int aSlot, int bSlot)
 {
     a.AddDependent(b.Id, bSlot, aSlot);
     b.AddDependency(a.Id, aSlot, bSlot);
 }
        public void DuelLoops()
        {
            //                -> LoopEnd ->
            // S -> LoopStart               End
            //                -> LoopEnd ->

            List <DependentNode> nodes = new List <DependentNode>();

            { // start node
                DependentNode dep = new DependentNode(0, "start");
                dep.AddDependent(1, 0, 0);
                nodes.Add(dep);
            }
            { // loop start
                DependentNode dep = new DependentNode(1, LoopStart.TypeName);
                dep.AddDependency(0, 0, 0);
                dep.AddDependent(2, 0, 0);
                dep.AddDependent(2, 2, 1);
                dep.AddDependent(4, 0, 0);
                dep.AddDependent(4, 2, 1);
                nodes.Add(dep);
            }
            { // condition for first end loop
                DependentNode dep = new DependentNode(5, "condition");
                dep.AddDependent(2, 1, 0);
                nodes.Add(dep);
            }
            { // first loop end
                DependentNode dep = new DependentNode(2, LoopEnd.TypeName);
                dep.AddDependency(1, 0, 0);
                dep.AddDependency(5, 0, 1);
                dep.AddDependency(1, 1, 2);
                dep.AddDependent(3, 0, 0);
                nodes.Add(dep);
            }
            { // condition for second end loop
                DependentNode dep = new DependentNode(6, "condition");
                dep.AddDependent(4, 1, 0);
                nodes.Add(dep);
            }
            { // second loop end
                DependentNode dep = new DependentNode(4, LoopEnd.TypeName);
                dep.AddDependency(1, 0, 0);
                dep.AddDependency(6, 0, 1);
                dep.AddDependency(1, 1, 2);
                dep.AddDependent(3, 1, 0);
                nodes.Add(dep);
            }
            { // end node
                DependentNode dep = new DependentNode(3, "end");
                dep.AddDependency(2, 0, 0);
                dep.AddDependency(4, 0, 1);
                nodes.Add(dep);
            }

            Assert.Throws <SlotLimitExceeded>(() => new LoopDetector(TestHelpers.ConvertToDictionary(nodes)).FindLoops());


            /*List<LoopPair> loops = pipe.getLoops();
             * Assert.AreEqual(2, loops.Count, "incorrect amount of loops detected");
             * Assert.AreEqual(0, loops[0].Depth);
             * Assert.AreEqual(0, loops[1].Depth);
             * Assert.AreNotSame(loops[1].Id, loops[1].Id);*/
        }