/// <summary>
    ///     Removes an item at the specified index.
    /// </summary>
    /// <param name="index">The index at which to remove an item from.</param>
    public override void RemoveAt(int index)
    {
        ThrowIfCurrentObjectDisposed();

        T item;

        using (ReadWriteSynchronizationLocker lockContext = ReadWriteLock())
        {
            if (index >= InternalListContainer.Count)
            {
                return;
            }

            lockContext.Upgrade();

            item = InternalListContainer[index];
            IncreaseIgnoreMustResetCounter();
            InternalListContainer.RemoveAt(index);

            PushUndoLevel(
                new RemoveStateChange <T>(
                    index,
                    item));
        }

        RaiseCollectionChangedRemove(
            item,
            index);
        RaisePropertyChanged(nameof(Count));
        ContentsMayHaveChanged();
    }
コード例 #2
0
    /// <summary>
    ///     Registers an assembly to extract compatible functions from.
    /// </summary>
    /// <param name="assembly">The assembly to register.</param>
    public void RegisterFunctionsAssembly(Assembly assembly)
    {
        _ = Requires.NotNull(
            assembly,
            nameof(assembly));

        ThrowIfCurrentObjectDisposed();

        using ReadWriteSynchronizationLocker innerLocker = ReadWriteLock();

        if (isInitialized)
        {
            throw new InvalidOperationException(
                      "Initialization has already completed, so you cannot register any more assemblies for this service.");
        }

        if (assembliesToRegister.Contains(assembly))
        {
            return;
        }

        innerLocker.Upgrade();

        assembliesToRegister.Add(assembly);
    }
コード例 #3
0
        /// <summary>
        ///     Removes an item at the specified index.
        /// </summary>
        /// <param name="index">The index at which to remove an item from.</param>
        public override void RemoveAt(int index)
        {
            this.RequiresNotDisposed();

            T item;

            using (ReadWriteSynchronizationLocker lockContext = this.ReadWriteLock())
            {
                if (index >= this.InternalContainer.Count)
                {
                    return;
                }

                lockContext.Upgrade();

                item = this.InternalContainer[index];
                this.IncreaseIgnoreMustResetCounter();
                this.InternalContainer.RemoveAt(index);

                this.PushUndoLevel(new RemoveUndoLevel <T> {
                    Index = index, RemovedItem = item
                });
            }

            this.RaiseCollectionChangedRemove(
                item,
                index);
            this.RaisePropertyChanged(nameof(this.Count));
            this.ContentsMayHaveChanged();
        }
コード例 #4
0
        /// <summary>
        ///     Attempts to de-queue an item and to remove it from queue.
        /// </summary>
        /// <param name="item">The item that has been de-queued, default if unsuccessful.</param>
        /// <returns>
        ///     <see langword="true" /> if an item is de-queued successfully, <see langword="false" /> otherwise, or if the
        ///     queue is empty.
        /// </returns>
        public bool TryDequeue(out T item)
        {
            this.RequiresNotDisposed();

            using (ReadWriteSynchronizationLocker locker = this.ReadWriteLock())
            {
                var adapter = (QueueCollectionAdapter <T>) this.InternalContainer;

                if (adapter.Count == 0)
                {
                    item = default;
                    return(false);
                }

                locker.Upgrade();

                item = adapter.Dequeue();
                this.PushUndoLevel(new DequeueUndoLevel <T> {
                    DequeuedItem = item
                });
            }

            this.RaisePropertyChanged(nameof(this.Count));
            this.RaisePropertyChanged(Constants.ItemsName);
            this.RaiseCollectionChangedRemove(
                item,
                0);

            return(true);
        }
コード例 #5
0
    /// <summary>
    ///     Attempts to de-queue an item and to remove it from queue.
    /// </summary>
    /// <param name="item">The item that has been de-queued, default if unsuccessful.</param>
    /// <returns>
    ///     <see langword="true" /> if an item is de-queued successfully, <see langword="false" /> otherwise, or if the
    ///     queue is empty.
    /// </returns>
    public bool TryDequeue(out T item)
    {
        ThrowIfCurrentObjectDisposed();

        using (ReadWriteSynchronizationLocker locker = ReadWriteLock())
        {
            var adapter = (QueueCollectionAdapter <T>)InternalContainer;

            if (adapter.Count == 0)
            {
                item = default !;
コード例 #6
0
    /// <summary>
    ///     Removes an item at the specified index.
    /// </summary>
    /// <param name="index">The index at which to remove an item from.</param>
    public virtual void RemoveAt(int index)
    {
        // PRECONDITIONS

        // Current object not disposed
        ThrowIfCurrentObjectDisposed();

        // ACTION
        T item;

        // Inside a read/write lock
        using (ReadWriteSynchronizationLocker lockContext = ReadWriteLock())
        {
            // Check to see if we are in range
            if (index >= InternalListContainer.Count)
            {
                return;
            }

            // Upgrade the lock to a write lock
            lockContext.Upgrade();

            item = InternalListContainer[index];

            // Using an undo/redo transaction
            using OperationTransaction tc = CheckItemAutoRelease(item);

            // Actually do the removal
            InternalListContainer.RemoveAt(index);

            // Push an undo level
            PushUndoLevel(
                new RemoveStateChange <T>(
                    index,
                    item));

            // Mark the transaction as successful
            tc.Success();
        }

        // NOTIFICATION

        // Collection changed
        RaiseCollectionChangedRemove(
            item,
            index);

        // Property changed
        RaisePropertyChanged(nameof(Count));

        // Contents may have changed
        ContentsMayHaveChanged();
    }
    /// <summary>
    ///     Attempts to remove all info related to a key from the dictionary.
    /// </summary>
    /// <param name="key">The key to remove data from.</param>
    /// <returns><see langword="true" /> if the removal was successful, <see langword="false" /> otherwise.</returns>
    public bool Remove(TKey key)
    {
        // PRECONDITIONS

        // Current object not disposed
        this.RequiresNotDisposed();

        // ACTION
        bool result;
        IDictionaryCollectionAdapter <TKey, TValue> container = InternalContainer;

        // Within a read/write lock
        using (ReadWriteSynchronizationLocker locker = ReadWriteLock())
        {
            // Find out if there's anything to remove
            if (!container.TryGetValue(
                    key,
                    out TValue? value))
            {
                return(false);
            }

            // Upgrade the locker to a write lock
            locker.Upgrade();

            // Do the actual removal
            result = container.Remove(key);

            // Push undo level
            if (result)
            {
                PushUndoLevel(
                    new DictionaryRemoveStateChange <TKey, TValue>(
                        key,
                        value));
            }
        }

        // NOTIFICATION AND RETURN
        if (result)
        {
            BroadcastChange();
        }

        return(result);
    }
コード例 #8
0
    /// <summary>
    ///     Returns an enumerator that iterates through the collection, from the point in which it currently stands, to the
    ///     end.
    /// </summary>
    /// <returns>An enumerator that can be used to iterate through the collection.</returns>
    public IEnumerator <T> GetEnumerator()
    {
        while (true)
        {
            T item;
            using (ReadWriteSynchronizationLocker lck = ReadWriteLock())
            {
                if (storeIndex >= items.Length)
                {
                    break;
                }

                lck.Upgrade();

                item = items[storeIndex];
                storeIndex++;
            }

            yield return(item);
        }
    }
        /// <summary>
        ///     Removes a key from the dictionary, then acts on its resulting value.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="action">The action.</param>
        /// <returns><see langword="true" /> if the variable was successfully removed, <see langword="false" /> otherwise.</returns>
        public bool RemoveThenAct(
            TKey key,
            Action <TValue> action)
        {
            // PRECONDITIONS

            // Current object not disposed
            this.RequiresNotDisposed();

            // ACTION
            int    oldIndex;
            TValue value;

            // Under read/write lock
            using (ReadWriteSynchronizationLocker rwl = this.ReadWriteLock())
            {
                if (this.InternalContainer.TryGetValue(
                        key,
                        out value))
                {
                    rwl.Upgrade();

                    if (this.InternalContainer.TryGetValue(
                            key,
                            out value))
                    {
                        // Re-check within a write lock, to ensure that something else hasn't already removed it.
                        oldIndex = this.InternalContainer.Remove(
                            new KeyValuePair <TKey, TValue>(
                                key,
                                value));

                        action(value);
                    }
                    else
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            }

            // NOTIFICATIONS

            // Collection changed
            if (oldIndex == -1)
            {
                // If no index could be found for an item (Dictionary remove)
                this.RaiseCollectionReset();
            }
            else
            {
                // If index was added at a specific index
                this.RaiseCollectionChangedRemove(
                    new KeyValuePair <TKey, TValue>(
                        key,
                        value), oldIndex);
            }

            // Property changed
            this.RaisePropertyChanged(nameof(this.Count));

            // Contents may have changed
            this.ContentsMayHaveChanged();

            return(true);
        }
        /// <summary>
        ///     Creates an item or changes its state, if one exists.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="valueGenerator">The value generator.</param>
        /// <param name="valueAction">The value action.</param>
        /// <returns>The created or state-changed item.</returns>
        public TValue CreateOrChangeState(
            TKey key,
            Func <TValue> valueGenerator,
            Action <TValue> valueAction)
        {
            // PRECONDITIONS

            // Current object not disposed
            this.RequiresNotDisposed();

            // ACTION
            int    newIndex;
            TValue value;

            // Under read/write lock
            using (ReadWriteSynchronizationLocker rwl = this.ReadWriteLock())
            {
                if (this.InternalContainer.TryGetValue(
                        key,
                        out value))
                {
                    // Within read lock, if the key is found, return the value.
                    valueAction(value);
                    return(value);
                }

                rwl.Upgrade();

                if (this.InternalContainer.TryGetValue(
                        key,
                        out value))
                {
                    // Re-check within a write lock, to ensure that something else hasn't already added it.
                    valueAction(value);
                    return(value);
                }

                // Generate the value
                value = valueGenerator();

                // Add the item
                newIndex = this.InternalContainer.Add(
                    key,
                    value);
            }

            // NOTIFICATIONS

            // Collection changed
            if (newIndex == -1)
            {
                // If no index could be found for an item (Dictionary add)
                this.RaiseCollectionReset();
            }
            else
            {
                // If index was added at a specific index
                this.RaiseCollectionChangedAdd(
                    new KeyValuePair <TKey, TValue>(
                        key,
                        value), newIndex);
            }

            // Property changed
            this.RaisePropertyChanged(nameof(this.Count));

            // Contents may have changed
            this.ContentsMayHaveChanged();

            return(value);
        }
コード例 #11
0
    /// <summary>
    ///     Gets the item at the specified index.
    /// </summary>
    /// <value>
    ///     The item.
    /// </value>
    /// <param name="index">The index.</param>
    /// <returns>The item at the specified index.</returns>
    public virtual T this[int index]
    {
        get
        {
            // PRECONDITIONS

            // Current object not disposed
            ThrowIfCurrentObjectDisposed();

            // ACTION
            using (ReadLock())
            {
                return(InternalListContainer[index]);
            }
        }

        set
        {
            // PRECONDITIONS

            // Current object not disposed
            ThrowIfCurrentObjectDisposed();

            // ACTION
            T oldValue;

            // Inside a read/write lock
            using (ReadWriteSynchronizationLocker lockContext = ReadWriteLock())
            {
                // Verify if we are within bounds in a read lock
                if (index >= InternalListContainer.Count)
                {
                    throw new IndexOutOfRangeException();
                }

                // Upgrade to a write lock
                lockContext.Upgrade();

                // Get the old value
                oldValue = InternalListContainer[index];

                // Two undo/redo transactions
                using (OperationTransaction tc1 = CheckItemAutoCapture(value))
                {
                    using (OperationTransaction tc2 = CheckItemAutoRelease(oldValue))
                    {
                        // Replace with new value
                        InternalListContainer[index] = value;

                        // Push the undo level
                        PushUndoLevel(
                            new ChangeAtStateChange <T>(
                                index,
                                value,
                                oldValue));

                        // Mark the second transaction as successful
                        tc2.Success();
                    }

                    // Mark the first transaction as successful
                    tc1.Success();
                }
            }

            // NOTIFICATION

            // Collection changed
            RaiseCollectionChangedChanged(
                oldValue,
                value,
                index);

            // Property changed
            RaisePropertyChanged(nameof(Count));

            // Contents may have changed
            ContentsMayHaveChanged();
        }
    }