in Source/Shared/arcana/scheduling/state_machine.h [255:292]
static auto on(state_machine_driver& driver,
state_machine_state<ResultT>& state,
DispatcherT& dispatcher,
cancellation& cancel,
CallableT&& callable)
{
struct pending_data
{
ResultT data{};
};
auto node_data = std::make_shared<pending_data>();
ResultT* dataptr = &node_data->data;
using callable_traits = internal::callable_traits<CallableT, ResultT>;
static_assert(std::is_same_v<typename callable_traits::error_propagation_type, std::error_code>, "state machine only supports error_codes for now");
auto work = [ callable = std::forward<CallableT>(callable), dataptr ]() noexcept
{
return callable(*dataptr);
};
return driver.enter(state, cancel)
.then(dispatcher, cancel, std::move(work))
.then(inline_scheduler,
cancellation::none(),
[&, node_data = std::move(node_data) ](const typename callable_traits::expected_return_type& result) mutable noexcept {
ResultT data = std::move(node_data->data);
// remove ourselves as a cancellation listener, as we were
// only listening in order to avoid getting stuck on enter.
node_data.reset();
driver.exit(state, data);
return result;
});
}