So, my last post on this topic talked about adapting my component pool into a more generic packed-array object pool. It turns out that my implementation of this was absolutely littered with bugs. So many bugs that I’m surprised the game functioned at all, let alone in a remotely similar way to how it worked before.
The main reason for all the bugs was that I was still letting the object pool return a pointer to the actual new object that was just created. And I had objects holding on to this pointer, all the while the object pool was rearranging memory every time anything was deleted. This led, of course, to objects pointing to and manipulating incorrect data.
So the first thing to fix was making sure the Create function would return a handle rather than a pointer. But what to return when the object pool is full? I had been returning a nullptr. My initial fix for this had been to return the capacity of the pool, but of course that number is still a valid handle, and this caused a couple of tricky bugs that took me a while to track down. So I am now returning 0, since that is never a valid handle (unless the unsigned int variable overflows, but then I’ve got other problems..)
However I decided that Components still do need to store an actual pointer to their owning GameObjects. So if that GameObject moves as part of an object pool rearrangement, I need to fix the pointers in each of the Components. In order to do this I created a “post move” function for anything that can be pooled (hmm, should I make things inherit from a Poolable abstract class to make sure people don’t leave out the post move function? Or would the multiple inheritance become too much, since many of these things will also be Subjects for the Observer pattern too?) Anyway, in this post move function I simply loop through the component list for a game object and call the “SetGameObject” function from Component.
Once I’d pooled my bullets, I realised that the Init function wasn’t clearing the Component and Observer lists from the GameObject class. This resulted in a Bullet thinking it had more Observers than it really did, as well as too many Components. I ended up clearing these lists in the Bullet Init, but reading over this now, this should really be done in the GameObject Init and called by Bullet.
It also became obvious that I would need to pass the Object pools around to multiple different places. I ended up creating a “helper” class for this, since that meant I could just pass a pointer to this helper class, rather than needing to pass each individual object pool (my function argument lists had been getting ridiculously long). I tried my best to generalise this helper class, but once again my lack of practice with templates came back to bite me, and I started down a few idiotic paths without getting anywhere. This post on Stack Overflow seems similar to what I wanted, but for now I just hard coded in the 4 different components I’m using. If I start to add more components to my engine I will really need to fix this up properly.
So, once I’d fixed up all these bugs things returned a bit more to normal. I’ve actually done another series of changes since these (I’m behind on blogging, but I have been coding!) but I’ll leave those for another post. As always you can see my code on GitHub.