Async 1.8.0
AsyncStateMachine.h
Go to the documentation of this file.
1
31#ifndef ASYNC_STATE_MACHINE_INCLUDED
32#define ASYNC_STATE_MACHINE_INCLUDED
33
34
35/****************************************************************************
36 *
37 * System Includes
38 *
39 ****************************************************************************/
40
41#include <typeinfo>
42#include <cassert>
43
44
45/****************************************************************************
46 *
47 * Project Includes
48 *
49 ****************************************************************************/
50
51#include <AsyncTimer.h>
52#include <AsyncAtTimer.h>
53
54
55/****************************************************************************
56 *
57 * Local Includes
58 *
59 ****************************************************************************/
60
61
62
63/****************************************************************************
64 *
65 * Forward declarations
66 *
67 ****************************************************************************/
68
69
70
71/****************************************************************************
72 *
73 * Namespace
74 *
75 ****************************************************************************/
76
77namespace Async
78{
79
80
81/****************************************************************************
82 *
83 * Forward declarations of classes inside of the declared namespace
84 *
85 ****************************************************************************/
86
87template <class ContextT, class TopStateT> class StateTopBase;
88
89
90/****************************************************************************
91 *
92 * Defines & typedefs
93 *
94 ****************************************************************************/
95
96
97
98/****************************************************************************
99 *
100 * Exported Global Variables
101 *
102 ****************************************************************************/
103
104
105
106/****************************************************************************
107 *
108 * Class definitions
109 *
110 ****************************************************************************/
111
155template <class ContextT, class StateTopT>
157{
158 public:
163
168 StateMachine(ContextT* ctx) : m_ctx(ctx)
169 {
170 m_timer.expired.connect(
171 [&](Timer*)
172 {
173 assert(m_state != nullptr);
174 clearTimeout();
175 static_cast<StateTopBaseT*>(m_state)->timeoutEvent();
176 });
177 m_at_timer.expired.connect(
178 [&](AtTimer*)
179 {
180 assert(m_state != nullptr);
182 static_cast<StateTopBaseT*>(m_state)->timeoutAtEvent();
183 });
184 }
185
189 StateMachine(const StateMachine&) = delete;
190
195
200 {
201 delete m_state;
202 m_state = nullptr;
203 }
204
212 void start(void)
213 {
215 }
216
221 ContextT& ctx(void)
222 {
223 return *m_ctx;
224 }
225
240 template <class NewStateT>
241 void setState(NewStateT* state=new NewStateT)
242 {
243 state->setMachine(this);
244 StateTopT* old_state = m_state;
245 if ((old_state != nullptr) && (typeid(NewStateT) == old_state->typeId()))
246 {
247 delete state;
248 return;
249 }
250 static_cast<StateTopBaseT*>(state)->initHandler();
251 if (old_state != m_state)
252 {
253 delete state;
254 return;
255 }
256#ifdef ASYNC_STATE_MACHINE_DEBUG
257 std::cout << "### StateMachine: ";
258 std::cout << (old_state != nullptr ? old_state->name() : "NULL");
259 std::cout << " -> " << state->name() << std::endl;
260#endif
261 if (old_state != nullptr)
262 {
263 static_cast<StateTopBaseT*>(old_state)->exitHandler(state);
264 }
265 m_state = state;
266 static_cast<StateTopBaseT*>(m_state)->entryHandler(old_state);
267 delete old_state;
268 }
269
280 template <class T>
281 bool isActive(void) const
282 {
283 return typeid(T) == m_state->typeId();
284 }
285
290 StateTopT& state(void) { return *m_state; }
291
300 void setTimeout(int timeout_ms)
301 {
302#ifdef ASYNC_STATE_MACHINE_DEBUG
303 std::cout << "### StateMachine: setTimeout(" << timeout_ms << ")"
304 << std::endl;
305#endif
306 m_timer.setTimeout(timeout_ms);
307 m_timer.setEnable(true);
308 }
309
319 void setTimeoutAt(struct tm& tm, int expire_offset=0)
320 {
321 m_at_timer.setTimeout(tm);
322 m_at_timer.setExpireOffset(expire_offset);
323 m_at_timer.start();
324 }
325
332 void clearTimeout(void)
333 {
334#ifdef ASYNC_STATE_MACHINE_DEBUG
335 std::cout << "### StateMachine: clearTimeout()" << std::endl;
336#endif
337 m_timer.setEnable(false);
338 }
339
346 void clearTimeoutAt(void)
347 {
348 m_at_timer.stop();
349 }
350
351 private:
352 StateTopT* m_state = nullptr;
353 ContextT* m_ctx = nullptr;
354 Timer m_timer = -1;
355 AtTimer m_at_timer;
356}; /* StateMachine */
357
358
380template <class ParentT, class T>
381class StateBase : public ParentT
382{
383 public:
388 virtual const std::type_info& typeId(void) const override
389 {
390 return typeid(T);
391 }
392
393 virtual const char* name(void) const { return T::NAME; }
394
395 protected:
399 virtual void initHandler(void) override
400 {
401 dynamic_cast<T*>(this)->init();
402 }
403
408 virtual void entryHandler(typename ParentT::StateT* from) override
409 {
410 if (dynamic_cast<T*>(from) == nullptr)
411 {
412 ParentT::entryHandler(from);
413 dynamic_cast<T*>(this)->entry();
414 }
415 }
416
421 virtual void exitHandler(typename ParentT::StateT* to) override
422 {
423 if (dynamic_cast<T*>(to) == nullptr)
424 {
425 dynamic_cast<T*>(this)->exit();
426 ParentT::exitHandler(to);
427 }
428 }
429
440 void init(void) {}
441
453 void entry(void) {}
454
466 void exit(void) {}
467
479 virtual void timeoutEvent(void) override
480 {
481 assert(!"Async::StateBase: Unhandled timeoutEvent");
482 }
483
484 virtual void timeoutAtEvent(void) override
485 {
486 assert(!"Async::StateBase: Unhandled timeoutAtEvent");
487 }
488
489}; /* StateBase */
490
491
512template <class ContextT, class TopStateT>
514{
515 public:
520
524 using StateT = TopStateT;
525
530
534 virtual ~StateTopBase(void) {}
535
540 ContextT& ctx(void) { return m_sm->ctx(); }
541
542 protected:
548 template <class NewStateT>
549 void setState(void) { m_sm->setState(new NewStateT); }
550
559 void setTimeout(int timeout_ms) { m_sm->setTimeout(timeout_ms); }
560
570 void setTimeoutAt(struct tm& tm, int expire_offset=0)
571 {
572 m_sm->setTimeoutAt(tm, expire_offset);
573 }
574
581 void clearTimeout(void) { m_sm->clearTimeout(); }
582
589 void clearTimeoutAt(void) { m_sm->clearTimeoutAt(); }
590
594 virtual const std::type_info& typeId(void) const = 0;
595
599 virtual void initHandler(void) = 0;
600
605 virtual void entryHandler(StateT* from) {}
606
611 virtual void exitHandler(StateT* to) {}
612
624 virtual void timeoutEvent(void) = 0;
625
637 virtual void timeoutAtEvent(void) = 0;
638
639 private:
640 StateMachineT* m_sm;
641
642 void setMachine(StateMachineT* sm) { m_sm = sm; }
643
644 friend StateMachineT;
645}; /* StateTopBase */
646
647
648
649} /* namespace Async */
650
651#endif /* ASYNC_STATE_MACHINE_INCLUDED */
652
653/*
654 * This file has not been truncated
655 */
A timer that times out at a specified absolute time.
Contains a single shot or periodic timer that emits a signal on timeout.
A timer that times out at a specified absolute time.
sigc::signal< void, AtTimer * > expired
A signal that is emitted when the timer expires.
bool start(void)
Start the timer.
void setExpireOffset(int offset_ms)
Set the expire offset.
void stop(void)
Stop the timer.
bool setTimeout(time_t t)
Set the timeout time.
Implements a hierarchial state machine.
virtual void exitHandler(typename ParentT::StateT *to) override
Handle calling the exit function on state transitions.
virtual const char * name(void) const
virtual void timeoutEvent(void) override
An event function that will be called when a timeout occurs.
virtual void initHandler(void) override
Handle calling the init function on state transitions.
virtual void timeoutAtEvent(void) override
virtual void entryHandler(typename ParentT::StateT *from) override
Handle calling the entry function on state transitions.
virtual const std::type_info & typeId(void) const override
Get the typeid for this state.
void entry(void)
Called when a state is entered.
void init(void)
Called before a transition from one state to another.
Implements a hierarchial state machine.
void setTimeoutAt(struct tm &tm, int expire_offset=0)
Set a timeout after which the timeoutAtEvent is issued.
void setState(NewStateT *state=new NewStateT)
Switch to the given state.
void clearTimeoutAt(void)
Clear a pending absolute time timeout.
void clearTimeout(void)
Clear a pending timeout.
void start(void)
Start the state machine.
~StateMachine(void)
Destructor.
ContextT & ctx(void)
Get the context object.
StateTopT & state(void)
Get the active state.
bool isActive(void) const
Check if the given state is the active one.
StateMachine(ContextT *ctx)
Constructor.
StateMachine & operator=(const StateMachine &)=delete
Disallow copy assignment.
StateMachine(const StateMachine &)=delete
Disallow copy construction.
void setTimeout(int timeout_ms)
Set a timeout after which the timeoutEvent is issued.
The base class for the top state of a state machine.
void setTimeoutAt(struct tm &tm, int expire_offset=0)
Set a timeout after which the timeoutAtEvent is issued.
virtual void entryHandler(StateT *from)
Run all entry handlers in the state hierarchy, top to bottom.
virtual void exitHandler(StateT *to)
Run all exit handlers in the state hierarchy, bottom to top.
TopStateT StateT
A type alias to access the top state type.
virtual void timeoutAtEvent(void)=0
Event function called when an absolute time timeout occurs.
void setTimeout(int timeout_ms)
Set a timeout after which the timeoutEvent is issued.
virtual void timeoutEvent(void)=0
An event function that will be called when a timeout occurs.
StateMachine< ContextT, StateT > StateMachineT
A type alias to simplify usage of the state machine type.
virtual const std::type_info & typeId(void) const =0
Get the typeid for this state.
ContextT & ctx(void)
Get the context object.
virtual ~StateTopBase(void)
Destructor.
void setState(void)
Transition to the given state.
void clearTimeoutAt(void)
Clear a pending absolute time timeout.
virtual void initHandler(void)=0
Run the init functon in a state.
void clearTimeout(void)
Clear a pending timeout.
A class that produces timer events.
Definition AsyncTimer.h:117
void setTimeout(int timeout_ms)
Set (change) the timeout value.
void setEnable(bool do_enable)
Enable or disable the timer.
sigc::signal< void, Timer * > expired
A signal that is emitted when the timer expires.
Definition AsyncTimer.h:210
Namespace for the asynchronous programming classes.