Open pgaskin opened 3 years ago
This could be implemented by making void nm_menu_action_do(nm_menu_item_t *it, nm_argtransform_t argtransform, void *argtransform_data)
into void nm_menu_action_do_async(nm_menu_item_t *it, nm_argtransform_t argtransform, void *argtransform_data, struct {int cfgver; nm_menu_action_t *cur; nm_action_result_t *res} *async_state)
:
async_state
.
nm_menu_action_t
.async_state.cfgver
against the current config version. If it's different, log an error and return silently since the config pointers won't be valid anymore.async_state.res
.
async_state.res
and calls nm_action_do_async
again, free it, then return.async_state.cur.next
(we could call nm_menu_action_do_async
recursively, but is more efficient, easier to debug, and doesn't have a risk of stack overflows):
async_state.cur
to the action.async_state.res
to the result.async_state.res
:
async_state.res
and calls nm_action_do_async
again, free it, then return.Actions results which do not use Qt signals are out of scope (since then we can't guarantee actions are running in the correct thread).
This should only require changes in nickelmenu.cc
; the actions themselves should remain the same. In addition, the code path would remain almost identical for chains which do not use async results, significantly reducing the likelihood and impact of regressions.
This would allow implementing asynchronous action results, e.g. confirmation dialogs (note that the current ok dialog result doesn't wait).
A few potential issues:
nm_menu_action_do
is implemented to not allocate memory between action result executions.Note that this does not include implementing async actions since that has more implications and would result in quite a bit more complexity (for execution, checking the current state, and handling abortions) and potentially confusing behaviour.