/// <summary> /// when connecting a plotcommit to the child make sure that you will not be /// located on a lane on which a passed commit is located on. /// </summary> /// <remarks> /// when connecting a plotcommit to the child make sure that you will not be /// located on a lane on which a passed commit is located on. Otherwise we /// would have to draw a line through a commit. /// </remarks> /// <param name="index"></param> /// <param name="commit"></param> /// <param name="nChildren"></param> private void HandleBlockedLanes(int index, PlotCommit <L> commit, int nChildren) { // take care: int remaining = nChildren; BitSet blockedPositions = new BitSet(); for (int r = index - 1; r >= 0; r--) { PlotCommit rObj = this[r]; if (commit.IsChild(rObj)) { if (--remaining == 0) { break; } } if (rObj != null) { PlotLane lane = rObj.GetLane(); if (lane != null) { blockedPositions.Set(lane.GetPosition()); } rObj.AddPassingLane(commit.lane); } } // Now let's check whether we have to reposition the lane if (blockedPositions.Get(commit.lane.GetPosition())) { int newPos = -1; foreach (int pos in freePositions) { if (!blockedPositions.Get(pos)) { newPos = pos; break; } } if (newPos == -1) { newPos = positionsAllocated++; } freePositions.AddItem(Sharpen.Extensions.ValueOf(commit.lane.GetPosition())); activeLanes.Remove(commit.lane); commit.lane.position = newPos; activeLanes.AddItem(commit.lane); } }
protected internal override void Enter(int index, PlotCommit <L> currCommit) { SetupChildren(currCommit); int nChildren = currCommit.GetChildCount(); if (nChildren == 0) { return; } if (nChildren == 1 && currCommit.children[0].ParentCount < 2) { // Only one child, child has only us as their parent. // Stay in the same lane as the child. // PlotCommit c = currCommit.children[0]; if (c.lane == null) { // Hmmph. This child must be the first along this lane. // c.lane = NextFreeLane(); activeLanes.AddItem(c.lane); } for (int r = index - 1; r >= 0; r--) { PlotCommit rObj = this[r]; if (rObj == c) { break; } rObj.AddPassingLane(c.lane); } currCommit.lane = c.lane; } else { // More than one child, or our child is a merge. // Use a different lane. // // Process all our children. Especially important when there is more // than one child (e.g. a commit is processed where other branches // fork out). For each child the following is done // 1. If no lane was assigned to the child a new lane is created and // assigned // 2. The lane of the child is closed. If this frees a position, // this position will be added freePositions list. // If we have multiple children which where previously not on a lane // each such child will get his own new lane but all those new lanes // will be on the same position. We have to take care that not // multiple newly created (in step 1) lanes occupy that position on // which the // parent's lane will be on. Therefore we delay closing the lane // with the parents position until all children are processed. // The lane on that position the current commit will be on PlotLane reservedLane = null; for (int i = 0; i < nChildren; i++) { PlotCommit c = currCommit.children[i]; // don't forget to position all of your children if they are // not already positioned. if (c.lane == null) { c.lane = NextFreeLane(); activeLanes.AddItem(c.lane); if (reservedLane != null) { CloseLane(c.lane); } else { reservedLane = c.lane; } } else { if (reservedLane == null && activeLanes.Contains(c.lane)) { reservedLane = c.lane; } else { CloseLane(c.lane); } } } // finally all children are processed. We can close the lane on that // position our current commit will be on. if (reservedLane != null) { CloseLane(reservedLane); } currCommit.lane = NextFreeLane(); activeLanes.AddItem(currCommit.lane); // take care: when connecting yourself to your child make sure that // you will not be located on a lane on which a passed commit is // located on. Otherwise we would have to draw a line through a // commit. int remaining = nChildren; BitSet blockedPositions = new BitSet(); for (int r = index - 1; r >= 0; r--) { PlotCommit rObj = this[r]; if (currCommit.IsChild(rObj)) { if (--remaining == 0) { break; } } if (rObj != null) { PlotLane lane = rObj.GetLane(); if (lane != null) { blockedPositions.Set(lane.GetPosition()); } rObj.AddPassingLane(currCommit.lane); } } // Now let's check whether we have to reposition the lane if (blockedPositions.Get(currCommit.lane.GetPosition())) { int newPos = -1; foreach (int pos in freePositions) { if (!blockedPositions.Get(pos)) { newPos = pos; break; } } if (newPos == -1) { newPos = positionsAllocated++; } freePositions.AddItem(currCommit.lane.GetPosition()); currCommit.lane.position = newPos; } } }