/// <summary> /// Gets the 'from' node's successors that are at the same depth that the 'from' node is at. Depth /// increases when a path enters a parallel divergence, and decreases when it exits that divergence. /// Traversal terminates when it encounters a node it has encountered before - therefore, a way of /// bounding the traversal is to add the terminal nodes into the 'beenThere' list before making the /// initial call. /// </summary> /// <param name="beenThere">A list of the nodes already encountered in this traversal.</param> /// <param name="retval">The list of nodes that are zero-depth peers of the initial 'from' node.</param> /// <param name="from">The current 'from' node. This is the traversal node.</param> /// <param name="depth">The current traversal depth.</param> /// <param name="nodeFilter">The node filter - applied to all zero-depth nodes to see if they are /// acceptable to add to the retval list.</param> private static void GetZeroDepthSuccessors(PfcNodeList beenThere, PfcNodeList retval, IPfcNode from, int depth, Predicate <IPfcNode> nodeFilter) { if (s_diagnostics) { Console.WriteLine("Checking zero-depth successors from " + from.Name + ", which is at depth " + depth + "."); } if (beenThere.Contains(from)) { return; } else { beenThere.Add(from); } if (from.SuccessorNodes.Count > 1 && from.ElementType.Equals(PfcElementType.Transition)) { depth++; } foreach (IPfcNode to in from.SuccessorNodes) { if (to.PredecessorNodes.Count > 1 && to.ElementType.Equals(PfcElementType.Transition)) { depth--; } if (depth == 0 && nodeFilter(to) && !retval.Contains(to)) { retval.Add(to); } GetZeroDepthSuccessors(beenThere, retval, to, depth, nodeFilter); } }
///// <summary> ///// Sorts the pfcNodes in the provided list in order of their execution dependencies. ///// </summary> ///// <param name="nodes">The nodes.</param> ///// <param name="topToBottom">if set to <c>true</c> [top to bottom].</param> ///// <returns></returns> //public static List<IPfcNode> SortByDependencies(List<IPfcNode> nodes, bool topToBottom) { // DependencySorter<IPfcNode>.ParentGetter parentGetter = null; // if (topToBottom) { // parentGetter = new DependencySorter<IPfcNode>.ParentGetter(delegate(IPfcNode node) { return node.SuccessorNodes; }); // } else { // parentGetter = new DependencySorter<IPfcNode>.ParentGetter(delegate(IPfcNode node) { return node.PredecessorNodes; }); // } // DependencySorter<IPfcNode> depsorter = new DependencySorter<IPfcNode>(nodes, parentGetter); // return depsorter.DependencySequence; //} //class DependencySorter<T> : IEnumerable<T> where T : Highpoint.Sage.SimCore.IHasName { // public delegate List<T> ParentGetter(T t); // private List<T> m_vertices; // private Dictionary<T, Vertex<T>> m_dictionary; // public DependencySorter(List<T> list, ParentGetter parentGetter) { // m_dictionary = new Dictionary<T, Vertex<T>>(); // foreach (T t in list) { // Vertex<T> vertex = new Vertex<T>(t, m_dictionary); // } // foreach (Vertex<T> v in m_dictionary.Values) { // v.SetParents(parentGetter(v.Element)); // } // System.Collections.ArrayList vertices = new System.Collections.ArrayList(); // foreach (Vertex<T> vt in m_dictionary.Values) { // vertices.Add(vt); // } // //Dependencies.IDependencyVertex // Dependencies.GraphSequencer gs = new Highpoint.Sage.Dependencies.GraphSequencer(); // gs.AddVertices(vertices); // System.Collections.IList retval = gs.GetServiceSequenceList(); // m_vertices = new List<T>(); // foreach (Vertex<T> v in gs.GetServiceSequenceList()) { // m_vertices.Add(v.Element); // } // } // public List<T> DependencySequence { // get { // return m_vertices; // } // } // class Vertex<T1> : Dependencies.IDependencyVertex where T1 : Highpoint.Sage.SimCore.IHasName { // System.Collections.ArrayList m_parents; // Dictionary<T1, Vertex<T1>> m_dictionary; // T1 m_element; // public Vertex(T1 t, Dictionary<T1, Vertex<T1>> dict) { // m_element = t; // m_dictionary = dict; // m_dictionary.Add(m_element, this); // } // public T1 Element { get { return m_element; } } // #region IDependencyVertex Members // /// <summary> // /// An IComparable that determines how otherwise equal vertices // /// are to be sorted. Note that 'otherwise equal' means that the // /// vertices are equal after a dependency analysis is done, // /// and that both are independent of each other in the graph. // /// </summary> // /// <value></value> // public IComparable SortCriteria { // get { return m_element.Name; } // } // public System.Collections.ICollection ParentsList { // get { return m_parents; } // } // public void SetParents(List<T1> parents) { // m_parents = new System.Collections.ArrayList(); // foreach (T1 t in parents) { // m_parents.Add(m_dictionary[t]); // } // } // #endregion // } // #region IEnumerable<T> Members // public IEnumerator<T> GetEnumerator() { // return m_vertices.GetEnumerator(); // } // #endregion // #region IEnumerable Members // System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { // return m_vertices.GetEnumerator(); // } // #endregion //} #endregion Dependency Checker Stuff /// <summary> /// Creates a dictionary of transition to step mappings, such that by using this.Values, one can obtain steps /// that are recognizable to the user, and by using this[usersStepChoice], one can obtain the original transition. /// </summary> /// <param name="transitions">The IPfcNodeList that contains the transitions that govern the desired behaviors.</param> /// <param name="precedingStep">if set to <c>true</c> returns a preceding step of the transition, if false, a following step.</param> /// <returns>A dictionary of Step-to-Transition mappings.</returns> public static Dictionary <IPfcStepNode, IPfcTransitionNode> GetTransitionToStepMappings(PfcNodeList transitions, bool precedingStep) { Dictionary <IPfcStepNode, IPfcTransitionNode> retval = new Dictionary <IPfcStepNode, IPfcTransitionNode>(); foreach (IPfcTransitionNode transition in transitions) { Debug.Assert(transition.ElementType.Equals(PfcElementType.Transition), "The nodes passed in to the GetTransitionToStepMappings must be Transitions."); if (precedingStep) { if (transition.PredecessorNodes.Count > 0 && transition.PredecessorNodes[0].ElementType.Equals(PfcElementType.Transition)) { retval.Add((IPfcStepNode)transition.PredecessorNodes[0], (IPfcTransitionNode)transition); } } else { if (transition.SuccessorNodes.Count > 0 && transition.SuccessorNodes[0].ElementType.Equals(PfcElementType.Transition)) { retval.Add((IPfcStepNode)transition.SuccessorNodes[0], (IPfcTransitionNode)transition); } } } return(retval); }