DelayedAction - Monika-After-Story/MonikaModDev GitHub Wiki

Summary

The DelayedAction framework is a framework that allows for Event-based actions (as well as custom actions) to be queued and executed later if a condition is true. This is NOT a replacement for Event conditional checking. This is more about running some code that is dependent on system-related variables or initial conditions.

Components

The DelayedAction framework consists of the following:

  • MASDelayedAction class
  • mas_delact store

MASDelayedAction

This class contains several properties, but the main ones are: (all of these are required in the constructor)

  • id - the unique ID for this DelayedAction
  • ev - the Event this DelayedAction is associated with
  • conditional - eval'd condition that controls when the DelayedAction is performed
  • action - either an EV_ACTION constant or a callable that performs the action
  • flowcheck - MAS_FC constant that controls when the conditional is checked

This class also contains a static method makeWithLabel which can create a DelayedAction instance using an eventlabel instead of the actual event. This assumes mas_getEV is available, so make sure to use the correct init level.

DelayedActions are meant to act as wrappers around common actions that allow them to be executed lazily, when conditional is met and at certain times during inittime or runtime or even multiple sessions later.

When a DelayedAction's conditional is met, the action is executed. If the action was successfully executed, then it is removed from the DelayedAction map and persistent delayed action list.

Actions that are callables should return True on success and False otherwise to signify action success to the framework. Callable actions are called with the Event object, keyword ev.

Flowcheck is designed to work using bitwise checking, so a DelayedAction can be checked in multiple places by bitwise or'ing the MAS_FC constants.

mas_delact

This store contains save/load functions for the DelayedAction Map as well as the MAP that relates DelayedAction IDs with constructor functions.

Setup

To setup a DelayedAction, you will need the following:

  1. Constructor function that can build a DelayedAction at init level 994.
  2. An Event to perform the DelayedAction on.

And to create:

  1. Create a constructor function to build the DelayedAction. This function should be prefixed with a single underscore and be built in the mas_delact store. This store will have access to the store import so you can retrieve all other variables from here. You should create this function at a init level before 994. This function should accept no parameters and return a MASDelayedAction object.
  2. Add that function to the mas_delact.MAP dict located in event-handler. Make sure that your ID is unique and is the same as the one you used in creation of the MASDelayedAction object. It is recommended to use a number for the ID.
  3. Call mas_addDelayedAction using your DelayedAction's ID when you need to queue a DelayedAction.

Execution

Here's how execution of DelayedAction's work:

  1. At init level 994, all DelayedAction IDs that were saved in persistent._mas_delayed_action_list are converted into DelayedAction instances and stored in mas_delayed_action_map. Note that this runtime variable is a dict while the persistent var is a list.
  2. At init level 995, all DelayedActions with a flowcheck containing MAS_FC_INIT are checked and executed if conditional passes.
  3. DelayedActions with flowcheck containing MAS_FC_START are checked during runtime in splash.
  4. DelayedActions with flowcheck containing MAS_FC_IDLE_ONCE are checked during runtime in ch30_preloop.
  5. DelayedActions with flowcheck containing MAS_FC_IDLE_ROUTINE are checked roughly once per minute in ch30_loop.
  6. DelayedActions with flowcheck containing MAS_FC_END are checked during runtime in quit.
  7. The IDs of DelayedActions that were not executed this session are saved in persistent._mas_delayed_action_list. NOTE: This list is always regenerated, not appended, on session end.

Additional:

All DelayedAction code is located in event-handler.

The first Event to use DelayedActions is the islands event. This was used to handle cases were images failed to decode, which meant the Event needed to remain locked until the images were successfully parsed.