Designing an Object Pool for Unity - Philosophy (3)
We want to talk about our approach/philosophy for Object Pooling. It is the underpinning of our feature requirements, as well as the template for our design and implementation.
We want a design that is simple, highly effective, extensible, and versatile
We want a design that works really well for .NET objects (POCOs)
We want a design that extends to work well for Unity Game Objects
We want a low-latency mechanism that enables concurrency for .NET objects
The code doesn't need to be overly complicated or contain extraneous features that are not part of our core requirements. Anything difficult to understand should be re-factored, and anything tricky should be re-thought. The less moving parts, the more efficient and higher quality the components will be. Most importantly, the usage model should be simple and easy. It needs to be easy for other developers to setup, manage, and use object pooling correctly and effectively.
The components need to meet the objective, and because we will be changing other components and system to leverage the object pooling components it needs to add clear value thru increased efficiency and performance.
Although we want the core to be simple, we may need to ability to specialize for ย some use-cases and, we want to maximize our ability to build the Unity Game Object pooling on top of the POCO pooling. In addition, we may want to add a variety of more advanced features as add-ons, rather than via derived classes, so we need to provide opportunities for future code to make observations of pool operations. Getting this correct can be tricky as we canโt know all the possible things we might want to do in the future, but at the same time we need to resist the urge to increase the complexity of the components in anticipation of a future feature that may never happen.
The components need to be effective and adaptable to a large number of use cases. We do not want to be limited/constrained to only a few ways of using the ย components. As an example, we want to avoid having our object pool be a singleton as this pattern results in an extremely limiting usage model. As another example, we do not want to be restricted to having a single object pool for the same type. For example, we might want two or more pools for StringBuilder instances where we group instances by capacity.
Unity generally only allows access to Unity game objects and components on the main thread, so there is little or no need for concurrency for object pooling of game objects. However, with every release the Unity team works to increase the overall parallelization and distribution of work across all available cores. This means that in the future the we will be able to run more of our code off the main thread and that will require us to write code that can manage concurrency. In addition, we already use a lot of background threads for processing network requests, large data sets, etc. It would be nice if we could have a simple mechanism that gave us concurrency without the overhead of acquiring and releasing locks. Strictly speaking, concurrency is not required because our object pooling for Unity game objects does not require it, but it would be really, really nice to have.
The implementations for Unity object pooling of game objects and the .NET POCO object pooling are not, and cannot be the same. That doesn't mean that we don't want their designs and implementations to look and feel as similar as possible; we do. We also wouldn't mind re-using as much code from the POCO implementation as is possible in the Unity object pooling.