Embedded Template Library 1.0
Loading...
Searching...
No Matches
state_chart.h
1/******************************************************************************
2The MIT License(MIT)
3
4Embedded Template Library.
5https://github.com/ETLCPP/etl
6https://www.etlcpp.com
7
8Copyright(c) 2018 John Wellbelove
9
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files(the "Software"), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions :
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26SOFTWARE.
27******************************************************************************/
28
29#ifndef ETL_STATE_CHART_INCLUDED
30#define ETL_STATE_CHART_INCLUDED
31
32#include "platform.h"
33#include "nullptr.h"
34#include "array.h"
35#include "array_view.h"
36#include "utility.h"
37
38#include <stdint.h>
39
40namespace etl
41{
42 //***************************************************************************
44 //***************************************************************************
45
46 namespace state_chart_traits
47 {
50
51 //*************************************************************************
53 //*************************************************************************
54 template <typename TObject, typename TParameter = void>
56 {
57 ETL_CONSTEXPR transition(const state_id_t current_state_id_,
58 event_id_t event_id_,
59 const state_id_t next_state_id_,
60 void (TObject::* const action_)(TParameter) = ETL_NULLPTR,
61 bool (TObject::* const guard_)() = ETL_NULLPTR)
62 : current_state_id(current_state_id_)
63 , event_id(event_id_)
64 , next_state_id(next_state_id_)
65 , action(action_)
66 , guard(guard_)
67 , from_any_state(false)
68 {
69 }
70
71 ETL_CONSTEXPR transition(event_id_t event_id_,
72 const state_id_t next_state_id_,
73 void (TObject::* const action_)(TParameter) = ETL_NULLPTR,
74 bool (TObject::* const guard_)() = ETL_NULLPTR)
75 : current_state_id(0)
76 , event_id(event_id_)
77 , next_state_id(next_state_id_)
78 , action(action_)
79 , guard(guard_)
80 , from_any_state(true)
81 {
82 }
83
84 const state_id_t current_state_id;
85 const event_id_t event_id;
86 const state_id_t next_state_id;
87 void (TObject::* const action)(TParameter);
88 bool (TObject::* const guard)();
89 const bool from_any_state;
90 };
91
92 //*************************************************************************
95 //*************************************************************************
96 template <typename TObject>
98 {
99 ETL_CONSTEXPR transition(const state_id_t current_state_id_,
100 event_id_t event_id_,
101 const state_id_t next_state_id_,
102 void (TObject::* const action_)() = ETL_NULLPTR,
103 bool (TObject::* const guard_)() = ETL_NULLPTR)
104 : current_state_id(current_state_id_)
105 , event_id(event_id_)
106 , next_state_id(next_state_id_)
107 , action(action_)
108 , guard(guard_)
109 , from_any_state(false)
110 {
111 }
112
113 ETL_CONSTEXPR transition(event_id_t event_id_,
114 const state_id_t next_state_id_,
115 void (TObject::* const action_)() = ETL_NULLPTR,
116 bool (TObject::* const guard_)() = ETL_NULLPTR)
117 : current_state_id(0)
118 , event_id(event_id_)
119 , next_state_id(next_state_id_)
120 , action(action_)
121 , guard(guard_)
122 , from_any_state(true)
123 {
124 }
125
126 const state_id_t current_state_id;
127 const event_id_t event_id;
128 const state_id_t next_state_id;
129 void (TObject::* const action)();
130 bool (TObject::* const guard)();
131 const bool from_any_state;
132 };
133
134 //*************************************************************************
136 //*************************************************************************
137 template <typename TObject>
138 struct state
139 {
140 ETL_CONSTEXPR state(const state_id_t state_id_,
141 void (TObject::* const on_entry_)() = ETL_NULLPTR,
142 void (TObject::* const on_exit_)() = ETL_NULLPTR)
143 : state_id(state_id_)
144 , on_entry(on_entry_)
145 , on_exit(on_exit_)
146 {
147 }
148
149 state_id_t state_id;
150 void (TObject::* const on_entry)();
151 void (TObject::* const on_exit)();
152 };
153 }
154
155 //***************************************************************************
157 //***************************************************************************
158 template <typename TParameter>
160 {
161 public:
162
163 typedef TParameter parameter_t;
164 typedef state_chart_traits::state_id_t state_id_t;
165 typedef state_chart_traits::event_id_t event_id_t;
166
169 {
170 }
171
172 virtual void start(bool on_entry_initial = true) = 0;
173 virtual void process_event(event_id_t, parameter_t) = 0;
174 virtual ~istate_chart() {}
175
176 //*************************************************************************
179 //*************************************************************************
181 {
182 return current_state_id;
183 }
184
185 protected:
186
188 };
189
190 //***************************************************************************
192 //***************************************************************************
193 template <>
195 {
196 public:
197
198 typedef void parameter_t;
199 typedef state_chart_traits::state_id_t state_id_t;
200 typedef state_chart_traits::event_id_t event_id_t;
201
204 {
205 }
206
207 virtual void process_event(event_id_t) = 0;
208 virtual void start(bool on_entry_initial = true) = 0;
209 virtual ~istate_chart() {}
210
211 //*************************************************************************
214 //*************************************************************************
216 {
217 return current_state_id;
218 }
219
220 protected:
221
223 };
224
225 //***************************************************************************
229 //***************************************************************************
230 template <typename TObject,
235 size_t State_Table_Size,
237 class state_chart_ct : public istate_chart<void>
238 {
239 public:
240
241 typedef void parameter_t;
242 typedef state_chart_traits::state_id_t state_id_t;
243 typedef state_chart_traits::event_id_t event_id_t;
246
247 //*************************************************************************
249 //*************************************************************************
250 ETL_CONSTEXPR state_chart_ct()
252 , started(false)
253 {
254 }
255
256 //*************************************************************************
259 //*************************************************************************
261 {
262 return TObject_Ref;
263 }
264
265 //*************************************************************************
268 //*************************************************************************
269 const TObject& get_object() const
270 {
271 return TObject_Ref;
272 }
273
274 //*************************************************************************
276 //*************************************************************************
277 virtual void start(bool on_entry_initial = true) ETL_OVERRIDE
278 {
279 if (!started)
280 {
282 {
283 // See if we have a state item for the initial state.
284 const state* s = find_state(this->current_state_id);
285
286 // If the initial state has an 'on_entry' then call it.
287 if ((s != (State_Table_Begin + State_Table_Size)) && (s->on_entry != ETL_NULLPTR))
288 {
289 (TObject_Ref.*(s->on_entry))();
290 }
291 }
292
293 started = true;
294 }
295 }
296
297 //*************************************************************************
302 //*************************************************************************
303 virtual void process_event(event_id_t event_id) ETL_OVERRIDE
304 {
305 if (started)
306 {
308
309 // Keep looping until we execute a transition or reach the end of the table.
311 {
312 // Scan the transition table from the latest position.
313 t = etl::find_if(t, (Transition_Table_Begin + Transition_Table_Size), is_transition(event_id, this->current_state_id));
314
315 // Found an entry?
317 {
318 // Shall we execute the transition?
319 if ((t->guard == ETL_NULLPTR) || ((TObject_Ref.*t->guard)()))
320 {
321 // Shall we execute the action?
322 if (t->action != ETL_NULLPTR)
323 {
324 (TObject_Ref.*t->action)();
325 }
326
327 // Changing state?
328 if (this->current_state_id != t->next_state_id)
329 {
330 const state* s;
331
332 // See if we have a state item for the current state.
333 s = find_state(this->current_state_id);
334
335 // If the current state has an 'on_exit' then call it.
336 if ((s != (State_Table_Begin + State_Table_Size)) && (s->on_exit != ETL_NULLPTR))
337 {
338 (TObject_Ref.*(s->on_exit))();
339 }
340
341 this->current_state_id = t->next_state_id;
342
343 // See if we have a state item for the new state.
344 s = find_state(this->current_state_id);
345
346 // If the new state has an 'on_entry' then call it.
347 if ((s != (State_Table_Begin + State_Table_Size)) && (s->on_entry != ETL_NULLPTR))
348 {
349 (TObject_Ref.*(s->on_entry))();
350 }
351 }
352
354 }
355 else
356 {
357 // Start the search from the next item in the table.
358 ++t;
359 }
360 }
361 }
362 }
363 }
364
365 private:
366
367 //*************************************************************************
370 //*************************************************************************
371 const state* find_state(state_id_t state_id)
372 {
373 return etl::find_if(State_Table_Begin, State_Table_Begin + State_Table_Size, is_state(state_id));
374 }
375
376 //*************************************************************************
377 struct is_transition
378 {
379 is_transition(event_id_t event_id_, state_id_t state_id_)
380 : event_id(event_id_)
381 , state_id(state_id_)
382 {
383 }
384
385 bool operator()(const transition& t) const
386 {
387 return (t.event_id == event_id) && (t.from_any_state || (t.current_state_id == state_id));
388 }
389
390 const event_id_t event_id;
391 const state_id_t state_id;
392 };
393
394 //*************************************************************************
395 struct is_state
396 {
397 is_state(state_id_t state_id_)
398 : state_id(state_id_)
399 {
400 }
401
402 bool operator()(const state& s) const
403 {
404 return (s.state_id == state_id);
405 }
406
407 const state_id_t state_id;
408 };
409
410 // Disabled
411 state_chart_ct(const state_chart_ct&) ETL_DELETE;
412 state_chart_ct& operator =(const state_chart_ct&) ETL_DELETE;
413
414 bool started;
415 };
416
417 //***************************************************************************
421 //***************************************************************************
422 template <typename TObject,
423 typename TParameter,
424 TObject& TObject_Ref,
426 size_t Transition_Table_Size,
427 const etl::state_chart_traits::state<TObject>* State_Table_Begin,
428 size_t State_Table_Size,
430 class state_chart_ctp : public istate_chart<TParameter>
431 {
432 public:
433
434 typedef TParameter parameter_t;
435 typedef state_chart_traits::state_id_t state_id_t;
436 typedef state_chart_traits::event_id_t event_id_t;
439
440 //*************************************************************************
442 //*************************************************************************
443 ETL_CONSTEXPR state_chart_ctp()
445 , started(false)
446 {
447 }
448
449 //*************************************************************************
452 //*************************************************************************
454 {
455 return TObject_Ref;
456 }
457
458 //*************************************************************************
461 //*************************************************************************
462 const TObject& get_object() const
463 {
464 return TObject_Ref;
465 }
466
467 //*************************************************************************
469 //*************************************************************************
470 virtual void start(bool on_entry_initial = true) ETL_OVERRIDE
471 {
472 if (!started)
473 {
475 {
476 // See if we have a state item for the initial state.
477 const state* s = find_state(this->current_state_id);
478
479 // If the initial state has an 'on_entry' then call it.
480 if ((s != (State_Table_Begin + State_Table_Size)) && (s->on_entry != ETL_NULLPTR))
481 {
482 (TObject_Ref.*(s->on_entry))();
483 }
484 }
485
486 started = true;
487 }
488 }
489
490 //*************************************************************************
495 //*************************************************************************
496 virtual void process_event(event_id_t event_id, parameter_t data) ETL_OVERRIDE
497 {
498 if (started)
499 {
501
502 // Keep looping until we execute a transition or reach the end of the table.
504 {
505 // Scan the transition table from the latest position.
506 t = etl::find_if(t, (Transition_Table_Begin + Transition_Table_Size), is_transition(event_id, this->current_state_id));
507
508 // Found an entry?
510 {
511 // Shall we execute the transition?
512 if ((t->guard == ETL_NULLPTR) || ((TObject_Ref.*t->guard)()))
513 {
514 // Shall we execute the action?
515 if (t->action != ETL_NULLPTR)
516 {
517#if ETL_USING_CPP11
518 (TObject_Ref.*t->action)(etl::forward<parameter_t>(data));
519#else
520 (TObject_Ref.*t->action)(data);
521#endif
522 }
523
524 // Changing state?
525 if (this->current_state_id != t->next_state_id)
526 {
527 const state* s;
528
529 // See if we have a state item for the current state.
530 s = find_state(this->current_state_id);
531
532 // If the current state has an 'on_exit' then call it.
533 if ((s != (State_Table_Begin + State_Table_Size)) && (s->on_exit != ETL_NULLPTR))
534 {
535 (TObject_Ref.*(s->on_exit))();
536 }
537
538 this->current_state_id = t->next_state_id;
539
540 // See if we have a state item for the new state.
541 s = find_state(this->current_state_id);
542
543 // If the new state has an 'on_entry' then call it.
544 if ((s != (State_Table_Begin + State_Table_Size)) && (s->on_entry != ETL_NULLPTR))
545 {
546 (TObject_Ref.*(s->on_entry))();
547 }
548 }
549
551 }
552 else
553 {
554 // Start the search from the next item in the table.
555 ++t;
556 }
557 }
558 }
559 }
560 }
561
562 private:
563
564 //*************************************************************************
567 //*************************************************************************
568 const state* find_state(state_id_t state_id)
569 {
570 return etl::find_if(State_Table_Begin, State_Table_Begin + State_Table_Size, is_state(state_id));
571 }
572
573 //*************************************************************************
574 struct is_transition
575 {
576 is_transition(event_id_t event_id_, state_id_t state_id_)
577 : event_id(event_id_)
578 , state_id(state_id_)
579 {
580 }
581
582 bool operator()(const transition& t) const
583 {
584 return (t.event_id == event_id) && (t.from_any_state || (t.current_state_id == state_id));
585 }
586
587 const event_id_t event_id;
588 const state_id_t state_id;
589 };
590
591 //*************************************************************************
592 struct is_state
593 {
594 is_state(state_id_t state_id_)
595 : state_id(state_id_)
596 {
597 }
598
599 bool operator()(const state& s) const
600 {
601 return (s.state_id == state_id);
602 }
603
604 const state_id_t state_id;
605 };
606
607 // Disabled
608 state_chart_ctp(const state_chart_ctp&) ETL_DELETE;
609 state_chart_ctp& operator =(const state_chart_ctp&) ETL_DELETE;
610
611 bool started;
612 };
613
614 //***************************************************************************
618 //***************************************************************************
619 template <typename TObject, typename TParameter = void>
620 class state_chart : public istate_chart<TParameter>
621 {
622 public:
623
624 typedef TParameter parameter_t;
625 typedef state_chart_traits::state_id_t state_id_t;
626 typedef state_chart_traits::event_id_t event_id_t;
629
630 //*************************************************************************
638 //*************************************************************************
643 const state* state_table_end_,
644 const state_id_t state_id_)
646 , object(object_)
647 , transition_table_begin(transition_table_begin_)
648 , state_table_begin(state_table_begin_)
649 , transition_table_size(transition_table_end_ - transition_table_begin_)
650 , state_table_size(state_table_end_ - state_table_begin_)
651 , started(false)
652 {
653 }
654
655 //*************************************************************************
659 //*************************************************************************
662 {
663 transition_table_begin = transition_table_begin_;
664 transition_table_size = transition_table_end_ - transition_table_begin_;
665 }
666
667 //*************************************************************************
671 //*************************************************************************
673 const state* state_table_end_)
674 {
675 state_table_begin = state_table_begin_;
676 state_table_size = state_table_end_ - state_table_begin_;
677 }
678
679 //*************************************************************************
682 //*************************************************************************
684 {
685 return object;
686 }
687
688 //*************************************************************************
691 //*************************************************************************
692 const TObject& get_object() const
693 {
694 return object;
695 }
696
697 //*************************************************************************
699 //*************************************************************************
700 virtual void start(bool on_entry_initial = true) ETL_OVERRIDE
701 {
702 if (!started)
703 {
705 {
706 // See if we have a state item for the initial state.
707 const state* s = find_state(this->current_state_id);
708
709 // If the initial state has an 'on_entry' then call it.
710 if ((s != state_table_end()) && (s->on_entry != ETL_NULLPTR))
711 {
712 (object.*(s->on_entry))();
713 }
714 }
715
716 started = true;
717 }
718 }
719
720 //*************************************************************************
725 //*************************************************************************
726 void process_event(event_id_t event_id, parameter_t data) ETL_OVERRIDE
727 {
728 if (started)
729 {
730 const transition* t = transition_table_begin;
731
732 // Keep looping until we execute a transition or reach the end of the table.
733 while (t != transition_table_end())
734 {
735 // Scan the transition table from the latest position.
736 t = etl::find_if(t, transition_table_end(), is_transition(event_id, this->current_state_id));
737
738 // Found an entry?
739 if (t != transition_table_end())
740 {
741 // Shall we execute the transition?
742 if ((t->guard == ETL_NULLPTR) || ((object.*t->guard)()))
743 {
744 // Shall we execute the action?
745 if (t->action != ETL_NULLPTR)
746 {
747#if ETL_USING_CPP11
748 (object.*t->action)(etl::forward<parameter_t>(data));
749#else
750 (object.*t->action)(data);
751#endif
752 }
753
754 // Changing state?
755 if (this->current_state_id != t->next_state_id)
756 {
757 const state* s;
758
759 // See if we have a state item for the current state.
760 s = find_state(this->current_state_id);
761
762 // If the current state has an 'on_exit' then call it.
763 if ((s != state_table_end()) && (s->on_exit != ETL_NULLPTR))
764 {
765 (object.*(s->on_exit))();
766 }
767
768 this->current_state_id = t->next_state_id;
769
770 // See if we have a state item for the new state.
771 s = find_state(this->current_state_id);
772
773 // If the new state has an 'on_entry' then call it.
774 if ((s != state_table_end()) && (s->on_entry != ETL_NULLPTR))
775 {
776 (object.*(s->on_entry))();
777 }
778 }
779
780 t = transition_table_end();
781 }
782 else
783 {
784 // Start the search from the next item in the table.
785 ++t;
786 }
787 }
788 }
789 }
790 }
791
792 private:
793
794 //*************************************************************************
797 //*************************************************************************
798 const state* find_state(state_id_t state_id)
799 {
800 if (state_table_begin == ETL_NULLPTR)
801 {
802 return state_table_end();
803 }
804 else
805 {
806 return etl::find_if(state_table_begin, state_table_end(), is_state(state_id));
807 }
808 }
809
810 //*************************************************************************
811 const transition* transition_table_end() const
812 {
813 return transition_table_begin + transition_table_size;
814 }
815
816 //*************************************************************************
817 const state* state_table_end() const
818 {
819 return state_table_begin + state_table_size;
820 }
821
822 //*************************************************************************
823 struct is_transition
824 {
825 is_transition(event_id_t event_id_, state_id_t state_id_)
826 : event_id(event_id_)
827 , state_id(state_id_)
828 {
829 }
830
831 bool operator()(const transition& t) const
832 {
833 return (t.event_id == event_id) && (t.from_any_state || (t.current_state_id == state_id));
834 }
835
836 const event_id_t event_id;
837 const state_id_t state_id;
838 };
839
840 //*************************************************************************
841 struct is_state
842 {
843 is_state(state_id_t state_id_)
844 : state_id(state_id_)
845 {
846 }
847
848 bool operator()(const state& s) const
849 {
850 return (s.state_id == state_id);
851 }
852
853 const state_id_t state_id;
854 };
855
856 // Disabled
857 state_chart(const state_chart&) ETL_DELETE;
858 state_chart& operator =(const state_chart&) ETL_DELETE;
859
860 TObject& object;
861 const transition* transition_table_begin;
862 const state* state_table_begin;
863 uint_least8_t transition_table_size;
864 uint_least8_t state_table_size;
865 bool started;
866 };
867
868 //***************************************************************************
872 //***************************************************************************
873 template <typename TObject>
874 class state_chart<TObject, void> : public istate_chart<void>
875 {
876 public:
877
878 typedef void parameter_t;
879 typedef state_chart_traits::state_id_t state_id_t;
880 typedef state_chart_traits::event_id_t event_id_t;
883
884 //*************************************************************************
892 //*************************************************************************
897 const state* state_table_end_,
898 const state_id_t state_id_)
900 , object(object_)
901 , transition_table_begin(transition_table_begin_)
902 , state_table_begin(state_table_begin_)
903 , transition_table_size(transition_table_end_ - transition_table_begin_)
904 , state_table_size(state_table_end_ - state_table_begin_)
905 , started(false)
906 {
907 }
908
909 //*************************************************************************
913 //*************************************************************************
916 {
917 transition_table_begin = transition_table_begin_;
918 transition_table_size = transition_table_end_ - transition_table_begin_;
919 }
920
921 //*************************************************************************
925 //*************************************************************************
927 const state* state_table_end_)
928 {
929 state_table_begin = state_table_begin_;
930 state_table_size = state_table_end_ - state_table_begin_;
931 }
932
933 //*************************************************************************
936 //*************************************************************************
938 {
939 return object;
940 }
941
942 //*************************************************************************
945 //*************************************************************************
946 const TObject& get_object() const
947 {
948 return object;
949 }
950
951 //*************************************************************************
953 //*************************************************************************
954 virtual void start(bool on_entry_initial = true) ETL_OVERRIDE
955 {
956 if (!started)
957 {
959 {
960 // See if we have a state item for the initial state.
961 const state* s = find_state(this->current_state_id);
962
963 // If the initial state has an 'on_entry' then call it.
964 if ((s != state_table_end()) && (s->on_entry != ETL_NULLPTR))
965 {
966 (object.*(s->on_entry))();
967 }
968 }
969
970 started = true;
971 }
972 }
973
974 //*************************************************************************
979 //*************************************************************************
980 void process_event(event_id_t event_id) ETL_OVERRIDE
981 {
982 if (started)
983 {
984 const transition* t = transition_table_begin;
985
986 // Keep looping until we execute a transition or reach the end of the table.
987 while (t != transition_table_end())
988 {
989 // Scan the transition table from the latest position.
990 t = etl::find_if(t, transition_table_end(), is_transition(event_id, this->current_state_id));
991
992 // Found an entry?
993 if (t != transition_table_end())
994 {
995 // Shall we execute the transition?
996 if ((t->guard == ETL_NULLPTR) || ((object.*t->guard)()))
997 {
998 // Shall we execute the action?
999 if (t->action != ETL_NULLPTR)
1000 {
1001 (object.*t->action)();
1002 }
1003
1004 // Changing state?
1005 if (this->current_state_id != t->next_state_id)
1006 {
1007 const state* s;
1008
1009 // See if we have a state item for the current state.
1010 s = find_state(this->current_state_id);
1011
1012 // If the current state has an 'on_exit' then call it.
1013 if ((s != state_table_end()) && (s->on_exit != ETL_NULLPTR))
1014 {
1015 (object.*(s->on_exit))();
1016 }
1017
1018 this->current_state_id = t->next_state_id;
1019
1020 // See if we have a state item for the new state.
1021 s = find_state(this->current_state_id);
1022
1023 // If the new state has an 'on_entry' then call it.
1024 if ((s != state_table_end()) && (s->on_entry != ETL_NULLPTR))
1025 {
1026 (object.*(s->on_entry))();
1027 }
1028 }
1029
1030 t = transition_table_end();
1031 }
1032 else
1033 {
1034 // Start the search from the next item in the table.
1035 ++t;
1036 }
1037 }
1038 }
1039 }
1040 }
1041
1042 private:
1043
1044 //*************************************************************************
1047 //*************************************************************************
1048 const state* find_state(state_id_t state_id)
1049 {
1050 if (state_table_begin == ETL_NULLPTR)
1051 {
1052 return state_table_end();
1053 }
1054 else
1055 {
1056 return etl::find_if(state_table_begin, state_table_end(), is_state(state_id));
1057 }
1058 }
1059
1060 //*************************************************************************
1061 const transition* transition_table_end() const
1062 {
1063 return transition_table_begin + transition_table_size;
1064 }
1065
1066 //*************************************************************************
1067 const state* state_table_end() const
1068 {
1069 return state_table_begin + state_table_size;
1070 }
1071
1072 //*************************************************************************
1073 struct is_transition
1074 {
1075 is_transition(event_id_t event_id_, state_id_t state_id_)
1076 : event_id(event_id_)
1077 , state_id(state_id_)
1078 {
1079 }
1080
1081 bool operator()(const transition& t) const
1082 {
1083 return (t.event_id == event_id) && (t.from_any_state || (t.current_state_id == state_id));
1084 }
1085
1086 const event_id_t event_id;
1087 const state_id_t state_id;
1088 };
1089
1090 //*************************************************************************
1091 struct is_state
1092 {
1093 is_state(state_id_t state_id_)
1094 : state_id(state_id_)
1095 {
1096 }
1097
1098 bool operator()(const state& s) const
1099 {
1100 return (s.state_id == state_id);
1101 }
1102
1103 const state_id_t state_id;
1104 };
1105
1106 // Disabled
1107 state_chart(const state_chart&) ETL_DELETE;
1108 state_chart& operator =(const state_chart&) ETL_DELETE;
1109
1110 TObject& object;
1111 const transition* transition_table_begin;
1112 const state* state_table_begin;
1113 uint_least8_t transition_table_size;
1114 uint_least8_t state_table_size;
1115 bool started;
1116 };
1117}
1118
1119#endif
state_id_t get_state_id() const
Definition state_chart.h:215
state_id_t current_state_id
The current state id.
Definition state_chart.h:222
For non-void parameter types.
Definition state_chart.h:160
state_id_t current_state_id
The current state id.
Definition state_chart.h:187
state_id_t get_state_id() const
Definition state_chart.h:180
ETL_CONSTEXPR state_chart(TObject &object_, const transition *transition_table_begin_, const transition *transition_table_end_, const state *state_table_begin_, const state *state_table_end_, const state_id_t state_id_)
Definition state_chart.h:893
virtual void start(bool on_entry_initial=true) ETL_OVERRIDE
Start the state chart.
Definition state_chart.h:954
void process_event(event_id_t event_id) ETL_OVERRIDE
Definition state_chart.h:980
TObject & get_object()
Definition state_chart.h:937
const TObject & get_object() const
Definition state_chart.h:946
void set_transition_table(const transition *transition_table_begin_, const transition *transition_table_end_)
Definition state_chart.h:914
void set_state_table(const state *state_table_begin_, const state *state_table_end_)
Definition state_chart.h:926
Definition state_chart.h:238
ETL_CONSTEXPR state_chart_ct()
Constructor.
Definition state_chart.h:250
const TObject & get_object() const
Definition state_chart.h:269
TObject & get_object()
Definition state_chart.h:260
virtual void start(bool on_entry_initial=true) ETL_OVERRIDE
Start the state chart.
Definition state_chart.h:277
virtual void process_event(event_id_t event_id) ETL_OVERRIDE
Definition state_chart.h:303
Definition state_chart.h:431
const TObject & get_object() const
Definition state_chart.h:462
TObject & get_object()
Definition state_chart.h:453
virtual void start(bool on_entry_initial=true) ETL_OVERRIDE
Start the state chart.
Definition state_chart.h:470
virtual void process_event(event_id_t event_id, parameter_t data) ETL_OVERRIDE
Definition state_chart.h:496
ETL_CONSTEXPR state_chart_ctp()
Constructor.
Definition state_chart.h:443
Definition state_chart.h:621
void process_event(event_id_t event_id, parameter_t data) ETL_OVERRIDE
Definition state_chart.h:726
ETL_CONSTEXPR state_chart(TObject &object_, const transition *transition_table_begin_, const transition *transition_table_end_, const state *state_table_begin_, const state *state_table_end_, const state_id_t state_id_)
Definition state_chart.h:639
TObject & get_object()
Definition state_chart.h:683
virtual void start(bool on_entry_initial=true) ETL_OVERRIDE
Start the state chart.
Definition state_chart.h:700
void set_transition_table(const transition *transition_table_begin_, const transition *transition_table_end_)
Definition state_chart.h:660
void set_state_table(const state *state_table_begin_, const state *state_table_end_)
Definition state_chart.h:672
const TObject & get_object() const
Definition state_chart.h:692
bitset_ext
Definition absolute.h:38
pair holds two objects of arbitrary type
Definition utility.h:164
State definition.
Definition state_chart.h:139
Transition definition.
Definition state_chart.h:56