ratchetfreak's plan sounds good and won't force you to change to much of your system. But if you want even more flexibility at the cost of having to alter your system a lot you might think about trying to write the GUI API as just generating a list of commands and then having one call at the end of the GUI that can execute everything.
In C++ the only problem with this is that the usual IMGUI API with the if will not work.
| if (do_button(button_parameters)){
do_button_result();
}
|
It won't work because the command you push onto the list won't be resolved until later, so it is impossible to know whether the button should return true or false. I made it work with a system of ids, so each GUI item gets a unique id, then whichever item is activated has it's id stored in an "activated" field that persists to the next frame and THEN the do_button call can return true.
However since you're working in Lua which has beautiful support for lambdas and closures you could instead have calls like:
| do_button(button_parameters, function(params_if_you_want)
-- do button results
end)
|
Then instead of waiting until the next frame, you can store the lambda as a part of the command in the command list, and when you resolve which item to activate you then call it's lambda. This gives you the advantage that you know all of the state changes caused by your GUI will come after the GUI has been fully executed this frame, which is a nice guarantee to have.