28 # pragma GCC diagnostic ignored "-Wmissing-braces"
30 # if __cplusplus >= 201402L
31 # define deprecated14(msg) [[deprecated(msg)]]
33 # define deprecated14(msg)
52 template <
typename Fsm>
65 template <
typename FsmInput,
typename FsmInput::Input i,
typename Fsm>
81 template <
typename FsmInput,
typename FsmInput::Input i,
typename Fsm>
91 template <
typename Fsm>
104 template <time_t s,
typename Fsm>
108 return timeout_<Fsm>(fsm, timeout);
115 template <
unsigned int ms,
typename Fsm>
119 return timeout_<Fsm>(fsm, timeout);
126 template <u
int64_t us,
typename Fsm>
130 return timeout_<Fsm>(fsm, timeout);
137 template <
typename Fsm>
151 template <
typename Fsm>
174 template <
typename Fsm>
181 : m_function(function)
192 return m_function(fsm);
209 template <
typename Fsm>
223 template <
typename Fsm>
231 # if GCC_VERSION >= 49000L
232 __attribute__((returns_nonnull))
234 __attribute__((warn_unused_result))
Fsm*
237 return new Fsm(*
this);
243 return m_description;
259 if(!p->
guard.valid())
264 while((p++)->guard.valid())
271 if(!p->
guard.valid())
276 while((p++)->guard.valid()) {
287 mutable bool m_compiled;
303 template <
typename State_,
typename Input_ =
int,
typename FsmImpl_ =
void>
332 # if __cplusplus >= 201103L && !defined(DOXYGEN)
333 static_assert(std::is_base_of<Fsm, FsmImpl>::value,
"");
348 switch(m_evalState) {
350 return m_state->
state;
372 switch(m_evalState) {
375 return m_stateNext->
state;
388 switch(m_evalState) {
523 m_inputs.push_back(i);
529 for(
size_t j = 0; j < m_inputs.size(); j++)
530 if(m_inputs[j] == i) {
531 m_inputs[j] = m_inputs.back();
545 # if __cplusplus >= 201103L
546 if(m_inputs.capacity() > capacity * 2U) {
548 m_inputs.shrink_to_fit();
552 m_inputs.reserve(capacity);
557 for(
size_t j = 0; j < m_inputs.size(); j++)
565 bool didCallback =
false;
568 switch(m_evalState) {
591 while((wait = evalOnce()).hasPassed())
593 if(alwaysDoCallback && !didCallback)
611 if(!m_state->
guard.valid()) {
628 }
while(m_state->
guard.valid());
644 TimeInterval evalOnce()
648 while(p->guard.valid()) {
649 TimeInterval ti((p++)->
guard(
static_cast<FsmImpl&
>(*
this)));
651 setState(p->stateAddr);
655 }
else if(ti < wait) {
667 if(nextState == m_state)
673 m_stateNext = nextState;
725 typename State_,
typename CallbackArg_ = void,
typename Input_ = int,
726 typename FsmImpl_ =
void>
730 typename choose_type<
731 FsmImpl_, FsmCallback<State_, CallbackArg_, Input_, void> >::type> {
743 char const*
name =
"FSM")
753 char const*
name =
"FSM")
763 return m_callbackArg;
772 this->
entry() ?
" (entry)" : this->
exit() ?
" (exit)" :
"");
773 m_callback(*
this, m_callbackArg);
782 template <
typename State_,
typename Input_,
typename FsmImpl_>
786 typename choose_type<
787 FsmImpl_, FsmCallback<State_, void, Input_, void> >::type> {
797 char const*
name =
"FSM")
805 char const*
name =
"FSM")
818 this->
entry() ?
" (entry)" : this->
exit() ?
" (exit)" :
"");
CallbackArg callbackArg() const
void(* Callback)(FsmCallback &, CallbackArg)
FsmCallback(typename base::Compiler const &compiler, Callback callback, CallbackArg callbackArg, char const *name="FSM")
FsmCallback(typename base::Description description, Callback callback, CallbackArg callbackArg, char const *name="FSM")
Fsm< State_, Input_, FsmImpl > base
virtual void callback() override
This function is called when the FSM has to execute the code belonging by the current state.
choose_type< FsmImpl_, FsmCallback< State_, CallbackArg_, Input_, void > >::type FsmImpl
A compiler to turn an zth::FsmDescription into something that can be used by zth::Fsm.
FsmDescription< Fsm > const * description() const
constexpr FsmCompiler(FsmDescription< Fsm > *description)
A guard is evaluated, and when true, the corresponding transition is taken.
constexpr bool valid() const
TimeInterval(* Function)(Fsm &fsm)
TimeInterval operator()(Fsm &fsm) const
constexpr FsmGuard(Function function)
bool lockstep() const
Check if lockstep mode is enabled.
Timestamp const & t() const
bool guardStep()
Check if a step was requested while paused in lockstep mode.
void step()
Allow the Fsm to proceed one step, if in lockstep mode.
virtual void callback()=0
This function is called when the FSM has to execute the code belonging by the current state.
Fsm(Compiler const &compiler, char const *name="FSM")
FsmDescription< FsmImpl > * m_description
State const & next() const
FsmDescription< FsmImpl > const * m_compiledDescription
FsmDescription< FsmImpl > const * StateAddr
choose_type< FsmImpl_, Fsm >::type FsmImpl
void setInputsCapacity(size_t capacity)
FsmDescription< FsmImpl > Description[]
Compiler const * m_compiler
Fsm(Description description, char const *name="FSM")
bool hasInput(Input i) const
bool guardLock()
Check if a lock was requested while running in lockstep mode.
void setLockstep(bool enable)
Enable/disable lockstep mode.
FsmCompiler< FsmImpl > Compiler
TimeInterval eval(bool alwaysDoCallback=false)
State const & state() const
void setInterval(TimeInterval const &interval, Timestamp const &now=Timestamp::now()) noexcept
TimeInterval const & interval() const noexcept
void signal(bool queue=true, bool queueEveryTime=false) noexcept
Convenient wrapper around struct timespec that contains a time interval.
constexpr bool isInfinite() const noexcept
constexpr bool hasPassed() const noexcept
constexpr static TimeInterval infinity() noexcept
constexpr static TimeInterval null() noexcept
Convenient wrapper around struct timespec that contains an absolute timestamp.
friend cow_string str(UniqueIDBase const &)
Keeps track of a process-wide unique ID within the type T.
virtual char const * id_str() const override
string const & name() const noexcept
char const * c_str() const
#define deprecated14(msg)
Fiber & currentFiber() noexcept
Return the currently executing fiber.
constexpr auto guard(T &&g, char const *name=nullptr)
Create a guard from a function.
TimeInterval timeout_s(Fsm &fsm)
A guard that is true when the Fsm stayed for the given time in this state.
TimeInterval lock(Fsm &fsm)
A wrapper for zth::Fsm::guardLock().
TimeInterval always(Fsm &fsm)
A guard that is always true.
TimeInterval step(Fsm &fsm)
A wrapper for zth::Fsm::guardStep().
TimeInterval peek(Fsm &fsm)
A guard that is true when the given input has been set.
TimeInterval timeout_us(Fsm &fsm)
A guard that is true when the Fsm stayed for the given time in this state.
@ end
End-of-guard-list marker.
TimeInterval input(Fsm &fsm)
A guard that is true when the given input has been set.
TimeInterval timeout_ms(Fsm &fsm)
A guard that is true when the Fsm stayed for the given time in this state.
#define zth_dbg(group, fmt, a...)
Debug printf()-like function.
#define ZTH_CLASS_NEW_DELETE(T)
Define new/delete operators for a class, which are allocator-aware.
TimeInterval timeout_(Fsm &fsm, TimeInterval const &timeout)
cow_string str(T value)
Returns an zth::string representation of the given value.
void unscheduleTask(TimedWaitable &w)
void scheduleTask(TimedWaitable &w)
The description of a Fsm.
FsmDescription const * stateAddr
std::map type using Config::Allocator::type.
std::vector type using Config::Allocator::type.
#define zth_assert(expr)
assert(), but better integrated in Zth.
#define likely(expr)
Marks the given expression to likely be evaluated to true.