One thing I like the most in programming is finding out how to fix the mundane problems. One problem I've had with particle systems and other things that tend to allocate and delete lots of memory is fighting the GC. So I came up with a class that takes care of this. It's a preallocated, generic pool class that gives all the control of managing the list to the list itself. Since I'm so proud of my pool I wanted to release it to the public for use, critisism, and improvement/suggestions. First I just want to briefly outline how the class works.
I want to start with constructors since one of the biggest hurdles for me was finding a way to manage a pool of
anything. I didn't want the constructor of an object stopping me from storing it. So I created a number of constructors to handle virtually any object.
I gave it a few constructors where the only required parameter is the number of objects to allocate space for. You can also specify delegates that handle validating objects in the list. The default option is to simply check the objects against null, but with the delegate you can do whatever check you like. For instance a particle system might use the delegate to check a particle's life against a pre-set time limit.
The constructors can also use a delegate for the initialization in case you want to create more complex objects. You can then simply create a new object and return it for the list to add. This allows you to easily code random starting parameters for the objects without having to store or use a Random variable in the object itself.
I also put some reflection in there such that you can give the constructor a Type[] of parameter types and an Object[] of parameters and have the pool call that specific constructor for the object. This allows you to easily have a resource pool that will manage things like GameComponents where a Game instance is required for creation.
As a backup to both the delegate and reflection constructors, if either fails to work the pool will attempt to use reflection to find a parameterless constructor and call that. If
that fails, it just throws an exception. :)
So enough about constructors. How does the rest of the pool function? Glad you asked ;).
When your program is running, the most important method to call is ValidateObjects() which will iterate through the pool, calling the delegate you gave to see if objects are to be considered valid or invalid. An object deemed invalid is memory that the pool will get ready for handing out the next time you want a "new" object.
So to get a new object from the list you just call GetNextValidObject(). Easy as that. It'll return the first invalid object it finds or null if the entire pool is valid. So a complex example of how I use this would be like this:
Ship2 ship = ships.GetNewValidObject();
if (ship != null)
{
ship.vertices.Clear();
for (int i = 0; i < vertices.Length; i++)
ship.vertices.Add(vertices[i]);
ship.alive = true;
ship.exploding = false;
ship.explosionTimer = 0f;
ship.debris.Clear();
}
So you get the next object, check if it's null, and then set the parameters you need. You have to remember that the returned object is not an object that was called with 'new' so it will still have old data in it. You may want to make a method that clears an object (something like, in my example, Ship2.Clear() that will handle clearing it for reuse).
The pool also implements the IEnumerable<> interface as well as having the [] operator defined. The [] operator is the prefered method for going through the list as it will only let you get valid objects. Luckily the pool also exposes properties for getting the maximum number of objects, the number of valid objects, and the number of invalid objects.
Needless to say this class has become a cornerstone for my programming in XNA because it starts to remove the fear of the GC hitting me mid-game. Since I've found so much use for it, I figured others might as well. So here it is. Full source code for you to do with it as you will. Hopefully you will find it useful like I have.
http://xna.multigan.com/pastebin/?page=view&id=1184377072And a brief sample code can be found here:
http://xna.multigan.com/pastebin/?page=view&id=1184378263I did a lot of documenting the methods so it shouldn't be too hard (using Intellisense) to get how it works. Any comments, questions, suggestions, death threats, or anything, just let me know. :)