ResourceArena

A resource arena keeps track of resources in use, taking note of the time since the resource was last updated. Time is tracked in terms of "cycles". Resources are expected to be updated every cycle, or be freed. The time it takes to actually free resource can be adjusted.

The simplest way to understand the resource arena is by assuming all resources are freed every cycle:

const resourceID = arena.load(...);  // Resource loaded
arena.startCycle();  // Unloaded

In a practical scenario, resources will likely continue to be used across cycles. The load call will be repeated next cycle with the same resource. The arena will therefore *not* free resources immediately, but keep them alive in the background for long enough they can be reused for another load. This means that on the outside the resources appear freed, while they stay active until it can be confirmed they will not be reused.

The amount of cycles resources stay alive for can be adjusted by setting arena.resourceLifetime. The default is to preserve resources for one cycle (1). Forcing immediate frees like in the example above can be achieved by setting it to zero (0).

In Fluid, the resource arena is mostly used by I/O systems to manage resources that nodes will allocate. A cycle starts when the I/O system begins resizing:

ResourceArena!Image images;
override void resizeImpl(Vector2 space) {
    images.startCycle();
    super.resizeImpl(space);
}
override int load(DrawableImage image) {
    return images.load(image);
}

Members

Functions

activeResources
auto activeResources()

List every active resource in the arena. Omits expired resources.

allResources
auto allResources()

List every resource in the arena.

isActive
bool isActive(int index)

Check if resource at given index is active; A resource is active if it has been loaded during this cycle. An active resource can be fetched using opIndex.

isAlive
bool isAlive(int index)

Check if the resource is still loaded in the area.

load
int load(T resource)

Load a resource into the arena.

opIndex
inout(T) opIndex(int index)

Get a resource by its index.

reload
void reload(int index, T resource)

Reload a resource.

resourceCount
int resourceCount()
startCycle
auto startCycle(void delegate(int index, ref T resource) @(safe) moved)

Start a new cycle.

Variables

cycleNumber
int cycleNumber;

Number of the current cycle. Cycles are used to determine the lifetimes stored in the arena. This field is incremented every time a new cycle starts.

resourceLifetime
int resourceLifetime;

Number of cycles a resource stays alive for, beyond the cycle they were created during.

Examples

Check if a resource has been using during this cycle with isActive.

ResourceArena!string arena;
auto zero = arena.load("Zero");
auto one  = arena.load("One");
auto two  = 2;
assert( arena.isActive(zero));
assert( arena.isActive(one));
assert(!arena.isActive(two));

// Resources are marked inactive when a new cycle starts
arena.startCycle();
assert(!arena.isActive(zero));  // The resource isn't active now
assert( arena.isAlive(zero));   // but it remains loaded

// Loading a resource turns it active
arena.reload(zero, "Zero");
assert( arena.isActive(zero));
assert( arena.isAlive(zero));
assert(!arena.isActive(one));
assert( arena.isAlive(one));
assert(!arena.isActive(two));
assert(!arena.isAlive(two));

// "Two" hasn't been used on the last cycle, so it will be freed
arena.startCycle();
assert( arena.isAlive(zero));
assert(!arena.isAlive(one));
assert(!arena.isAlive(two));

Disable keeping objects alive by setting resourceLifetime to zero.

ResourceArena!int arena;
arena.resourceLifetime = 0;
arena.load(0);
assert( arena.isActive(0));
assert( arena.isAlive(0));

// 0 will be freed on a new cycle
arena.startCycle();
assert(!arena.isActive(0));
assert(!arena.isAlive(0));

Meta