// (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();
}
}
}