Wednesday, January 16, 2013

Final pool version

Since I went from C# to AS3 in order to complete web games I realized that the lack of generics in AS3 was going to be a huge problem for my pooling system, this forced me to think things once again and the result was something more elegant, secure and completely contained within the pooled class.

Making use of the factory design pattern once again I was able to create a pool system within the same class (which is now a template in my IDE), here is how it goes:

public class PooledItem
{
   private static var PoolHead:PooledItem;
   private var Next:PooledItem;
   private var Self:PooledItem;

   public function PooledItem()
   {
      Self = this;
   }

   public static function Create():PooledItem
   {
      var Vessel:PooledItem;
      if(PooledHead != null)
      {
         Vessel = PoolHead;
         PoolHead = PoolHead.Next;
      }
      else
      {
         Vessel = new PooledItem();
      }
      
      return Vessel;
   }
}


The PoolHead is private and static, making it unique locally and impossible to access from outside this class, then we have the Next and the Self which are unique to each instance of the PooledItem, and finally we have a factory pattern which creates a new instance of a PooledItem if the head is null, but if the head is not null it will return it and set the new head as the next element in the queue.

One thing to have in mind is that AS3 does not allow to have private constructors, thus making it possible to create an instance of the PooledItem without the factory method, if this happens and you don't properly get rid of it by calling its recycle method then you will have an extra element (outside the pool) doing nothing, but even if you create it without the "create" function you can still put it back in the pool by calling recycle, so no real harm done if handled properly, still if this was not AS3 I would make the constructor private.

Going to the recycle function now, the recycle function is where I do all my clean up code (if required depending on the elements of the class) as well as to put elements back into the pool:

public function Recycle():void
{
   //Do clean up code, maybe recycle other pooled items that were created within this
   //class or release references of an element to let GC deal with it, etc.

   Next = PoolHead; //we set the next element as the current head.
   PoolHead = Self; //and finally we set the this element as the new head.
}


And that's it, it is amazing how essential and memory friendly this can be, allocating memory and deallocating memory can be very tasking in the system, specially if you are planning on putting your games in mobile devices, have in mind also that the more memory you use the more battery it might consume, so in order to have some balance make sure to maintain your pools, this can be achieve by an internal reference counter and releasing some of them if the number gets to a certain point, however you want to handle that I will leave to you.


No comments:

Post a Comment