Wiki

Clone wiki

hydro / Flyweight

The object pool

In a mobile environment, garbage collection is an heavyweight task that can slow down the whole application when too objects are created and destructed during a short timelapse. The flyweight pattern consists in an object pool that contains a fixed (or adaptable) amount of instances of a specific class, which are reused by the client code. Every time an istance is required, it is requested to the object pool, and when the client code is done with it, the instance is released and returns to the object pool.

The class Flyweight.ObjectPool implements the flyweight pattern. It generates a fixed amount of copies of a given prototype object. Copies can be requested already initialized by passing the initialization action to the Request method. When an object is not used anymore, the client code must release it to the original pool using the Release method. When all the pool objects are requested, requesting one more causes an exception to be thrown. The method TryRequest, instead of throwing an exception, returns null if no instance is available.

The shared objects are added a Flyweight.SharedObject component, which is used to mark a shared object with its owner pool. It also contains a method ReleaseThis, which calls the Release method on the relative owner object pool.

Usage example

The following script must have set an external object pool, which can be done through the Unity inspector.

#!c#

public GameObject objectPool;
ObjectPool objects;

void Start() {
    objects = objectPool.GetComponent<ObjectPool>();
}

GameObject InstantiateObject() {
    ...
    var got = objects.TryRequest(obj => Initialize(obj));    // null if empty pool
    if (got == null) { Debug.Log("Currently running out of objects"); }
    return got;
}

void Initialize(GameObject obj) {
    // initialize the shared object as it were created with GameObject.Instantiate(prototype)
}

void CodeUsingSharedObjects(GameObject shared) {
    if (NotNeededAnymore(shared)) { shared.GetComponent<SharedObject>().ReleaseThis(); }
}

Updated