public ColorNode(GapNode prev, Constraint constraint, int minValue, int maxValue) { length = (int)constraint.number; color = constraint.color; min = minValue; max = maxValue; PrevNode = prev; NextNode = null; Start = min; }
private void Build(out GapNode firstGap, out GapNode lastGap) { firstGap = new GapNode(null); GapNode prevGap = firstGap; for (int i = 0; i < constraints.Count; i++) { int min = boardView.ConstraintState.minValues[i]; int max = boardView.ConstraintState.maxValues[i]; ColorNode colorNode = new ColorNode(prevGap, constraints[i], min, max + 1); prevGap.SetNext(colorNode); prevGap = new GapNode(colorNode); colorNode.SetNext(prevGap); } prevGap.MarkAsEnd(boardView.Count); lastGap = prevGap; }
private protected void CleanRangeImpl(int index, int count) { if (count == 0) { return; } try { EnterStructureChange(); var endIndex = index + count - 1; var firstNodeCursor = Cursor.NavigateTo(index); var firstNode = firstNodeCursor.Node; // Single Node if (firstNodeCursor.Contains(endIndex)) { CleanNodeRange(ref firstNodeCursor, index, count); return; } var lastNodeCursor = firstNodeCursor.GetNext(); var lastNode = lastNodeCursor.Node; // Contiguous nodes if (lastNodeCursor.IsValid && lastNodeCursor.Contains(endIndex)) { // First is Gap. Expand to next if (firstNode is GapNode) { CleanNodeRange(ref lastNodeCursor, lastNodeCursor.NodeOffset, count - (lastNodeCursor.NodeOffset - index)); } // Last is Gap. Expand to prev else if (lastNode is GapNode) { CleanNodeRange(ref firstNodeCursor, index, firstNode.Size - (index - firstNodeCursor.NodeOffset)); } // Contiguous realized nodes. Make gap between else { var firstCount = firstNode.Size - (index - firstNodeCursor.NodeOffset); var lastCount = count - (lastNodeCursor.NodeOffset - index); CleanNodeRange(ref lastNodeCursor, lastNodeCursor.NodeOffset, lastCount); CleanNodeRange(ref firstNodeCursor, index, firstCount); } return; } GapNode gapNode = null; while (lastNodeCursor.IsValid && lastNodeCursor.Contains(endIndex) == false) { var nextCursor = lastNodeCursor.GetNext(); ReleaseNode(lastNodeCursor.Node); gapNode ??= lastNodeCursor.Node as GapNode; lastNodeCursor = nextCursor; lastNode = lastNodeCursor.Node; } Debug.Assert(lastNode != null); var gapSize = lastNodeCursor.NodeOffset - firstNodeCursor.NodeOffset - firstNode.Size; var firstGap = firstNode is GapNode; var lastGap = lastNode is GapNode; if (firstGap && lastGap) { if (ReferenceEquals(firstNode, HeadNode)) { if (ReferenceEquals(lastNode, TailNode)) { InitHeadTail(); return; } HeadNode.Next = lastNode.Next; lastNode.Next.Prev = HeadNode; HeadNode.Size += gapSize + lastNode.Size; ReleaseNode(lastNode); } else { lastNode.Size += gapSize + firstNode.Size; lastNode.Prev = firstNode.Prev; firstNode.Prev.Next = lastNode; ReleaseNode(firstNode); } } else if (firstGap) { firstNode.Next = lastNode; lastNode.Prev = firstNode; firstNode.Size += gapSize; CleanNodeRange(ref lastNodeCursor, lastNodeCursor.NodeOffset, count - (lastNodeCursor.NodeOffset - index)); } else if (lastGap) { firstNode.Next = lastNode; lastNode.Prev = firstNode; lastNode.Size += gapSize; CleanNodeRange(ref firstNodeCursor, index, firstNode.Size - (index - firstNodeCursor.NodeOffset)); } else { gapNode ??= Manager.GetGapNode(); gapNode.Size = gapSize; firstNode.Next = gapNode; lastNode.Prev = gapNode; gapNode.Prev = firstNode; gapNode.Next = lastNode; CleanNodeRange(ref firstNodeCursor, index, firstNode.Size - (index - firstNodeCursor.NodeOffset)); CleanNodeRange(ref lastNodeCursor, lastNodeCursor.NodeOffset, count - (lastNodeCursor.NodeOffset - index)); } } finally { LeaveStructureChange(); } }
public void SetNext(GapNode gap) { Debug.Assert(NextNode == null); Debug.Assert(gap != null); NextNode = gap; }