Skip to content

Memory Callback Cache

MapleWheels edited this page Feb 5, 2023 · 2 revisions

In-Memory Callback Cache

The purpose of this cache is to make it easy to cache values and re-apply them at a later point in time. The intended purpose of this is to allow modders to change SerializableProperty values in Item and ItemComponent (which are permanent changes) and then revert them at the end of a round.

However, this module can be used as a generic callback cache or State Machine. The cache stores a WeakReference to the object so that garbage collection is not affected.

Example: Working with SerializableProperties

In this example, we're going to find all pumps on a Submarine, change their MaxFlow and then reset it back to default at the end of the round.

// Some class

Guid cacheInstanceId;

void Initialize()
{
    cacheInstanceId = MemoryCallbackCache.CreateInstance();
}

// Level.Loaded = true
void OnLevelLoaded()
{
    foreach (var item in Submarine.MainSub.GetItems(false))
    {
        if (item.GetComponent<Pump>() is { } pump)
        {
            // Store the old value
            MemoryCallbackCache.AddCallback(
                cacheInstanceId,
                pump,
                pump.MaxFlow,
                (pumpRef, storedVal) => // pumpRef = WeakReference<Pump>   
                {
                    if (pumpRef.Target is Pump p)
                    {
                        p.MaxFlow = storedVal;  // Restore the old value.
                    }
                });
            // Assign the new value you were intending to
            pump.MaxFlow = 1000f;
        }
    }
}

// Called before the level is saved to file.
void OnRoundEnd()
{
    // Invoke all of the saved cache callback functions
    MemoryCallbackCache.ExecuteAndRemoveAll(cacheInstanceId);
}