Пример #1
0
        public virtual void TryAndProcess()
        {
            int c = Nodes.Count;

            for (int i = 0; i < c; i++)
            {
                Node n = Nodes[i];

                if (OutputNodes.Contains(n.Id))
                {
                    continue;
                }
                if (InputNodes.Contains(n.Id))
                {
                    continue;
                }

                n.TryAndProcess();
            }

            c = InputNodes.Count;

            for (int i = 0; i < c; i++)
            {
                Node n;
                if (NodeLookup.TryGetValue(InputNodes[i], out n))
                {
                    InputNode inp = (InputNode)n;
                    inp.TryAndProcess();
                }
            }
        }
Пример #2
0
        public virtual void SetOutputNode(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                OutputNode = null;
                if (OnOutputSet != null)
                {
                    OnOutputSet.Invoke(null);
                }
                Updated();
                return;
            }

            Node n = null;

            if (NodeLookup.TryGetValue(id, out n))
            {
                OutputNode = n;
                if (OnOutputSet != null)
                {
                    OnOutputSet.Invoke(n);
                }
                Updated();
            }
        }
Пример #3
0
        private void RemoveUnsatisfiedSuccessorActivity(T activityId)
        {
            // Check to make sure the node really exists.
            if (!NodeLookup.TryGetValue(activityId, out Node <T, TActivity> node))
            {
                return;
            }

            if (node.NodeType == NodeType.End ||
                node.NodeType == NodeType.Normal)
            {
                // If the activity was an unsatisfied successor, then remove it from the lookup.
                IList <KeyValuePair <T, HashSet <Node <T, TActivity> > > > kvps =
                    UnsatisfiedSuccessorsLookup.Where(x => x.Value.Select(y => y.Id).Contains(activityId)).ToList();

                foreach (KeyValuePair <T, HashSet <Node <T, TActivity> > > kvp in kvps)
                {
                    HashSet <Node <T, TActivity> > unsatisfiedSuccessorNodes = kvp.Value;
                    unsatisfiedSuccessorNodes.RemoveWhere(x => x.Id.Equals(activityId));
                    if (!unsatisfiedSuccessorNodes.Any())
                    {
                        UnsatisfiedSuccessorsLookup.Remove(kvp);
                    }
                }
            }
        }
Пример #4
0
        private bool ChangeEdgeHeadNodeWithoutCleanup(T edgeId, T newHeadNodeId)
        {
            // Do not attend this unless all dependencies are satisfied.
            if (!AllDependenciesSatisfied)
            {
                return(false);
            }
            // Retrieve the activity edge.
            if (!EdgeLookup.TryGetValue(edgeId, out Edge <T, TEdgeContent> _))
            {
                return(false);
            }
            // Retrieve the new head event node.
            if (!NodeLookup.TryGetValue(newHeadNodeId, out Node <T, TNodeContent> newHeadNode))
            {
                return(false);
            }

            // Remove the connection from the current head node.
            Node <T, TNodeContent> currentHeadNode = EdgeHeadNodeLookup[edgeId];

            currentHeadNode.IncomingEdges.Remove(edgeId);
            EdgeHeadNodeLookup.Remove(edgeId);

            // Attach to the new head node.
            newHeadNode.IncomingEdges.Add(edgeId);
            EdgeHeadNodeLookup.Add(edgeId, newHeadNode);
            return(true);
        }
Пример #5
0
        private void ResolveUnsatisfiedSuccessorActivities(T activityId)
        {
            // Check to make sure the node really exists.
            if (!NodeLookup.TryGetValue(activityId, out Node <T, TActivity> dependencyNode))
            {
                return;
            }

            // Check to see if any existing activities were expecting this activity
            // as a dependency. If so, then then hook their nodes to this activity with an edge.
            if (UnsatisfiedSuccessorsLookup.TryGetValue(activityId, out HashSet <Node <T, TActivity> > unsatisfiedSuccessorNodes))
            {
                // If the dependency node is an End or Isolated node, then convert it.
                if (dependencyNode.NodeType == NodeType.End)
                {
                    dependencyNode.SetNodeType(NodeType.Normal);
                }
                else if (dependencyNode.NodeType == NodeType.Isolated)
                {
                    dependencyNode.SetNodeType(NodeType.Start);
                }

                foreach (Node <T, TActivity> successorNode in unsatisfiedSuccessorNodes)
                {
                    T   edgeId = EdgeIdGenerator();
                    var edge   = new Edge <T, TEvent>(EventGenerator(edgeId));
                    dependencyNode.OutgoingEdges.Add(edgeId);
                    EdgeTailNodeLookup.Add(edgeId, dependencyNode);
                    successorNode.IncomingEdges.Add(edgeId);
                    EdgeHeadNodeLookup.Add(edgeId, successorNode);
                    EdgeLookup.Add(edgeId, edge);
                }
                UnsatisfiedSuccessorsLookup.Remove(activityId);
            }
        }
Пример #6
0
 public Node <T, TNodeContent> Node(T key)
 {
     if (!NodeLookup.TryGetValue(key, out Node <T, TNodeContent> node))
     {
         return(null);
     }
     return(node);
 }
Пример #7
0
        /// <summary>
        /// this is used in GraphInstances
        /// To resize proportionate to new size
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public virtual void ResizeWith(int width, int height)
        {
            this.width  = width;
            this.height = height;

            int c = Nodes.Count;

            for (int i = 0; i < c; i++)
            {
                Node n = Nodes[i];

                if (OutputNodes.Contains(n.Id))
                {
                    continue;
                }
                if (InputNodes.Contains(n.Id))
                {
                    continue;
                }

                if (n is BitmapNode)
                {
                    BitmapNode bn = (BitmapNode)n;
                    bn.TryAndProcess();
                }
                else
                {
                    Point osize;

                    if (OriginSizes.TryGetValue(n.Id, out osize))
                    {
                        float wratio = width / (float)osize.X;
                        float hratio = height / (float)osize.Y;

                        int fwidth  = (int)Math.Min(4096, Math.Max(16, Math.Round(osize.X * wratio)));
                        int fheight = (int)Math.Min(4096, Math.Max(16, Math.Round(osize.Y * hratio)));

                        n.Width  = fwidth;
                        n.Height = fheight;
                    }
                }
            }

            c = InputNodes.Count;

            for (int i = 0; i < c; i++)
            {
                Node n;
                if (NodeLookup.TryGetValue(InputNodes[i], out n))
                {
                    InputNode inp = (InputNode)n;
                    inp.TryAndProcess();
                }
            }
        }
Пример #8
0
        public override void FromJson(string data)
        {
            base.FromJson(data);

            FunctionGraphData d = JsonConvert.DeserializeObject <FunctionGraphData>(data);

            Node n = null;

            NodeLookup.TryGetValue(d.outputNode, out n);

            OutputNode = n;
        }
Пример #9
0
        public virtual void FromJson(string data)
        {
            FunctionGraphData d = JsonConvert.DeserializeObject <FunctionGraphData>(data);

            base.FromJson(d);

            Node n = null;

            if (d.outputNode != null)
            {
                NodeLookup.TryGetValue(d.outputNode, out n);
                OutputNode = n;
            }

            //we also want to set vars for argument if we have any
            //so they appear in the dropdown

            foreach (ArgNode arg in args)
            {
                object temp = 0;
                if (arg.InputType == NodeType.Float)
                {
                    temp = 0;
                }
                else if (arg.InputType == NodeType.Bool)
                {
                    temp = false;
                }
                else if (arg.InputType == NodeType.Matrix)
                {
                    temp = Matrix4.Identity;
                }
                else
                {
                    temp = new MVector();
                }

                SetVar(arg.InputName, temp, arg.InputType);
            }
        }
Пример #10
0
        public virtual void SetJsonReadyParameters(Dictionary <string, string> parameters)
        {
            if (parameters != null)
            {
                Parameters = new Dictionary <string, GraphParameterValue>();

                foreach (var k in parameters.Keys)
                {
                    string[] split = k.Split('.');

                    Node n = null;
                    NodeLookup.TryGetValue(split[0], out n);

                    Parameters[k] = GraphParameterValue.FromJson(parameters[k], n);
                    if (Parameters[k].IsFunction())
                    {
                        var f = Parameters[k].Value as FunctionGraph;
                        f.OnGraphUpdated += Graph_OnGraphUpdated;
                    }
                }
            }
        }
Пример #11
0
        private void AddEdge(string sourcePath, string targetPath, string label)
        {
            if (sourcePath.IsNullOrEmpty())
            {
                Debug.LogWarning($"Null source path for {label}.");
                return;
            }

            if (targetPath.IsNullOrEmpty())
            {
                Debug.LogWarning($"Null target path for {label}.");
                return;
            }

            if (!NodeLookup.TryGetValue(sourcePath, out GraphNode source))
            {
                Debug.LogWarning($"Couldn't find node for '{sourcePath}'.");
                return;
            }

            if (!targetPath.Contains('.') && !CurrentKnot.IsNullOrEmpty())
            {
                string testPath = $"{CurrentKnot}.{targetPath}";
                if (NodeLookup.ContainsKey(testPath))
                {
                    targetPath = testPath;
                }
            }

            if (!NodeLookup.TryGetValue(targetPath, out GraphNode target))
            {
                Debug.LogWarning($"Couldn't find node for '{targetPath}'.");
                return;
            }

            source = GetNodeAtDepth(source);
            target = GetNodeAtDepth(target);

            if (source.IsExcluded || target.IsExcluded)
            {
                return;
            }

            if (m_Settings.TunnelNodesHandling == TunnelNodesHandling.Remove && (target.IsTunnel || source.IsTunnel))
            {
                return;
            }

            bool duplicateTunnel = false;

            // Duplicate tunnels if needed.
            if (m_Settings.TunnelNodesHandling == TunnelNodesHandling.Duplicate && target.IsTunnel && source != target)
            {
                string tunnelId = source.Label + "->" + target.Label;

                if (DuplicateTunnelLookup.ContainsKey(tunnelId))
                {
                    // Already created this one.
                    return;
                }

                if (target.IsUsed)
                {
                    target = DuplicateNode(target);
                }
                else
                {
                    target.IsUsed = true;
                }

                DuplicateTunnelLookup[tunnelId] = target;
                duplicateTunnel = true;
            }
            else if (m_Settings.ForceDuplicatePaths.Contains(target.Label))
            {
                string forcedDuplicateId = source.Label + "->" + target.Label;

                if (ForceDuplicateLookup.ContainsKey(forcedDuplicateId))
                {
                    // Already created this one.
                    return;
                }

                if (target.IsUsed)
                {
                    target = DuplicateNode(target);
                }
                else
                {
                    target.IsUsed = true;
                }

                ForceDuplicateLookup[forcedDuplicateId] = target;
            }

            AddEdge(source, target, label);

            if (duplicateTunnel)
            {
                AddEdge(target, source);
            }
        }
Пример #12
0
 private GraphNode GetOrCreateNode(NodeType type, string path)
 {
     return(NodeLookup.TryGetValue(path, out GraphNode node) ? node : NodeLookup[path] = new GraphNode(type, GetNextId(), path));
 }
Пример #13
0
        public override bool RemoveActivityDependencies(T activityId, HashSet <T> dependencies)
        {
            if (dependencies is null)
            {
                throw new ArgumentNullException(nameof(dependencies));
            }
            if (!NodeLookup.TryGetValue(activityId, out Node <T, TActivity> node))
            {
                return(false);
            }
            if (!dependencies.Any())
            {
                return(true);
            }

            RemoveUnsatisfiedSuccessorActivityDependencies(activityId, dependencies);

            if (node.NodeType == NodeType.Start ||
                node.NodeType == NodeType.Isolated)
            {
                return(true);
            }

            // If any dependencies currently exist, remove them.
            var       existingDependencyLookup = new HashSet <T>(NodeLookup.Keys.Intersect(dependencies));
            IList <T> incomingEdgeIds          = node.IncomingEdges.ToList();
            int       length = incomingEdgeIds.Count;

            for (int i = 0; i < length; i++)
            {
                T edgeId = incomingEdgeIds[i];
                Node <T, TActivity> tailNode = EdgeTailNodeLookup[edgeId];

                if (!existingDependencyLookup.Contains(tailNode.Id))
                {
                    continue;
                }

                // Remove the edge from the tail node.
                tailNode.OutgoingEdges.Remove(edgeId);
                EdgeTailNodeLookup.Remove(edgeId);

                if (!tailNode.OutgoingEdges.Any())
                {
                    if (tailNode.NodeType == NodeType.Normal)
                    {
                        tailNode.SetNodeType(NodeType.End);
                    }
                    else if (tailNode.NodeType == NodeType.Start)
                    {
                        tailNode.SetNodeType(NodeType.Isolated);
                    }
                }

                // Remove the edge from the head node.
                node.IncomingEdges.Remove(edgeId);
                EdgeHeadNodeLookup.Remove(edgeId);

                // Remove the edge completely.
                EdgeLookup.Remove(edgeId);
            }

            if (!node.IncomingEdges.Any())
            {
                if (node.NodeType == NodeType.Normal)
                {
                    node.SetNodeType(NodeType.Start);
                }
                else if (node.NodeType == NodeType.End)
                {
                    node.SetNodeType(NodeType.Isolated);
                }
            }

            return(true);
        }
Пример #14
0
        public override bool RemoveActivity(T activityId)
        {
            // Retrieve the activity's node.
            if (!NodeLookup.TryGetValue(activityId, out Node <T, TActivity> node))
            {
                return(false);
            }
            if (!node.Content.CanBeRemoved)
            {
                return(false);
            }

            RemoveUnsatisfiedSuccessorActivity(activityId);
            NodeLookup.Remove(node.Id);

            if (node.NodeType == NodeType.Isolated)
            {
                return(true);
            }

            if (node.NodeType == NodeType.End ||
                node.NodeType == NodeType.Normal)
            {
                IList <T> incomingEdgeIds = node.IncomingEdges.ToList();
                int       length          = incomingEdgeIds.Count;
                for (int i = 0; i < length; i++)
                {
                    T edgeId = incomingEdgeIds[i];
                    Node <T, TActivity> tailNode = EdgeTailNodeLookup[edgeId];

                    // Remove the edge from the tail node.
                    tailNode.OutgoingEdges.Remove(edgeId);
                    EdgeTailNodeLookup.Remove(edgeId);

                    if (!tailNode.OutgoingEdges.Any())
                    {
                        if (tailNode.NodeType == NodeType.Normal)
                        {
                            tailNode.SetNodeType(NodeType.End);
                        }
                        else if (tailNode.NodeType == NodeType.Start)
                        {
                            tailNode.SetNodeType(NodeType.Isolated);
                        }
                    }

                    // Remove the edge from the head node.
                    node.IncomingEdges.Remove(edgeId);
                    EdgeHeadNodeLookup.Remove(edgeId);

                    if (!node.IncomingEdges.Any())
                    {
                        if (node.NodeType == NodeType.Normal)
                        {
                            node.SetNodeType(NodeType.Start);
                        }
                        else if (node.NodeType == NodeType.End)
                        {
                            node.SetNodeType(NodeType.Isolated);
                        }
                    }

                    // Remove the edge completely.
                    EdgeLookup.Remove(edgeId);
                }
            }

            if (node.NodeType == NodeType.Start ||
                node.NodeType == NodeType.Normal)
            {
                IList <T> outgoingEdgeIds = node.OutgoingEdges.ToList();
                int       length          = outgoingEdgeIds.Count;
                for (int i = 0; i < length; i++)
                {
                    T edgeId = outgoingEdgeIds[i];
                    Node <T, TActivity> headNode = EdgeHeadNodeLookup[edgeId];

                    // Remove the edge from the head node.
                    headNode.IncomingEdges.Remove(edgeId);
                    EdgeHeadNodeLookup.Remove(edgeId);

                    if (!headNode.IncomingEdges.Any())
                    {
                        if (headNode.NodeType == NodeType.Normal)
                        {
                            headNode.SetNodeType(NodeType.Start);
                        }
                        else if (headNode.NodeType == NodeType.End)
                        {
                            headNode.SetNodeType(NodeType.Isolated);
                        }
                    }

                    // Remove the edge from the tail node.
                    node.OutgoingEdges.Remove(edgeId);
                    EdgeTailNodeLookup.Remove(edgeId);

                    if (!node.OutgoingEdges.Any())
                    {
                        if (node.NodeType == NodeType.Normal)
                        {
                            node.SetNodeType(NodeType.End);
                        }
                        else if (node.NodeType == NodeType.Start)
                        {
                            node.SetNodeType(NodeType.Isolated);
                        }
                    }

                    // Remove the edge completely.
                    EdgeLookup.Remove(edgeId);
                }
            }
            return(true);
        }
Пример #15
0
        public override bool AddActivityDependencies(T activityId, HashSet <T> dependencies)
        {
            if (dependencies is null)
            {
                throw new ArgumentNullException(nameof(dependencies));
            }

            if (!NodeLookup.TryGetValue(activityId, out Node <T, TActivity> node))
            {
                return(false);
            }
            if (!dependencies.Any())
            {
                return(true);
            }
            if (dependencies.Contains(activityId))
            {
                return(false);
            }

            // If the node is an Start or Isolated node, then convert it.
            if (node.NodeType == NodeType.Start)
            {
                node.SetNodeType(NodeType.Normal);
            }
            else if (node.NodeType == NodeType.Isolated)
            {
                node.SetNodeType(NodeType.End);
            }

            // Check which of the expected dependencies currently exist.
            IList <T> existingDependencies    = NodeLookup.Keys.Intersect(dependencies).ToList();
            IList <T> nonExistingDependencies = dependencies.Except(existingDependencies).ToList();

            // If any expected dependencies currently exist, generate an edge to connect them.
            foreach (T dependencyId in existingDependencies)
            {
                Node <T, TActivity> dependencyNode = NodeLookup[dependencyId];
                T   edgeId = EdgeIdGenerator();
                var edge   = new Edge <T, TEvent>(EventGenerator(edgeId));
                node.IncomingEdges.Add(edgeId);
                EdgeHeadNodeLookup.Add(edgeId, node);

                // If the dependency node is an End or Isolated node, then convert it.
                if (dependencyNode.NodeType == NodeType.End)
                {
                    dependencyNode.SetNodeType(NodeType.Normal);
                }
                else if (dependencyNode.NodeType == NodeType.Isolated)
                {
                    dependencyNode.SetNodeType(NodeType.Start);
                }

                dependencyNode.OutgoingEdges.Add(edgeId);
                EdgeTailNodeLookup.Add(edgeId, dependencyNode);
                EdgeLookup.Add(edgeId, edge);
            }

            // If any expected dependencies currently do not exist, then record their
            // IDs and add this node as an unsatisfied successor.
            foreach (T dependencyId in nonExistingDependencies)
            {
                if (!UnsatisfiedSuccessorsLookup.TryGetValue(dependencyId, out HashSet <Node <T, TActivity> > successorNodes))
                {
                    successorNodes = new HashSet <Node <T, TActivity> >();
                    UnsatisfiedSuccessorsLookup.Add(dependencyId, successorNodes);
                }
                successorNodes.Add(node);
            }
            return(true);
        }