Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using Microsoft.Xna.Framework;
- namespace MyPoolNamespace
- {
- /// <summary>
- /// Represents a fixed-size pool of available items that can be removed
- /// as needed and returned when finished.
- /// </summary>
- public class Pool<T> : IEnumerable<T> where T : new()
- {
- /// <summary>
- /// Represents an entry in a Pool collection.
- /// </summary>
- public struct Node
- {
- /// <summary>
- /// Used internally to track which entry in the Pool
- /// is associated with this Node.
- /// </summary>
- internal int NodeIndex;
- /// <summary>
- /// Item stored in Pool.
- /// </summary>
- public T Item;
- }
- /// <summary>
- /// Fixed Pool of item nodes.
- /// </summary>
- private Node[] pool;
- /// <summary>
- /// Array containing the active/available state for each item node
- /// in the Pool.
- /// </summary>
- private bool[] active;
- /// <summary>
- /// Queue of available item node indices.
- /// </summary>
- private Queue<int> available;
- /// <summary>
- /// Gets the number of available items in the Pool.
- /// </summary>
- /// <remarks>
- /// Retrieving this property is an O(1) operation.
- /// </remarks>
- public int AvailableCount
- {
- get { return available.Count; }
- }
- /// <summary>
- /// Gets the number of active items in the Pool.
- /// </summary>
- /// <remarks>
- /// Retrieving this property is an O(1) operation.
- /// </remarks>
- public int ActiveCount
- {
- get { return pool.Length - available.Count; }
- }
- /// <summary>
- /// Gets the total number of items in the Pool.
- /// </summary>
- /// <remarks>
- /// Retrieving this property is an O(1) operation.
- /// </remarks>
- public int Capacity
- {
- get { return pool.Length; }
- }
- /// <summary>
- /// Initializes a new instance of the Pool class.
- /// </summary>
- /// <param name="numItems">Total number of items in the Pool.</param>
- /// <exception cref="ArgumentException">
- /// Number of items is less than 1.
- /// </exception>
- /// <remarks>
- /// This constructor is an O(n) operation, where n is capacity.
- /// </remarks>
- public Pool(int capacity)
- {
- if (capacity <= 0)
- {
- throw new ArgumentOutOfRangeException(
- "Pool must contain at least one item.");
- }
- pool = new Node[capacity];
- active = new bool[capacity];
- available = new Queue<int>(capacity);
- for (int i = 0; i < capacity; i++)
- {
- pool[i] = new Node();
- pool[i].NodeIndex = i;
- pool[i].Item = new T();
- active[i] = false;
- available.Enqueue(i);
- }
- }
- /// <summary>
- /// Makes all items in the Pool available.
- /// </summary>
- /// <remarks>
- /// This method is an O(n) operation, where n is Capacity.
- /// </remarks>
- public void Clear()
- {
- available.Clear();
- for (int i = 0; i < pool.Length; i++)
- {
- active[i] = false;
- available.Enqueue(i);
- }
- }
- /// <summary>
- /// Removes an available item from the Pool and makes it active.
- /// </summary>
- /// <returns>The node that is removed from the available Pool.</returns>
- /// <exception cref="InvalidOperationException">
- /// There are no available items in the Pool.
- /// </exception>
- /// <remarks>
- /// This method is an O(1) operation.
- /// </remarks>
- public Node Get()
- {
- int nodeIndex = available.Dequeue();
- active[nodeIndex] = true;
- return pool[nodeIndex];
- }
- /// <summary>
- /// Returns an active item to the available Pool.
- /// </summary>
- /// <param name="item">The node to return to the available Pool.</param>
- /// <exception cref="ArgumentException">
- /// The node being returned is invalid.
- /// </exception>
- /// <exception cref="InvalidOperationException">
- /// The node being returned was not active.
- /// This probably means the node was previously returned.
- /// </exception>
- /// <remarks>
- /// This method is an O(1) operation.
- /// </remarks>
- public void Return(Node item)
- {
- if ((item.NodeIndex < 0) || (item.NodeIndex > pool.Length))
- {
- throw new ArgumentException("Invalid item node.");
- }
- if (!active[item.NodeIndex])
- {
- throw new InvalidOperationException("Attempt to return an inactive node.");
- }
- active[item.NodeIndex] = false;
- available.Enqueue(item.NodeIndex);
- }
- /// <summary>
- /// Sets the value of the item in the Pool associated with the
- /// given node.
- /// </summary>
- /// <param name="item">The node whose item value is to be set.</param>
- /// <exception cref="ArgumentException">
- /// The node being returned is invalid.
- /// </exception>
- /// <remarks>
- /// This method is necessary to modify the value of a value type stored
- /// in the Pool. It copies the value of the node's Item field into the
- /// Pool.
- /// This method is an O(1) operation.
- /// </remarks>
- public void SetItemValue(Node item)
- {
- if ((item.NodeIndex < 0) || (item.NodeIndex > pool.Length))
- {
- throw new ArgumentException("Invalid item node.");
- }
- pool[item.NodeIndex].Item = item.Item;
- }
- public bool IsActive(int index)
- {
- if (active[index])
- return true;
- else
- return false;
- }
- /// <summary>
- /// Copies the active items to an existing one-dimensional Array,
- /// starting at the specified array index.
- /// </summary>
- /// <param name="array">
- /// The one-dimensional array to which active Pool items will be
- /// copied.
- /// </param>
- /// <param name="arrayIndex">
- /// The index in array at which copying begins.
- /// </param>
- /// <returns>The number of items copied.</returns>
- /// <remarks>
- /// This method is an O(n) operation, where n is the smaller of
- /// capacity or the array length.
- /// </remarks>
- public int CopyTo(T[] array, int arrayIndex)
- {
- int index = arrayIndex;
- foreach (Node item in pool)
- {
- if (active[item.NodeIndex])
- {
- array[index++] = item.Item;
- if (index == array.Length)
- {
- return index - arrayIndex;
- }
- }
- }
- return index - arrayIndex;
- }
- /// <summary>
- /// Gets an enumerator that iterates through the active items
- /// in the Pool.
- /// </summary>
- /// <returns>Enumerator for the active items.</returns>
- /// <remarks>
- /// This method is an O(n) operation,
- /// where n is Capacity divided by ActiveCount.
- /// </remarks>
- public IEnumerator<T> GetEnumerator()
- {
- foreach (Node item in pool)
- {
- if (active[item.NodeIndex])
- {
- yield return item.Item;
- }
- }
- }
- /// <summary>
- /// Gets an enumerator that iterates through the active nodes
- /// in the Pool.
- /// </summary>
- /// <remarks>
- /// This method is an O(n) operation,
- /// where n is Capacity divided by ActiveCount.
- /// </remarks>
- public IEnumerable<Node> ActiveNodes
- {
- get
- {
- foreach (Node item in pool)
- {
- if (active[item.NodeIndex])
- {
- yield return item;
- }
- }
- }
- }
- /// <summary>
- /// Gets an enumerator that iterates through all of the nodes
- /// in the Pool.
- /// </summary>
- /// <remarks>
- /// This method is an O(1) operation.
- /// </remarks>
- public IEnumerable<Node> AllNodes
- {
- get
- {
- foreach (Node item in pool)
- {
- yield return item;
- }
- }
- }
- /// <summary>
- /// Implementation of the IEnumerable interface.
- /// </summary>
- /// <returns></returns>
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement