protected bool ChangeEdgeHeadNode(T edgeId, T newHeadNodeId) { // Do not attend this unless all dependencies are satisfied. if (!AllDependenciesSatisfied) { return(false); } Node <T, TNodeContent> oldHeadNode = EdgeHeadNodeLookup[edgeId]; bool changeHeadSuccess = ChangeEdgeHeadNodeWithoutCleanup(edgeId, newHeadNodeId); if (!changeHeadSuccess) { throw new InvalidOperationException($@"Unable to change head node of edge {edgeId} to node {newHeadNodeId} without cleanup"); } // If the old head node has no other incoming edges, then // connect its outgoing edges to the current tail node. IList <T> oldHeadNodeIncomingEdgeIds = oldHeadNode.IncomingEdges.ToList(); if (!oldHeadNodeIncomingEdgeIds.Any()) { Node <T, TNodeContent> tailNode = EdgeTailNodeLookup[edgeId]; IList <T> oldHeadNodeOutgoingEdgeIds = oldHeadNode.OutgoingEdges.ToList(); foreach (T oldHeadNodeOutgoingEdgeId in oldHeadNodeOutgoingEdgeIds) { bool changeTailSuccess = ChangeEdgeTailNodeWithoutCleanup(oldHeadNodeOutgoingEdgeId, tailNode.Id); if (!changeTailSuccess) { throw new InvalidOperationException($@"Unable to change tail node of edge {oldHeadNodeOutgoingEdgeId} to node {tailNode.Id} without cleanup"); } } } // Final check to see if the head node has no incoming or outgoing edges. // If it does not then remove it. if (oldHeadNode.NodeType != NodeType.End && oldHeadNode.NodeType != NodeType.Isolated && !oldHeadNode.IncomingEdges.Any() && !oldHeadNode.OutgoingEdges.Any()) { NodeLookup.Remove(oldHeadNode.Id); } return(true); }
public virtual void Remove(Node n) { if (n is OutputNode) { OutputNodes.Remove(n.Id); } else if (n is InputNode) { InputNodes.Remove(n.Id); } NodeLookup.Remove(n.Id); if (Nodes.Remove(n)) { n.OnUpdate -= N_OnUpdate; } n.Dispose(); }
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); }