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(); } } }
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(); } }
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); } } } }
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); }
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); } }
public Node <T, TNodeContent> Node(T key) { if (!NodeLookup.TryGetValue(key, out Node <T, TNodeContent> node)) { return(null); } return(node); }
/// <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(); } } }
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; }
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); } }
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; } } } }
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); } }
private GraphNode GetOrCreateNode(NodeType type, string path) { return(NodeLookup.TryGetValue(path, out GraphNode node) ? node : NodeLookup[path] = new GraphNode(type, GetNextId(), path)); }
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); }
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); }
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); }