Reputation: 340
I'm creating an android game that uses an Entity object class that is then extended in many different types (i.e. enemies, bullets, etc). Is there a way to create a pool of type Entity and then transform the obtained Entity objects into whatever I need at runtime (say a bullet type)? Passing the entity as an argument to a constructor will just defeat the purpose of the pool correct? An example is below:
public class EntityPool extends Pool<Entity> {
public EntityPool (int initialCapacity, int max) {
super(initialCapacity, max);
}
protected PooledEntity newObject () {
return new PooledEntity();
}
public Entity obtain (int objectType) {
Entity ent = super.obtain();
if (objectType==SOME_OBJECT_TYPE)
//Do something to make ent into that object type
return ent;
}
public class PooledEntity extends Entity {
PooledEntity () {
super(null, 0, 0);
}
public void free () {
EntityPool.this.free(this);
}
}
}
Upvotes: 2
Views: 5205
Reputation: 4137
With your current code, your pool can store any object that is an Entity or of a sub class of entity. As a result, you can only use instanceof
, or downcast to get the type of the concrete object.
If you would like to have different Pools per type, you can consider changing the declaration of the pool to :
public class EntityPool<T> extends Pool<T extends Entity>
And then for example have:
EntityPool<Bullet> bulletsPool = new EntityPool<Bullet>(); //only objects of Bullet of sub classes can be added
Upvotes: 0
Reputation: 25177
The point of an object pool is generally to avoid system allocation and deallocation overheads and requires you know a "worst case" limit on the number of each type of entity you will want to allocate. So, assuming your entities are rather different in lifetime and usage, you probably want to have separate pools for each entity. (You can definitely improve the pool as in @zaske's answer.)
On the other hand, if you really want a single Entity
pool, and you want to customize those entities at run-time, you could change from using Entity subclasses to something like:
class Entity {
EntityCustomizer custom;
...
}
Then when fetching an Entity
out of the pool you pass in a Bullet
or Ship
or whatever customizer object:
public Entity obtain (int objectType) {
Entity ent = super.obtain();
if (objectType==SOME_OBJECT_TYPE)
ent.custom = EntityCustomizer.SOME_OBJECT_TYPE_IMPL;
return ent;
}
(I'm pretty sure this is a well-known pattern and I should be using the appropriate language to identify the parts ...)
All said, I think separate pools for each Entity type are the way to go, as my work-around is pretty hacky (you're trading a bunch of compile-time type checking for some run-time flexibility).
Upvotes: 1