MODULE: ObjectPool (keep record of reusable objects)

Started by Crimson Wizard, Fri 19/02/2021 14:20:23

Previous topic - Next topic

Crimson Wizard

DOWNLOAD ObjectPool 1.0.1 MODULE

Latest source code may be found here
Git cloning address: https://github.com/ivan-mogilko/ags-script-modules.git

Requires AGS 3.4.0 or higher.



If you ever found yourself in a need to reuse a number of game objects you know that you must track which of these are currently in use and which are not. This basic module does that for you.

ObjectPool helps to keep track of a list of reusable objects. It does not matter what kind of objects are these so long as they have numeric IDs. It remembers which IDs are free and which are in use. It gives you next free ID by demand, and lets you mark used ID as a free one when you are no longer using it.

For an example of a use-case imagine making an arcade scene in AGS. Because AGS does not support creating objects in script you must create them in the editor and then reuse multiple times. Let's say that you've created 10 Characters to use as killable enemies and they have IDs from 4 to 14.

You put following code in the global script (it could be room script too, except you would probably use "room enter event" to set things up).
Code: ags

ObjectPool EnemyPool;

function game_start()
{
    EnemyPool.AddObjects(4, 14); // register character IDs from 4 to 14
}


Now, when you need a new enemy you ask ObjectPool what is the next free ID like this:
Code: ags

function SpawnEnemy()
{
    int enemy_id = EnemyPool.Acquire();
    if (enemy_id < 0) {
        Display("Whoops! no more dummy characters for enemies!");
        return;
    }
    Character* enemy = character[enemy_id];
    // set up character as necessary...
}


And when you no longer need this character, you mark it as unused like this:
Code: ags

function KillEnemy(Character* enemy)
{
    EnemyPool.Release(enemy.ID);
    // trigger some visual effects, hide character, and so on...
}


That's it.


ObjectPool API reference

Code: ags

    /// Adds a range of IDs into the list. You can keep adding more later and all the previous
    /// ones will be kept unless you call RemoveObjects or RemoveAll.
    void ObjectPool.AddObjects(int from, int to);
    /// Removes a range of IDs from the list.
    void ObjectPool.RemoveObjects(int from, int to);
    /// Removes all IDs.
    void ObjectPool.RemoveAll();

    /// Gives next free ID and marks it as "used". Returns -1 if no more free IDs are available.
    int ObjectPool.Acquire();
    /// Marks given ID as "free".
    void ObjectPool.Release(int id);
    /// Marks all the known IDs as "free".
    void ObjectPool.ReleaseAll();
    
    /// Gets number of acquired ("used") IDs
    int ObjectPool.GetAcquiredNum();
    /// Gets number of available free IDs
    int ObjectPool.GetFreeNum();
    /// Gets total number of registered IDs
    int ObjectPool.GetTotalNum();
    /// Gets pool capacity (may include empty slots!). This is for test purposes only.
    int ObjectPool.GetPoolSize();

eri0o

Just wanted to comment that there is a lot very smartly written in this module, the logic for acquiring and releasing in a deterministic way without for loops is not something I would have been able to think by myself. Loved the logic of tracking both the free and the in use, great stuff.

I have done the idea of a pool in my own stuff before and always did it very inefficiently and didn't notice  until I decided to check this module.

SMF spam blocked by CleanTalk