Пример #1
0
        public void SwapIndexRangeToBack(int sectionIndex, int sectionLength, int swapIndex, int swapRange)
        {
            if (sectionIndex < 0)
            {
                throw new ArgumentException($"{nameof(sectionIndex)} must be 0 or higher.");
            }

            if (sectionLength < 0)
            {
                throw new ArgumentException($"{nameof(sectionLength)} must be 0 or higher.");
            }

            if (swapIndex < 0)
            {
                throw new ArgumentException($"{nameof(swapIndex)} must be positive.");
            }

            if (swapIndex + swapRange > sectionLength)
            {
                throw new ArgumentException($"{nameof(swapIndex)} ({swapIndex}) + {nameof(swapRange)} ({swapRange}) must be smaller than {nameof(sectionIndex)} ({sectionIndex}).");
            }

            if (sectionLength == 0 || swapRange == 0)
            {
                return;
            }

            var lengthBehindSwapIndex = sectionLength - swapIndex;
            var tempOffset            = indexToID.Length;

            // aaaaaabbbbcc ....
            // aaaaaabbbbcc .... bbbb
            //        |           ^
            //        |___________|

            // Copy the original indices to beyond the end of the list
            // Make space for these indices, hopefully the index list already has the capacity for
            // this and no allocation needs to be made
            indexToID.Resize(tempOffset + swapRange, NativeArrayOptions.UninitializedMemory);
            indexToID.MemMove(tempOffset, sectionIndex + swapIndex, swapRange);

            // aaaaaabbbbcc .... bbbb
            // aaaaaaccbbcc .... bbbb
            //        ^  |
            //        |__|

            // Move indices behind our swapIndex/swapRange on top of where our swap region begins
            var count = lengthBehindSwapIndex - swapRange;

            indexToID.MemMove(sectionIndex + swapIndex, sectionIndex + swapIndex + swapRange, count);

            // aaaaaaccbbcc .... bbbb
            // aaaaaaccbbbb .... bbbb
            //         ^           |
            //         |___________|

            // Copy the original indices to the end
            indexToID.MemMove(sectionIndex + swapIndex + count, tempOffset, swapRange);

            // aaaaaaccbbbb .... bbbb
            // aaaaaaccbbbb ....

            // Resize indices list to remove the temporary data, this is basically just
            //   indexToID.length = tempOffset
            indexToID.Resize(tempOffset, NativeArrayOptions.UninitializedMemory);

            for (int index = sectionIndex + swapIndex, lastIndex = sectionIndex + sectionLength; index < lastIndex; index++)
            {
                var idInternal = indexToID[index] - 1;

                var idLookup = idToIndex[idInternal];
                idLookup.index        = index;
                idToIndex[idInternal] = idLookup;
            }
        }