27# pragma GCC diagnostic ignored "-Wmissing-braces"
29# if __cplusplus >= 201402L
30# define deprecated14(msg) [[deprecated(msg)]]
32# define deprecated14(msg)
51template <
typename Fsm>
64template <
typename FsmInput,
typename FsmInput::Input i,
typename Fsm>
80template <
typename FsmInput,
typename FsmInput::Input i,
typename Fsm>
90template <
typename Fsm>
103template <time_t s,
typename Fsm>
107 return timeout_<Fsm>(fsm, timeout);
114template <
unsigned int ms,
typename Fsm>
118 return timeout_<Fsm>(fsm, timeout);
125template <u
int64_t us,
typename Fsm>
129 return timeout_<Fsm>(fsm, timeout);
136template <
typename Fsm>
150template <
typename Fsm>
173template <
typename Fsm>
180 : m_function(function)
191 return m_function(fsm);
208template <
typename Fsm>
222template <
typename Fsm>
230# if GCC_VERSION >= 49000L
231 __attribute__((returns_nonnull))
233 __attribute__((warn_unused_result))
Fsm*
236 return new Fsm(*
this);
242 return m_description;
258 if(!p->
guard.valid())
263 while((p++)->guard.valid())
270 if(!p->
guard.valid())
275 while((p++)->guard.valid()) {
286 mutable bool m_compiled;
302template <
typename State_,
typename Input_ =
int,
typename FsmImpl_ =
void>
331# if __cplusplus >= 201103L && !defined(DOXYGEN)
332 static_assert(std::is_base_of<Fsm, FsmImpl>::value,
"");
347 switch(m_evalState) {
349 return m_state->
state;
371 switch(m_evalState) {
374 return m_stateNext->
state;
387 switch(m_evalState) {
522 m_inputs.push_back(i);
528 for(
size_t j = 0; j < m_inputs.size(); j++)
529 if(m_inputs[j] == i) {
530 m_inputs[j] = m_inputs.back();
544# if __cplusplus >= 201103L
545 if(m_inputs.capacity() > capacity * 2U) {
547 m_inputs.shrink_to_fit();
551 m_inputs.reserve(capacity);
556 for(
size_t j = 0; j < m_inputs.size(); j++)
564 bool didCallback =
false;
567 switch(m_evalState) {
590 while((wait = evalOnce()).hasPassed())
592 if(alwaysDoCallback && !didCallback)
610 if(!m_state->
guard.valid()) {
627 }
while(m_state->
guard.valid());
643 TimeInterval evalOnce()
647 while(p->guard.valid()) {
648 TimeInterval ti((p++)->guard(
static_cast<FsmImpl&
>(*
this)));
650 setState(p->stateAddr);
654 }
else if(ti < wait) {
666 if(nextState == m_state)
672 m_stateNext = nextState;
724 typename State_,
typename CallbackArg_ = void,
typename Input_ = int,
725 typename FsmImpl_ =
void>
729 typename choose_type<
730 FsmImpl_, FsmCallback<State_, CallbackArg_, Input_, void> >::type> {
746 , m_callbackArg(cbArg)
757 , m_callbackArg(cbArg)
764 return m_callbackArg;
773 this->
entry() ?
" (entry)"
774 : this->
exit() ?
" (exit)"
776 m_callback(*
this, m_callbackArg);
785template <
typename State_,
typename Input_,
typename FsmImpl_>
789 typename choose_type<
790 FsmImpl_, FsmCallback<State_, void, Input_, void> >::type> {
800 char const*
name =
"FSM")
808 char const*
name =
"FSM")
821 this->
entry() ?
" (entry)"
822 : this->
exit() ?
" (exit)"
CallbackArg callbackArg() const
void(* Callback)(FsmCallback &, CallbackArg)
FsmCallback(typename base::Compiler const &compiler, Callback const &cb, CallbackArg const &cbArg, char const *name="FSM")
FsmCallback(typename base::Description description, Callback const &cb, CallbackArg const &cbArg, char const *name="FSM")
choose_type< FsmImpl_, FsmCallback< State_, CallbackArg_, Input_, void > >::type FsmImpl
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.
virtual ~FsmCallback() override
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.
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.
State const & state() const
Fsm(Compiler const &compiler, char const *name="FSM")
FsmDescription< FsmImpl > * m_description
Timestamp const & t() const
FsmDescription< FsmImpl > const * m_compiledDescription
FsmDescription< FsmImpl > const * StateAddr
void setInputsCapacity(size_t capacity)
FsmDescription< FsmImpl > Description[]
choose_type< FsmImpl_, Fsm >::type FsmImpl
Compiler const * m_compiler
Fsm(Description description, char const *name="FSM")
State const & next() const
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)
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.
static constexpr TimeInterval null() noexcept
constexpr bool isInfinite() const noexcept
static constexpr TimeInterval infinity() noexcept
constexpr bool hasPassed() const 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.
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< T, typename Config::Allocator< T >::type > type
#define zth_assert(expr)
assert(), but better integrated in Zth.
#define likely(expr)
Marks the given expression to likely be evaluated to true.