All the controls missing in WPF. Over 1 million downloads.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
4.6 KiB

// (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
{
/// <summary>
/// A pool of objects that can be reused.
/// </summary>
/// <typeparam name="T">The type of object in the pool.</typeparam>
internal class ObjectPool<T>
{
/// <summary>
/// The default minimum number objects to keep in the pool.
/// </summary>
private const int DefaultMinimumObjectsInThePool = 10;
#if DEBUG
/// <summary>
/// A value indicating whether the pool is being traversed.
/// </summary>
private bool _traversing = false;
#endif
/// <summary>
/// A function which creates objects.
/// </summary>
private Func<T> _createObject;
/// <summary>
/// The list of objects.
/// </summary>
private List<T> _objects;
/// <summary>
/// The index of the current item in the list.
/// </summary>
private int currentIndex = 0;
/// <summary>
/// The minimum number of objects to keep in the pool.
/// </summary>
private int minimumObjectsInThePool;
/// <summary>
/// Initializes a new instance of the ObjectPool class.
/// </summary>
/// <param name="minimumObjectsInThePool">The minimum number of objects
/// to keep in the pool.</param>
/// <param name="createObject">The function that creates the objects.
/// </param>
public ObjectPool(
int minimumObjectsInThePool,
Func<T> createObject)
{
this._objects = new List<T>(minimumObjectsInThePool);
this.minimumObjectsInThePool = minimumObjectsInThePool;
this._createObject = createObject;
Reset();
}
/// <summary>
/// Initializes a new instance of the ObjectPool class.
/// </summary>
/// <param name="createObject">The function that creates the objects.
/// </param>
public ObjectPool(Func<T> createObject)
: this(DefaultMinimumObjectsInThePool, createObject)
{
}
/// <summary>
/// Performs an operation on the subsequent, already-created objects
/// in the pool.
/// </summary>
/// <param name="action">The action to perform on the remaining objects.
/// </param>
public void ForEachRemaining(Action<T> action)
{
for (var cnt = currentIndex; cnt < _objects.Count; cnt++)
{
action(_objects[cnt]);
}
}
/// <summary>
/// Creates a new object or reuses an existing object in the pool.
/// </summary>
/// <returns>A new or existing object in the pool.</returns>
public T Next()
{
if (currentIndex == _objects.Count)
{
_objects.Add(_createObject());
}
T item = _objects[currentIndex];
currentIndex++;
return item;
}
/// <summary>
/// Resets the pool of objects.
/// </summary>
public void Reset()
{
#if DEBUG
_traversing = true;
#endif
currentIndex = 0;
}
/// <summary>
/// Finishes the object creation process.
/// </summary>
/// <remarks>
/// If there are substantially more remaining objects in the pool those
/// objects may be removed.
/// </remarks>
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);
}
}
/// <summary>
/// Removes the objects from the pool.
/// </summary>
public void Clear()
{
#if DEBUG
System.Diagnostics.Debug.Assert(!_traversing, "Cannot clear an object pool while it is being traversed.");
#endif
_objects.Clear();
}
}
}