Advertisement
Guest User

Untitled

a guest
Dec 12th, 2012
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.63 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using Microsoft.Xna.Framework;
  6.  
  7. namespace MyPoolNamespace
  8. {
  9.     /// <summary>
  10.     /// Represents a fixed-size pool of available items that can be removed
  11.     /// as needed and returned when finished.
  12.     /// </summary>
  13.     public class Pool<T> : IEnumerable<T> where T : new()
  14.     {
  15.         /// <summary>
  16.         /// Represents an entry in a Pool collection.
  17.         /// </summary>
  18.         public struct Node
  19.         {
  20.             /// <summary>
  21.             /// Used internally to track which entry in the Pool
  22.             /// is associated with this Node.
  23.             /// </summary>
  24.             internal int NodeIndex;
  25.  
  26.             /// <summary>
  27.             /// Item stored in Pool.
  28.             /// </summary>
  29.             public T Item;
  30.         }
  31.  
  32.  
  33.         /// <summary>
  34.         /// Fixed Pool of item nodes.
  35.         /// </summary>
  36.         private Node[] pool;
  37.  
  38.  
  39.         /// <summary>
  40.         /// Array containing the active/available state for each item node
  41.         /// in the Pool.
  42.         /// </summary>
  43.         private bool[] active;
  44.  
  45.  
  46.         /// <summary>
  47.         /// Queue of available item node indices.
  48.         /// </summary>
  49.         private Queue<int> available;
  50.  
  51.  
  52.         /// <summary>
  53.         /// Gets the number of available items in the Pool.
  54.         /// </summary>
  55.         /// <remarks>
  56.         /// Retrieving this property is an O(1) operation.
  57.         /// </remarks>
  58.         public int AvailableCount
  59.         {
  60.             get { return available.Count; }
  61.         }
  62.  
  63.  
  64.         /// <summary>
  65.         /// Gets the number of active items in the Pool.
  66.         /// </summary>
  67.         /// <remarks>
  68.         /// Retrieving this property is an O(1) operation.
  69.         /// </remarks>
  70.         public int ActiveCount
  71.         {
  72.             get { return pool.Length - available.Count; }
  73.         }
  74.  
  75.  
  76.         /// <summary>
  77.         /// Gets the total number of items in the Pool.
  78.         /// </summary>
  79.         /// <remarks>
  80.         /// Retrieving this property is an O(1) operation.
  81.         /// </remarks>
  82.         public int Capacity
  83.         {
  84.             get { return pool.Length; }
  85.         }
  86.  
  87.  
  88.         /// <summary>
  89.         /// Initializes a new instance of the Pool class.
  90.         /// </summary>
  91.         /// <param name="numItems">Total number of items in the Pool.</param>
  92.         /// <exception cref="ArgumentException">
  93.         /// Number of items is less than 1.
  94.         /// </exception>
  95.         /// <remarks>
  96.         /// This constructor is an O(n) operation, where n is capacity.
  97.         /// </remarks>
  98.         public Pool(int capacity)
  99.         {
  100.             if (capacity <= 0)
  101.             {
  102.                 throw new ArgumentOutOfRangeException(
  103.                               "Pool must contain at least one item.");
  104.             }
  105.  
  106.             pool = new Node[capacity];
  107.             active = new bool[capacity];
  108.             available = new Queue<int>(capacity);
  109.  
  110.             for (int i = 0; i < capacity; i++)
  111.             {
  112.                 pool[i] = new Node();
  113.                 pool[i].NodeIndex = i;
  114.                 pool[i].Item = new T();
  115.  
  116.                 active[i] = false;
  117.                 available.Enqueue(i);
  118.             }
  119.         }
  120.  
  121.  
  122.         /// <summary>
  123.         /// Makes all items in the Pool available.
  124.         /// </summary>
  125.         /// <remarks>
  126.         /// This method is an O(n) operation, where n is Capacity.
  127.         /// </remarks>
  128.         public void Clear()
  129.         {
  130.             available.Clear();
  131.  
  132.             for (int i = 0; i < pool.Length; i++)
  133.             {
  134.                 active[i] = false;
  135.                 available.Enqueue(i);
  136.             }
  137.         }
  138.  
  139.  
  140.         /// <summary>
  141.         /// Removes an available item from the Pool and makes it active.
  142.         /// </summary>
  143.         /// <returns>The node that is removed from the available Pool.</returns>
  144.         /// <exception cref="InvalidOperationException">
  145.         /// There are no available items in the Pool.
  146.         /// </exception>
  147.         /// <remarks>
  148.         /// This method is an O(1) operation.
  149.         /// </remarks>
  150.         public Node Get()
  151.         {
  152.             int nodeIndex = available.Dequeue();
  153.             active[nodeIndex] = true;
  154.             return pool[nodeIndex];
  155.         }
  156.  
  157.  
  158.         /// <summary>
  159.         /// Returns an active item to the available Pool.
  160.         /// </summary>
  161.         /// <param name="item">The node to return to the available Pool.</param>
  162.         /// <exception cref="ArgumentException">
  163.         /// The node being returned is invalid.
  164.         /// </exception>
  165.         /// <exception cref="InvalidOperationException">
  166.         /// The node being returned was not active.
  167.         /// This probably means the node was previously returned.
  168.         /// </exception>
  169.         /// <remarks>
  170.         /// This method is an O(1) operation.
  171.         /// </remarks>
  172.         public void Return(Node item)
  173.         {
  174.             if ((item.NodeIndex < 0) || (item.NodeIndex > pool.Length))
  175.             {
  176.                 throw new ArgumentException("Invalid item node.");
  177.             }
  178.  
  179.             if (!active[item.NodeIndex])
  180.             {
  181.                 throw new InvalidOperationException("Attempt to return an inactive node.");
  182.             }
  183.  
  184.             active[item.NodeIndex] = false;
  185.             available.Enqueue(item.NodeIndex);
  186.         }
  187.  
  188.  
  189.         /// <summary>
  190.         /// Sets the value of the item in the Pool associated with the
  191.         /// given node.
  192.         /// </summary>
  193.         /// <param name="item">The node whose item value is to be set.</param>
  194.         /// <exception cref="ArgumentException">
  195.         /// The node being returned is invalid.
  196.         /// </exception>
  197.         /// <remarks>
  198.         /// This method is necessary to modify the value of a value type stored
  199.         /// in the Pool.  It copies the value of the node's Item field into the
  200.         /// Pool.
  201.         /// This method is an O(1) operation.
  202.         /// </remarks>
  203.         public void SetItemValue(Node item)
  204.         {
  205.             if ((item.NodeIndex < 0) || (item.NodeIndex > pool.Length))
  206.             {
  207.                 throw new ArgumentException("Invalid item node.");
  208.             }
  209.  
  210.             pool[item.NodeIndex].Item = item.Item;
  211.         }
  212.  
  213.  
  214.         public bool IsActive(int index)
  215.         {
  216.             if (active[index])
  217.                 return true;
  218.             else
  219.                 return false;
  220.                
  221.         }
  222.  
  223.         /// <summary>
  224.         /// Copies the active items to an existing one-dimensional Array,
  225.         /// starting at the specified array index.
  226.         /// </summary>
  227.         /// <param name="array">
  228.         /// The one-dimensional array to which active Pool items will be
  229.         /// copied.
  230.         /// </param>
  231.         /// <param name="arrayIndex">
  232.         /// The index in array at which copying begins.
  233.         /// </param>
  234.         /// <returns>The number of items copied.</returns>
  235.         /// <remarks>
  236.         /// This method is an O(n) operation, where n is the smaller of
  237.         /// capacity or the array length.
  238.         /// </remarks>
  239.         public int CopyTo(T[] array, int arrayIndex)
  240.         {
  241.             int index = arrayIndex;
  242.  
  243.             foreach (Node item in pool)
  244.             {
  245.                 if (active[item.NodeIndex])
  246.                 {
  247.                     array[index++] = item.Item;
  248.  
  249.                     if (index == array.Length)
  250.                     {
  251.                         return index - arrayIndex;
  252.                     }
  253.                 }
  254.             }
  255.  
  256.             return index - arrayIndex;
  257.         }
  258.  
  259.  
  260.         /// <summary>
  261.         /// Gets an enumerator that iterates through the active items
  262.         /// in the Pool.
  263.         /// </summary>
  264.         /// <returns>Enumerator for the active items.</returns>
  265.         /// <remarks>
  266.         /// This method is an O(n) operation,
  267.         /// where n is Capacity divided by ActiveCount.
  268.         /// </remarks>
  269.         public IEnumerator<T> GetEnumerator()
  270.         {
  271.             foreach (Node item in pool)
  272.             {
  273.                 if (active[item.NodeIndex])
  274.                 {
  275.                     yield return item.Item;
  276.                 }
  277.             }
  278.         }
  279.  
  280.  
  281.         /// <summary>
  282.         /// Gets an enumerator that iterates through the active nodes
  283.         /// in the Pool.
  284.         /// </summary>
  285.         /// <remarks>
  286.         /// This method is an O(n) operation,
  287.         /// where n is Capacity divided by ActiveCount.
  288.         /// </remarks>
  289.         public IEnumerable<Node> ActiveNodes
  290.         {
  291.             get
  292.             {
  293.                 foreach (Node item in pool)
  294.                 {
  295.                     if (active[item.NodeIndex])
  296.                     {
  297.                         yield return item;
  298.                     }
  299.                 }
  300.             }
  301.         }
  302.  
  303.  
  304.         /// <summary>
  305.         /// Gets an enumerator that iterates through all of the nodes
  306.         /// in the Pool.
  307.         /// </summary>
  308.         /// <remarks>
  309.         /// This method is an O(1) operation.
  310.         /// </remarks>
  311.         public IEnumerable<Node> AllNodes
  312.         {
  313.             get
  314.             {
  315.                 foreach (Node item in pool)
  316.                 {
  317.                     yield return item;
  318.                 }
  319.             }
  320.         }
  321.  
  322.  
  323.         /// <summary>
  324.         /// Implementation of the IEnumerable interface.
  325.         /// </summary>
  326.         /// <returns></returns>
  327.         IEnumerator IEnumerable.GetEnumerator()
  328.         {
  329.             return GetEnumerator();
  330.         }
  331.     }
  332. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement