Пример #1
0
        /// <summary>
        /// Ensures this container has the same state as the one given, using the least amount of operations
        /// </summary>
        /// <param name="otherContainer">The container to match</param>
        public void Reconcile(Container otherContainer)
        {
            Size = otherContainer.Size;

            if (Empty)
            {
                items.AddRange(otherContainer.items);
                OnContainerChanged(otherContainer.Items, ContainerChangeType.Add);
                return;
            }

            if (otherContainer.Empty)
            {
                Dump();
                return;
            }

            // Loop through all items to find the first index of divergence
            // We can assume that all items after that point have been changed, as items are always inserted at the end
            List <Item> movedItems   = new List <Item>();
            int         changedIndex = -1;

            for (var i = 0; i < items.Count; i++)
            {
                StoredItem storedItem         = items[i];
                StoredItem otherContainerItem = otherContainer.items[i];
                if (storedItem.Item != otherContainerItem.Item)
                {
                    changedIndex = i;
                    break;
                }

                if (storedItem.Position != otherContainerItem.Position)
                {
                    movedItems.Add(storedItem.Item);
                }
            }

            // Invoke move logic if any element has moved
            if (movedItems.Count > 0)
            {
                OnContainerChanged(movedItems, ContainerChangeType.Move);
            }

            // Nothing actually changed
            if (changedIndex == -1)
            {
                return;
            }

            // Remove all items after first divergence
            Item[] removedItems = new Item[items.Count - changedIndex];
            for (var i = changedIndex; i < items.Count;)
            {
                items.RemoveAt(i);
            }
            OnContainerChanged(removedItems.AsEnumerable(), ContainerChangeType.Remove);

            // Add all remaining items
            for (int i = changedIndex; i < otherContainer.ItemCount; i++)
            {
                items.Add(otherContainer.items[i]);
            }
            OnContainerChanged(otherContainer.Items.Skip(changedIndex + 1), ContainerChangeType.Add);
        }