Esempio n. 1
0
            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;
            }
Esempio n. 2
0
        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;
        }
Esempio n. 3
0
        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();
            }
        }
Esempio n. 4
0
 public void SetNext(GapNode gap)
 {
     Debug.Assert(NextNode == null);
     Debug.Assert(gap != null);
     NextNode = gap;
 }