-
-
Notifications
You must be signed in to change notification settings - Fork 12
Description
In original Swoosh, the Actions for an ActionList required the user to allocate on the heap while the ActionList deleted memory for the user. This is not intuitive. Generally the expectations are that, if a user allocates memory, then they must also delete their own memory too. Therefore a clearer API would use smart pointers and constructs to do this behind-the-scenes as Swoosh's mission statement is to let the user be free of any memory management and one of the reasons why segue effects are wrapped in meta template syntax.
Similarly, ActionList type and constructor arguments can be bound, but not allocated on the heap until needed. This is not a complete example, but for illustrative purposes describes what I mean:
auto checkHealth = [this]() {
return creatureHealth > 0;
};
sw::ActionListBuilder builder = {
sw::Concurrent<AttackAction>(3.0, &decalSpr),
sw::Blocking<WaitForInput>(Input::Key_Enter),
// args: query func, list if true, list if false
// both lists are intentionally std::nullopt for this example
sw::Conditional(checkCreatureHealth, std::nullopt, std::nullopt),
...
... };
while(actionList.empty() == false) {
sw::ActionRef currAction = actionList.top();
currAction.tick();
//Later, a conditional execution path changes the next actions
if(currAction.is<sw::Conditional>()) {
sw::ConditionalRef condition = currAction.as<sw::Conditional>();
if(condition.isTrue()) {
actionList.clear();
// Do something else
} else {
// The builder list at the top of this example defers construction
// until this moment - using the data to configure the necessary
// internals that would otherwise be tedious "plumbing".
actionList.insert(actionList.begin(), builder.buildList());
}
}The idea is that all memory management is safe and hidden away from the user. They should receive primitive-like handles which wrap the complex logic. Only when a direct call to buildList() should any of the "registered" action metadata allocate memory for those Actions.
It's debatable whether or not the ActionList itself needs to be a UDT type at all as it can be represented by std::stack or some other satisfactory data structure. Mutation of the list could occur in the underlining class of the sw::ActionRef itself.