示例#1
0
            public void Update(Node aNode)
            {
                if (aNode.Descendants.Count != 0)
                {
                    return;
                }

                // This node is a head, create a new lane for it
                Node h = aNode;

                if (h.Ancestors.Count != 0)
                {
                    foreach (Junction j in h.Ancestors)
                    {
                        var detail = new LaneJunctionDetail(j);
                        laneNodes.Add(detail);
                    }
                }
                else
                {
                    // This is a single entry with no parents or children.
                    var detail = new LaneJunctionDetail(h);
                    laneNodes.Add(detail);
                }
            }
            public void Clear()
            {
                laneRows.Clear();
                laneNodes.Clear();
                currentRow.Clear();

                foreach (Node aNode in sourceGraph.GetHeads())
                {
                    if (aNode.Descendants.Count == 0)
                    {
                        // This node is a head, create a new lane for it
                        Node h = aNode;
                        if (h.Ancestors.Count == 0)
                        {
                            // This is a single entry with no parents or children.
                            var detail = new LaneJunctionDetail(h);
                            laneNodes.Add(detail);
                        }
                        else
                        {
                            foreach (Junction j in h.Ancestors)
                            {
                                var detail = new LaneJunctionDetail(j);
                                laneNodes.Add(detail);
                            }
                        }
                    }
                }
            }
示例#3
0
            /// <summary>
            /// Advance the lane to the next element
            /// </summary>
            /// <param name="curLane">Index of the lane to advance</param>
            /// <returns>True if there will still be nodes in this lane</returns>
            private int AdvanceLane(int curLane)
            {
                LaneJunctionDetail lane = laneNodes[curLane];
                int minLane             = curLane;

                // Advance the lane
                lane.Next();

                // See if we can pull up ancestors
                if (lane.Count == 0 && lane.Junction == null)
                {
                    // Handle a single node branch.
                    currentRow.Collapse(curLane);
                    laneNodes.RemoveAt(curLane);
                }
                else if (lane.Count == 0)
                {
                    Node node = lane.Junction.Oldest;
                    foreach (Junction parent in node.Ancestors)
                    {
                        if (parent.CurrentState != Junction.State.Unprocessed)
                        {
                            // This item is already in the lane list, no action needed
                            continue;
                        }

                        var addedLane = new LaneJunctionDetail(parent);
                        addedLane.Next();
                        int addedLaneLane = int.MaxValue;

                        // Check to see if this junction already points to one of the
                        // existing lanes. If so, we'll just add the lane line and not
                        // add it to the laneNodes.
                        if (addedLane.Count == 1)
                        {
                            for (int i = 0; i < laneNodes.Count; i++)
                            {
                                if (laneNodes[i].Current == addedLane.Current)
                                {
                                    // We still advance the lane so it gets
                                    // marked as processed.
                                    addedLane.Next();

                                    addedLaneLane = i;
                                    break;
                                }
                            }
                        }

                        // Add to the lane nodes
                        if (addedLaneLane == int.MaxValue)
                        {
                            if (lane.Count == 0)
                            {
                                lane = addedLane;
                                laneNodes[curLane] = lane;
                                addedLaneLane      = curLane;
                            }
                            else
                            {
                                addedLaneLane = curLane + 1;
                                laneNodes.Insert(addedLaneLane, addedLane);
                                currentRow.Expand(addedLaneLane);
                            }
                        }

                        currentRow.Add(curLane, new Graph.LaneInfo(addedLaneLane, parent));
                    }

                    // If the lane count after processing is still 0
                    // this is a root node of the graph
                    if (lane.Count == 0)
                    {
                        currentRow.Collapse(curLane);
                        laneNodes.RemoveAt(curLane);
                    }
                }
                else if (lane.Count == 1)
                {
                    // If any other lanes have this node on top, merge them together
                    for (int i = 0; i < laneNodes.Count; i++)
                    {
                        if (i == curLane || curLane >= laneNodes.Count)
                        {
                            continue;
                        }
                        if (laneNodes[i].Current == laneNodes[curLane].Current)
                        {
                            int      left;
                            int      right;
                            Junction junction = laneNodes[curLane].Junction;
                            if (i > curLane)
                            {
                                left  = curLane;
                                right = i;
                            }
                            else
                            {
                                left    = i;
                                right   = curLane;
                                curLane = i;
                            }
                            currentRow.Replace(right, left);
                            currentRow.Collapse(right);
                            laneNodes[right].Clear();
                            laneNodes.RemoveAt(right);

                            currentRow.Add(currentRow.NodeLane, new Graph.LaneInfo(left, junction));
                            minLane = Math.Min(minLane, left);
                        }
                    }

                    // If the current lane is still active, add it. It might not be active
                    // if it got merged above.
                    if (!lane.IsClear)
                    {
                        currentRow.Add(currentRow.NodeLane, new Graph.LaneInfo(curLane, lane.Junction));
                    }
                }
                else // lane.Count > 1
                {
                    currentRow.Add(currentRow.NodeLane, new Graph.LaneInfo(curLane, lane.Junction));
                }

                return(curLane);
            }
示例#4
0
            private bool MoveNext()
            {
                // If there are no lanes, there is nothing more to draw
                if (laneNodes.Count == 0 || sourceGraph.Count <= laneRows.Count)
                {
                    return(false);
                }

                // Find the new current row's node (newest item in the row)

                #region Find current node & index

                currentRow.Node = null;
                for (int curLane = 0; curLane < laneNodes.Count; curLane++)
                {
                    LaneJunctionDetail lane = laneNodes[curLane];
                    if (lane.Count == 0)
                    {
                        continue;
                    }

                    // NOTE: We could also compare with sourceGraph sourceGraph.AddedNodes[sourceGraph.processedNodes],
                    // since it should always be the same value
                    if (currentRow.Node == null ||
                        currentRow.Node.Data == null ||
                        (lane.Current.Data != null && lane.Current.Index < currentRow.Node.Index))
                    {
                        currentRow.Node     = lane.Current;
                        currentRow.NodeLane = curLane;
                        //break;
                    }
                }
                if (currentRow.Node == null)
                {
                    // DEBUG: The check above didn't find anything, but should have
                    if (Debugger.IsAttached)
                    {
                        Debugger.Break();
                    }
                    //Node[] topo = this.sourceGraph.TopoSortedNodes();
                    return(false);
                }

                // If this row doesn't contain data, we're to the end of the valid entries.
                if (currentRow.Node.Data == null)
                {
                    return(false);
                }

                sourceGraph.ProcessNode(currentRow.Node);

                #endregion

                // Check for multiple junctions with this node at the top. Remove the
                // node from that junction as well. This will happen when there is a branch

                #region Check for branches

                currentRow.Clear(currentRow.NodeLane);
                for (int curLane = 0; curLane < laneNodes.Count; curLane++)
                {
                    LaneJunctionDetail lane = laneNodes[curLane];
                    if (lane.Count == 0)
                    {
                        continue;
                    }

                    if (currentRow.Node != lane.Current)
                    {
                        // We're only interested in columns that have the same node
                        // at the top of the junction as the current row's node
                        continue;
                    }

                    // Remove the item from the lane, since it is being drawn now.
                    // We need to draw the graph line for this lane. If there are no items
                    // left in the lane we don't draw it.
                    int intoLane = AdvanceLane(curLane);
                    if (intoLane < curLane)
                    {
                        // AdvanceLane could have removed lanes so we need to start from
                        // the merged into lane (otherwise we could skip a lane, causing
                        // us to try to insert a node into the graph twice)
                        curLane = intoLane;
                    }

                    // Re-process the lane to make sure there are no actions left.
                    curLane--;
                }

                #endregion

                // Look for lanes that cross and reorder to straighten them out if possible,
                // and keep the lanes that merge next to each other.

                #region Straighten out lanes

                // Look for crossing lanes
                //   but only when there are not too many lanes taking up too much performance
                if (currentRow.Count < 10)
                {
                    for (int lane = 0; lane < currentRow.Count; lane++)
                    {
                        for (int item = 0; item < currentRow.LaneInfoCount(lane); item++)
                        {
                            Graph.LaneInfo laneInfo = currentRow[lane, item];
                            if (laneInfo.ConnectLane <= lane)
                            {
                                continue;
                            }
                            // Lane is moving to the right, check to see if it intersects
                            // with any lanes moving to the left.
                            for (int otherLane = lane + 1; otherLane <= laneInfo.ConnectLane; otherLane++)
                            {
                                if (currentRow.LaneInfoCount(otherLane) != 1)
                                {
                                    continue;
                                }
                                Graph.LaneInfo otherLaneInfo = currentRow[otherLane, 0];
                                if (otherLaneInfo.ConnectLane < otherLane)
                                {
                                    currentRow.Swap(otherLaneInfo.ConnectLane, otherLane);
                                    LaneJunctionDetail temp = laneNodes[otherLane];
                                    laneNodes[otherLane] = laneNodes[otherLaneInfo.ConnectLane];
                                    laneNodes[otherLaneInfo.ConnectLane] = temp;
                                }
                            }
                        }
                    }
                }

                //// Keep the merge lanes next to each other
                //int mergeFromCount = currentRow.LaneInfoCount(currentRow.NodeLane);
                //if (mergeFromCount > 1)
                //{
                //    for (int i = 0; i < mergeFromCount; i++)
                //    {
                //        Graph.LaneInfo laneInfo = currentRow[currentRow.NodeLane, i];
                //        // Check to see if the lane is currently next to us
                //        if (laneInfo.ConnectLane - currentRow.NodeLane > mergeFromCount)
                //        {
                //            // Only move the lane if it isn't already being drawn.
                //            if (currentRow.LaneInfoCount(laneInfo.ConnectLane) == 0)
                //            {
                //                // Remove the row laneInfo.ConnectLane and insert
                //                // it at currentRow.NodeLane+1.
                //                // Then start over searching for others if i != mergeFromCount-1?
                //                int adjacentLane = currentRow.NodeLane + 1;
                //                if (adjacentLane >= laneNodes.Count) Debugger.Break();
                //                currentRow.Expand(adjacentLane);
                //                currentRow.Replace(laneInfo.ConnectLane + 1, adjacentLane);

                //                LaneJunctionDetail temp = laneNodes[laneInfo.ConnectLane];
                //                laneNodes.RemoveAt(laneInfo.ConnectLane);
                //                laneNodes.Insert(adjacentLane, temp);
                //            }
                //        }
                //    }
                //}

                #endregion

                if (currentRow.Node != null)
                {
                    Graph.ILaneRow row = currentRow.Advance();

                    // This means there is a node that got put in the graph twice...
                    if (row.Node.InLane != int.MaxValue)
                    {
                        if (Debugger.IsAttached)
                        {
                            Debugger.Break();
                        }
                    }

                    row.Node.InLane = laneRows.Count;
                    laneRows.Add(row);
                    return(true);
                }

                // Return that there are more items left
                return(false);
            }