I spent the evening learning about Generics in C#. Using my newfound knowledge, I was able to revamp my object pool. I knew that what I was doing initially wasn't the best approach, but it worked and it was fast. My new version works, is just as fast and is a lot more elegant.
In the old version, I had a pool for chunks, cubes and creatures. Each individual pool had something like this:
In the old version, I had a pool for chunks, cubes and creatures. Each individual pool had something like this:
1: public static Queue<chunk> chunkPool;
2: public static int chunkCount;
3: public static int numFreeChunks;
It also had multiple methods for getting an object and putting it back. Everytime I wanted a new pool, I had to create a new set of objects and methods. It worked, but was ugly. The new pool is this:
1: public static class pool
2: {
3: public static hose<tree> treePool;
4: public static hose<change> changesPool;
5: public static hose<cube> cubePool;
6: public static void init()
7: {
8: treePool = new hose<tree>();
9: cubePool = new hose<cube>();
10: changesPool = new hose<change>();
11: }
12: }
Hose<T> is a generic class that has everything embedded in it. Creating new pools is now much cleaner and easier.
I've been testing this in the 2d version (from here on out, called 2dr) instead of the 3d (called 3dr). Once I make sure it's cool, I'll migrate it over.
Edit: Forgot to put this originally. My hose class: http://pastebin.com/mNU5qgHw
using System;
using System.Collections.Generic;
namespace R_01.classes
{
public class hose<T>
where T : class, new()
{
private Queue<T> objectPool;
public int count;
public int numFree;
private bool lockObjects;
public hose()
{
objectPool = new Queue<T>();
lockObjects = false;
numFree = 0;
count = 0;
}
public T get()
{
while (lockObjects && !gameData.exiting) { }
lockObjects = true;
T obj;
lock (objectPool)
{
try
{
if (numFree > 0)
{
obj = objectPool.Dequeue();
numFree--;
if (obj == null)
{
obj = new T();
count++;
}
}
else
{
obj = new T();
count++;
}
}
catch (Exception ex)
{
ex.ToString();
obj = new T();
count++;
}
finally
{
lockObjects = false;
}
}
return obj;
}
public void put(T obj)
{
while (lockObjects && !gameData.exiting) { }
lockObjects = true;
lock (objectPool)
{
try
{
objectPool.Enqueue(obj);
numFree++;
}
catch (Exception ex)
{
ex.ToString();
}
finally
{
lockObjects = false;
}
}
}
}
}
3 comments:
Any particular reason you call your generic class 'hose'?
Great blog by the way. I always look forward to updates :)
My object pool is completely empty at first until it's filled up somehow. In order to get water (objects) into a pool, you use a hose.
I think that was my logic, haha.
Also, here's my hose class: http://pastebin.com/mNU5qgHw
Forgot to put it in the OP.
Post a Comment