// (c) Copyright Microsoft Corporation. // This source is subject to the Microsoft Public License (Ms-PL). // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. // All other rights reserved. using System; using System.Collections.Generic; namespace System.Windows.Controls.DataVisualization { /// /// A pool of objects that can be reused. /// /// The type of object in the pool. internal class ObjectPool { /// /// The default minimum number objects to keep in the pool. /// private const int DefaultMinimumObjectsInThePool = 10; #if DEBUG /// /// A value indicating whether the pool is being traversed. /// private bool _traversing = false; #endif /// /// A function which creates objects. /// private Func _createObject; /// /// The list of objects. /// private List _objects; /// /// The index of the current item in the list. /// private int currentIndex = 0; /// /// The minimum number of objects to keep in the pool. /// private int minimumObjectsInThePool; /// /// Initializes a new instance of the ObjectPool class. /// /// The minimum number of objects /// to keep in the pool. /// The function that creates the objects. /// public ObjectPool( int minimumObjectsInThePool, Func createObject) { this._objects = new List(minimumObjectsInThePool); this.minimumObjectsInThePool = minimumObjectsInThePool; this._createObject = createObject; Reset(); } /// /// Initializes a new instance of the ObjectPool class. /// /// The function that creates the objects. /// public ObjectPool(Func createObject) : this(DefaultMinimumObjectsInThePool, createObject) { } /// /// Performs an operation on the subsequent, already-created objects /// in the pool. /// /// The action to perform on the remaining objects. /// public void ForEachRemaining(Action action) { for (var cnt = currentIndex; cnt < _objects.Count; cnt++) { action(_objects[cnt]); } } /// /// Creates a new object or reuses an existing object in the pool. /// /// A new or existing object in the pool. public T Next() { if (currentIndex == _objects.Count) { _objects.Add(_createObject()); } T item = _objects[currentIndex]; currentIndex++; return item; } /// /// Resets the pool of objects. /// public void Reset() { #if DEBUG _traversing = true; #endif currentIndex = 0; } /// /// Finishes the object creation process. /// /// /// If there are substantially more remaining objects in the pool those /// objects may be removed. /// public void Done() { #if DEBUG _traversing = false; #endif // Remove the rest of the objects if we are using less than // half of the pool. if (currentIndex != 0 && _objects.Count > 0 && currentIndex >= minimumObjectsInThePool && currentIndex < _objects.Count / 2) { _objects.RemoveRange(currentIndex, _objects.Count - currentIndex); } } /// /// Removes the objects from the pool. /// public void Clear() { #if DEBUG System.Diagnostics.Debug.Assert(!_traversing, "Cannot clear an object pool while it is being traversed."); #endif _objects.Clear(); } } }