morph 0.1.0
Asynchronous bridge between GUI thread and business models
Loading...
Searching...
No Matches
morph::flows::FlowSession< Model, Steps > Class Template Reference

Sequences an ordered list of registered actions (Steps...) as one multi-step flow sharing captured values across steps. More...

#include <flows.hpp>

Public Member Functions

 FlowSession (::morph::bridge::BridgeHandler< Model > &handler, std::function< void(std::exception_ptr)> onError=nullptr)
 Constructs a flow over handler, starting at step 0.
 ~FlowSession ()
 Stops every callback this session installed from being delivered.
 FlowSession (const FlowSession &)=delete
FlowSession & operator= (const FlowSession &)=delete
 FlowSession (FlowSession &&)=delete
FlowSession & operator= (FlowSession &&)=delete
template<auto FieldPtr>
void set (typename ::morph::bridge::detail::MemberPointerTraits< decltype(FieldPtr)>::ValueType value)
 Sets one field of the current step's draft and dispatches the step as soon as its ActionValidator reports the draft ready.
bool advance ()
 Moves to the next step, if the current step has already produced a successful result (a not-ready step does not advance).
bool back ()
 Returns to the previous step. Its draft — this session's own std::get<A>(_drafts) slot, the only draft in play — was never reset, so its entered values are intact.
bool finished () const noexcept
 Whether the flow has advanced past the last step.
bool ready () const noexcept
 Whether the current step already has a captured, successful result.
std::size_t currentIndex () const noexcept
 The current 0-based step position.
std::string_view currentActionType () const noexcept
 The registered type-id of the current step's action.
std::optional< std::string > resolved (std::string_view path) const
 Looks up a value captured from an earlier step's submitted draft or result.

Static Public Member Functions

static constexpr std::size_t stepCount () noexcept
 The number of steps in this flow.

Detailed Description

template<typename Model, typename... Steps>
class morph::flows::FlowSession< Model, Steps >

Sequences an ordered list of registered actions (Steps...) as one multi-step flow sharing captured values across steps.

Each step is fired through the handler's ordinary one-shot dispatch (BridgeHandler::execute<A>() → Completion<R>, bridge.hpp) — a FlowSession contributes only sequencing (advance/back), the per-step drafts and their readiness gate, and a resolved-values map callers use to prefill a later step from an earlier one's submitted fields or result. The handler holds no draft on a flow's behalf: nothing here goes through handler-side draft machinery.

Steps... must be pairwise distinct action types: this session's drafts live in a std::tuple<Steps...> addressed by type (std::get<A>(_drafts)), and std::get<T> is ill-formed when T occurs more than once — which is what the AllDistinct<Steps...> assert below enforces.

Template Parameters
ModelConcrete model type owning the BridgeHandler this flow dispatches through.
StepsOrdered, pairwise-distinct action types (the flow's steps).

Definition at line 153 of file flows.hpp.

Constructor & Destructor Documentation

◆ FlowSession()

template<typename Model, typename... Steps>
morph::flows::FlowSession< Model, Steps >::FlowSession ( ::morph::bridge::BridgeHandler< Model > & handler,
std::function< void(std::exception_ptr)> onError = nullptr )
inlineexplicit

Constructs a flow over handler, starting at step 0.

Parameters
handlerHandler the flow dispatches every step through. Must outlive this FlowSession. The session belongs to the handler's owner: it is built, used and destroyed there, and the handler's guiExec delivers its continuations there.
onErrorOptional callback invoked when the current step's fire fails (e.g. BackendChangedError mid-flight). When absent, the error is logged via morph::log::logError, which is how BridgeHandler itself reports a failure no caller is holding a Completion for (bridge.hpp). A handler offers no error callback to inherit a default from: subscribe<R> is notified of results only, and an execute() failure reaches the caller through the Completion it returned. Stored and invoked for this session's whole lifetime, so anything the callable refers to must outlive the session.

Definition at line 176 of file flows.hpp.

◆ ~FlowSession()

template<typename Model, typename... Steps>
morph::flows::FlowSession< Model, Steps >::~FlowSession ( )
inline

Stops every callback this session installed from being delivered.

There is nothing to detach. A step's callbacks are .then/.onError continuations on the Completion that BridgeHandler::execute<A>() returned — already owned by the in-flight dispatch, not held in a map this session could remove itself from, and possibly running on another thread the moment this destructor starts. _callbacks gates every installed callback on a token the callback checks before touching this.

The session is destroyed on the handler's owner, where the step's continuations are delivered, so check-then-run is atomic: a callback still in flight is refused instead of touching a destroyed object.

requestStop() is called explicitly rather than left to the member's own destruction, even though _callbacks is declared last: members are destroyed only after the destructor body, so a body that grew a call pumping an event loop would otherwise deliver into a half-dead session. This is the "teardown that pumps" escape hatch docs/spec/core/callback_scope.md documents; the body here does not do that today, but stopping first keeps the destructor correct if one is added.

Definition at line 204 of file flows.hpp.

Member Function Documentation

◆ set()

template<typename Model, typename... Steps>
template<auto FieldPtr>
void morph::flows::FlowSession< Model, Steps >::set ( typename ::morph::bridge::detail::MemberPointerTraits< decltype(FieldPtr)>::ValueType value)
inline

Sets one field of the current step's draft and dispatches the step as soon as its ActionValidator reports the draft ready.

The draft is this session's own (std::get<A>(_drafts)), the readiness check is made here, and a ready draft is fired by this session's fireStep<A> through BridgeHandler::execute<A>(). The handler keeps no draft of its own, so there is nothing to forward to.

No in-flight coalescing
Every set<> that leaves the draft ready dispatches, including one made while an earlier dispatch is still in flight. Keystroke-rate calls on an already-complete draft therefore produce one request each, and their results arrive in whatever order the backend answers them — the last reply to land wins, which need not be the last call made. An earlier handler-side draft did collapse patches arriving during a flight; nothing does now, here or on the standalone-form path. A caller that wants one request per pause throttles or debounces on its own side.
Template Parameters
FieldPtrPointer-to-data-member of the current step's action struct.
Parameters
valueNew value for the field.
Exceptions
std::logic_errorif FieldPtr's action is not the current step.

Definition at line 237 of file flows.hpp.

◆ advance()

template<typename Model, typename... Steps>
bool morph::flows::FlowSession< Model, Steps >::advance ( )
inline

Moves to the next step, if the current step has already produced a successful result (a not-ready step does not advance).

Returns
true if the flow advanced, false if the current step is not ready or the flow is already finished().

Definition at line 263 of file flows.hpp.

◆ back()

template<typename Model, typename... Steps>
bool morph::flows::FlowSession< Model, Steps >::back ( )
inline

Returns to the previous step. Its draft — this session's own std::get<A>(_drafts) slot, the only draft in play — was never reset, so its entered values are intact.

Returns
true if the flow moved back, false if already at step 0.

Definition at line 285 of file flows.hpp.

◆ finished()

template<typename Model, typename... Steps>
bool morph::flows::FlowSession< Model, Steps >::finished ( ) const
inlinenodiscardnoexcept

Whether the flow has advanced past the last step.

Returns
true once advance() has been called successfully on the last step.

Definition at line 299 of file flows.hpp.

◆ ready()

template<typename Model, typename... Steps>
bool morph::flows::FlowSession< Model, Steps >::ready ( ) const
inlinenodiscardnoexcept

Whether the current step already has a captured, successful result.

Returns
true if advance() would move the flow forward right now.

Definition at line 303 of file flows.hpp.

◆ currentIndex()

template<typename Model, typename... Steps>
std::size_t morph::flows::FlowSession< Model, Steps >::currentIndex ( ) const
inlinenodiscardnoexcept

The current 0-based step position.

Returns
sizeof...(Steps) once finished().

Definition at line 310 of file flows.hpp.

◆ stepCount()

template<typename Model, typename... Steps>
constexpr std::size_t morph::flows::FlowSession< Model, Steps >::stepCount ( )
inlinestaticnodiscardconstexprnoexcept

The number of steps in this flow.

Returns
sizeof...(Steps).

Definition at line 314 of file flows.hpp.

◆ currentActionType()

template<typename Model, typename... Steps>
std::string_view morph::flows::FlowSession< Model, Steps >::currentActionType ( ) const
inlinenodiscardnoexcept

The registered type-id of the current step's action.

Returns
Empty when finished() (no current step).

Definition at line 318 of file flows.hpp.

◆ resolved()

template<typename Model, typename... Steps>
std::optional< std::string > morph::flows::FlowSession< Model, Steps >::resolved ( std::string_view path) const
inlinenodiscard

Looks up a value captured from an earlier step's submitted draft or result.

Parameters
path"<ActionTypeId>.<field>", matching a wizard step's declared Bind::path().
Returns
The field's JSON-encoded value, or std::nullopt if path was never captured (the step never fired, or never had that field).

Definition at line 331 of file flows.hpp.


The documentation for this class was generated from the following file: