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); }
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); } }
public void UnionWith(LaneInfo other) { foreach (Junction otherJunction in other._junctions) { if (!_junctions.Contains(otherJunction)) { _junctions.Add(otherJunction); } } _junctions.TrimExcess(); }
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); } } }
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); } } }
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); }
public void Add(int lane, LaneInfo data) { _edges.Add(lane, data); }