Пример #1
0
        public ILaneRow Advance()
        {
            var newLaneRow = new SavedLaneRow(this);

            var newEdges = new Edges();

            for (int i = 0; i < _edges.CountNext(); i++)
            {
                int edgeCount = _edges.CountNext(i);
                if (edgeCount > 0)
                {
                    LaneInfo info = _edges.Next(i, 0).Clone();
                    for (int j = 1; j < edgeCount; j++)
                    {
                        LaneInfo edgeInfo = _edges.Next(i, j);
                        info.UnionWith(edgeInfo);
                    }

                    newEdges.Add(i, info);
                }
            }

            _edges = newEdges;

            return(newLaneRow);
        }
Пример #2
0
 public void Replace(int old, int @new)
 {
     for (int j = _edges.CountNext(old) - 1; j >= 0; --j)
     {
         LaneInfo info = _edges.RemoveNext(old, j, out var start, out _);
         info.ConnectLane = @new;
         _edges.Add(start, info);
     }
 }
Пример #3
0
        public void UnionWith(LaneInfo other)
        {
            foreach (Junction otherJunction in other._junctions)
            {
                if (!_junctions.Contains(otherJunction))
                {
                    _junctions.Add(otherJunction);
                }
            }

            _junctions.TrimExcess();
        }
Пример #4
0
        public void Expand(int col)
        {
            int edgeCount = Math.Max(_edges.CountCurrent(), _edges.CountNext());

            for (int i = edgeCount - 1; i >= col; --i)
            {
                while (_edges.CountNext(i) > 0)
                {
                    LaneInfo info = _edges.RemoveNext(i, 0, out var start, out _);
                    info.ConnectLane++;
                    _edges.Add(start, info);
                }
            }
        }
Пример #5
0
        public void Collapse(int col)
        {
            int edgeCount = Math.Max(_edges.CountCurrent(), _edges.CountNext());

            for (int i = col; i < edgeCount; i++)
            {
                while (_edges.CountNext(i) > 0)
                {
                    LaneInfo info = _edges.RemoveNext(i, 0, out var start, out _);
                    info.ConnectLane--;
                    _edges.Add(start, info);
                }
            }
        }
Пример #6
0
        private bool MoveNext()
        {
            // If there are no lanes, there is nothing more to draw
            if (_laneNodes.Count == 0 || 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?.Revision == null ||
                    (lane.Current.Revision != 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.Revision == null)
            {
                return(false);
            }

            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++)
                    {
                        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;
                            }

                            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)
            {
                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);
        }
Пример #7
0
 public void Add(int lane, LaneInfo data)
 {
     _edges.Add(lane, data);
 }