OpenRTM-aist  2.1.0
Macho.h
[詳解]
1 #ifndef MACHO_HPP
2 #define MACHO_HPP
3 
4 // Macho - C++ Machine Objects
5 //
6 // The Machine Objects class library (in short Macho) allows the creation of
7 // state machines based on the "State" design pattern in straight C++. It
8 // extends the pattern with the option to create hierarchical state machines,
9 // making it possible to convert the popular UML statechart notation to working
10 // code in a straightforward way. Other features are entry and exit actions,
11 // state histories and state variables.
12 //
13 // Copyright (c) 2005 by Eduard Hiti (feedback to macho@ehiti.de)
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining a copy
16 // of this software and associated documentation files (the "Software"), to deal
17 // in the Software without restriction, including without limitation the rights
18 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19 // copies of the Software, and to permit persons to whom the Software is
20 // furnished to do so, subject to the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be included in
23 // all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 // SOFTWARE.
32 //
33 // You are encouraged to provide any changes, extensions and corrections for
34 // this software to the author at the above-mentioned email address for
35 // inclusion into future versions.
36 //
37 //
38 // Description:
39 //
40 // States are represented as C++ classes. The hierarchy of states follows the
41 // inheritance relation between these state classes. A set of state classes for
42 // a single state machine derives directly or indirectly from a top state class,
43 // making it the composite state holding all other states. Events are processed
44 // by calling virtual methods of the top state class. Substates redefine the
45 // behaviour of these event handler methods.
46 //
47 // Special methods "entry", "exit" and "init" are called on state entry, state
48 // exit and state initialization of super- and substates (in the order defined
49 // by statechart semantics and current machine state).
50 //
51 // An object of type "Machine" maintains the current state of a state machine
52 // and dispatches events to it. The "Machine" type is a template class
53 // parametrized with the top state class of the state machine to be run.
54 //
55 // State data is not kept in state classes (because state class instances are
56 // created just once and then reused, whereas state data should be instantiated
57 // or destroyed each time its state is entered or left). State data is put in
58 // "Box" types specific to each state class instead, which are managed by the
59 // Machine object. Boxes are retrieved by calling the "box" method.
60 // Superstate boxes are accessible by qualifiying the "box" method with the
61 // state class name (e.g. TOP::box()).
62 //
63 // A history of entered substates can be kept for superstates. With a special
64 // transition into the superstate the history substate can be reentered. History
65 // can be shallow (only direct substates) or deep (any substate).
66 //
67 //
68 // Example:
69 //
70 // #include "Macho.hpp"
71 // #include <iostream>
72 // using namespace std;
73 //
74 // namespace Example {
75 // TOPSTATE(Top) {
76 // struct Box {
77 // Box() : data(0) {}
78 // long data;
79 // };
80 //
81 // STATE(Top)
82 //
83 // virtual void event1() {}
84 // virtual void event2() {}
85 //
86 // private:
87 // void entry();
88 // void exit();
89 // void init();
90 // };
91 //
92 // SUBSTATE(Super, Top) {
93 // STATE(Super)
94 // HISTORY()
95 //
96 // private:
97 // void entry();
98 // void exit();
99 // };
100 //
101 // SUBSTATE(StateA, Super) {
102 // struct Box {
103 // Box() : data(0) {}
104 // int data;
105 // };
106 //
107 // STATE(StateA)
108 //
109 // void event1();
110 //
111 // private:
112 // void entry();
113 // void exit();
114 // void init(int i);
115 // };
116 //
117 // SUBSTATE(StateB, Super) {
118 // STATE(StateB)
119 //
120 // void event2();
121 //
122 // private:
123 // void entry();
124 // void exit();
125 // };
126 //
127 // void Top::entry() { cout << "Top::entry" << endl; }
128 // void Top::exit() { cout << "Top::exit" << endl; }
129 // void Top::init() { setState<StateA>(42); }
130 //
131 // void Super::entry() { cout << "Super::entry" << endl; }
132 // void Super::exit() { cout << "Super::exit" << endl; }
133 //
134 // void StateA::entry() { cout << "StateA::entry" << endl; }
135 // void StateA::init(int i) { box().data = i; }
136 // void StateA::exit() { cout << "StateA::exit" << endl; }
137 // void StateA::event1() { setState<StateB>(); }
138 //
139 // void StateB::entry() { cout << "StateB::entry" << endl; }
140 // void StateB::exit() { cout << "StateB::exit" << endl; }
141 // void StateB::event2() { setState<StateA>(); }
142 // }
143 //
144 // int main() {
145 // Macho::Machine<Example::Top> m;
146 // m->event1();
147 // m->event2();
148 //
149 // return 0;
150 // }
151 //
152 // Output is:
153 //
154 // Top::entry
155 // Super::entry
156 // StateA::entry
157 // StateA::exit
158 // StateB::entry
159 // StateB::exit
160 // StateA::entry
161 // StateA::exit
162 // Super::exit
163 // Top::exit
164 //
165 //
166 // Version History:
167 //
168 // 0.9.6 (released 2007-09-01):
169 // - Changes to state transition semantics (see file "changes_0_9_6.txt")
170 // - New mechanism for state initialization
171 // - Runtime reflection on state relationships now possible
172 //
173 // 0.9.5 (released 2007-05-01):
174 // - Introduction of parametrized state transitions
175 //
176 // 0.9.4 (released 2006-06-01):
177 // - Snapshot functionality added
178 //
179 // 0.9.3 (released 2006-04-20):
180 // - Code reorganization (file Macho.cpp added)
181 //
182 // 0.9.2 (released 2006-04-10):
183 // - Memory leak plugged
184 // - MSVC6 version updated
185 //
186 // 0.9.1 (released 2006-03-30):
187 // - Introduction of persistent boxes
188 // - Speed and size optimizations
189 // - Machine instance can be accessed in event handlers with method "machine"
190 //
191 // 0.9 (released 2006-01-15):
192 // - Introduction of queuable event type
193 //
194 // 0.8.2 (released 2005-12-15):
195 // - Code size reduction by minimizing use of template classes
196 //
197 // 0.8.1 (released 2005-12-01):
198 // - Added MSVC6 variant (see directory "msvc6")
199 // - Added method "clearHistoryDeep"
200 //
201 // 0.8 (released 2005-11-01):
202 // - Initial release
203 //
204 
205 #include <new>
206 #include <cassert>
207 
208 #if defined(__clang__)
209 #if defined(_WIN32) || defined(_WIN64)
210 #pragma clang diagnostic push
211 #pragma clang diagnostic ignored "-Wreserved-identifier"
212 #endif
213 #endif
214 
215 
216 class TestAccess;
217 
218 
220 // Check type equality at compile time.
221 template<class T, class U>
223 };
224 
225 template<class T>
226 struct CheckSameType<T, T> {
227  using Check = bool;
228 };
229 
230 
232 // Various macros for state and history declaration
233 
234 // Use this macro to define your top state class.
235 #define TOPSTATE(TOP) \
236  struct TOP : public ::Macho::Link< TOP, ::Macho::TopBase< TOP > >
237 
238 // Use this macro for all other state classes.
239 #define SUBSTATE(STATE, SUPERSTATE) \
240  struct STATE : public ::Macho::Link< STATE, SUPERSTATE >
241 
242 // Use this macro in your class definition to give it state functionality
243 // (mandatory). If you have a state box declare it BEFORE macro invocation!
244 #define STATE(S) \
245 public: \
246  using SELF = S; \
247  /* Constructor and destructor already defined: you can't (and shouldn't) have your own! */ \
248  /* For the user a state class "constructor" and "destructor" are its entry and exit method! */ \
249  S(::Macho::_StateInstance & instance) : ::Macho::Link<S, SUPER>(instance) { \
250  /* Compile time check: S must derive directly from Link<S, SUPER> */ \
251  using MustDeriveFromLink = ::CheckSameType< ::Macho::Link<S, SUPER>, LINK>::Check; \
252  } \
253  ~S() {} \
254  static const char * _state_name() { return #S; } \
255  /* Get to your Box with this method: */ \
256  Box & box() { return *static_cast<Box *>(_box()); } \
257  friend class ::_VS8_Bug_101615;
258 
259 // Use this macro to select deep history strategy.
260 #define DEEPHISTORY() \
261 private: \
262  /* If no superstate has history, SUPER::_setHistorySuper is a NOOP */ \
263  void _saveHistory(::Macho::_StateInstance & self, ::Macho::_StateInstance & /* shallow */, ::Macho::_StateInstance & deep) override\
264  { self.setHistory(&deep); SELF::SUPER::_setHistorySuper(self, deep); } \
265 protected: \
266  /* Substates may use _setHistorySuper to bubble up history */ \
267  void _setHistorySuper(::Macho::_StateInstance & self, ::Macho::_StateInstance & deep) override\
268  { self.setHistorySuper(deep); } \
269 public:\
270  static_assert(true, "dummy for extra semicolon warning")
271 
272 // Use this macro to select shallow history strategy.
273 #define HISTORY() \
274 private: \
275  /* If no superstate has history, SUPER::_setHistorySuper is a NOOP */ \
276  virtual void _saveHistory(::Macho::_StateInstance & self, ::Macho::_StateInstance & shallow, ::Macho::_StateInstance & deep) \
277  { self.setHistory(&shallow); SELF::SUPER::_setHistorySuper(self, deep); } \
278 protected: \
279  /* Substates may use _setHistorySuper to bubble up history */ \
280  virtual void _setHistorySuper(::Macho::_StateInstance & self, ::Macho::_StateInstance & deep) \
281  { self.setHistorySuper(deep); } \
282 public:\
283  static_assert(true, "dummy for extra semicolon warning")
284 
285 // Use this macro to have boxes survive state transitions
286 #define PERSISTENT() \
287 private: \
288  virtual void _deleteBox(::Macho::_StateInstance & instance) {} \
289 public:
290 
291 
293 // Everything else is put into namespace 'Macho'.
294 // Some identifiers are prefixed with an underscore to prevent name clashes with
295 // deriving classes or to mark things as library internal. Don't touch things
296 // with an underscore prefix!
297 namespace Macho {
298 
299  class _MachineBase;
300 
301  template<class T>
302  class Machine;
303 
304  template<class T>
305  class IEvent;
306 
307  class _StateInstance;
308 
309  // Unique identifier of states.
310  using Key = void*;
311 
312  // Also an unique identifier of states, build from consecutive integers.
313  // Use Key to get to ID.
314  using ID = unsigned int;
315 
316 
318  // Box for states which don't declare own Box class.
319  class _EmptyBox {
320  public:
322  };
323 
324 
326  // Helper functions for box creation
327  template<class B>
328  void * _createBox(void * & place) {
329  if (!place)
330  place = ::operator new(sizeof(B));
331 
332  new (place) B;
333 
334  void * box = place;
335  place = nullptr;
336 
337  return box;
338  }
339 
340  template<class B>
341  void _deleteBox(void * & box, void * & place) {
342  assert(box);
343  assert(!place);
344 
345  static_cast<B *>(box)->~B();
346  place = box;
347  box = nullptr;
348  }
349 
350 #ifdef MACHO_SNAPSHOTS
351  template<class B>
352  void * _cloneBox(void * other) {
353  assert(other);
354  return new B(*static_cast<B *>(other));
355  }
356 #endif
357 
358  // Specializations for EmptyBox:
359  // EmptyBox object gets reused over and over and never is deleted.
360  template<>
361  void * _createBox<_EmptyBox>(void * & place);
362 
363  template<>
364  void _deleteBox<_EmptyBox>(void * & box, void * & place);
365 
366 #ifdef MACHO_SNAPSHOTS
367  template<>
368  void * _cloneBox<_EmptyBox>(void * other);
369 #endif
370 
371 
373  // Essential information pointed at by state key.
374  struct _KeyData {
376  using Predicate = bool (*)(Key);
377  using NameFn = const char* (*)();
378 
379  // Get StateInstance object from key.
381 
382  // Is state of given key a child state?
384 
385  const NameFn name;
386  const ID id;
387  };
388 
389 
391  // Base class for all state classes.
392  // Also serves as 'Root' state. By entering this state we trigger entry
393  // and exit actions of user's top state.
395  public:
396  virtual ~_StateSpecification() = default;
397 
398  static bool isChild(Key /*key*/) {
399  return false;
400  }
401 
402  protected:
404  : _myStateInstance(instance)
405  {}
406 
407  // Initiate transition to a new state.
408  // Template parameter S is the new state to enter.
409  // Transition is performed AFTER control flow returns to the Machine object.
410  // Initiating more than one transition is considered an error!
411  // The new state may receive parameters for its 'init' methods:
412  // setState<StateA>("someData");
413  template<class S>
414  void setState();
415 
416  template<class S, class P1>
417  void setState(const P1 & p1);
418 
419  template<class S, class P1, class P2>
420  void setState(const P1 & p1, const P2 & p2);
421 
422  template<class S, class P1, class P2, class P3>
423  void setState(const P1 & p1, const P2 & p2, const P3 & p3);
424 
425  template<class S, class P1, class P2, class P3, class P4>
426  void setState(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4);
427 
428  template<class S, class P1, class P2, class P3, class P4, class P5>
429  void setState(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5);
430 
431  template<class S, class P1, class P2, class P3, class P4, class P5, class P6>
432  void setState(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6);
433 
434  // Initiate transition to a state's history.
435  // If state has no history, transition is to the state itself.
436  template<class S>
437  void setStateHistory();
438 
439  // Initiate transition to a new state.
440  // Parameter 'state' is the new state to enter.
441  // See above and class 'Alias' for more information.
442  void setState(const class Alias & state);
443 
444  // Deprectated!
445  template<class S>
446  void setStateBox(typename S::Box * box = 0);
447 
448  // Deprectated!
449  template<class S>
450  void setStateDirect(typename S::Box * box = 0);
451 
452  // 'Restore from snapshot' event: set current state.
453  // Default implementation: Does not trigger entry actions!
454  virtual void _restore(_StateInstance & current);
455 
456  // only to be used in _restore
457  void setState(_StateInstance & current);
458 
459  // 'Shutdown machine' event: exit all states.
460  // Default implementation: Triggers exit actions!
461  // Override empty to omit calling exit actions.
462  virtual void _shutdown();
463 
464  // This is the method to bubble up history information
465  // for states whose superstates have no history (so does nothing).
466  virtual void _setHistorySuper(_StateInstance & /* self */, _StateInstance & /* deep*/ ) {}
467 
468  private:
469  // State exit. Not allowed to initiate state change.
470  virtual void exit() {}
471 
472  // State entry. Not allowed to initiate state change.
473  virtual void entry() {}
474 
475  // Special kind of state entry: Upon transition to a new state,
476  // entry methods of that state and its superstates are called;
477  // 'init' however is called only on the one state the transition
478  // actually goes to.
479  // Is allowed to change state (to child states).
480  virtual void init() {}
481 
482  private:
483  // C++ needs something like package visibility
484 
485  // for _myStateInstance
486  template<class T>
487  friend class TopBase;
488 
489  // for _getInstance
490  template<class C, class P>
491  friend class Link;
492 
493  friend class _StateInstance;
494  friend class _RootInstance;
495 
496  friend class _MachineBase;
497 
498  // Create StateInstance object of state.
499  static _StateInstance & _getInstance(_MachineBase & machine);
500 
501  virtual void _deleteBox(_StateInstance & /* instance */) {}
502 
503  // Default history strategy (no history).
504  virtual void _saveHistory(_StateInstance & /* self */, _StateInstance & /* shallow */, _StateInstance & /* deep */) {}
505 
506  private:
507  _StateInstance & _myStateInstance;
508  };
509 
510 
512  // Base class for user defined top state (and indirectly all other states).
513  template<class T>
514  class TopBase : public _StateSpecification {
515  public:
516  // This typedef is an alias for user defined top state in all (sub)states.
517  using TOP = T;
518 
519  protected:
521  : _StateSpecification(instance)
522  {}
523 
524  void dispatch(IEvent<TOP> * event);
525 
526  const Machine<TOP> & machine();
527  };
528 
529 
531  // This class links substate specifications to superstate specifications by
532  // deriving from the superstate and being derived from by the substate.
533  // Substates inherit event handlers from superstates for reuse or redefinition
534  // this way.
535  template<class C, class P>
536  class Link : public P {
537  public:
538  // Alias for superstate.
539  using SUPER = P;
540 
541  // Alias for topstate.
542  using TOP = typename P::TOP;
543 
544  // Default box type.
545  using Box = _EmptyBox;
546 
547  // Get unique key of state.
548  static Key key();
549 
550  static Alias alias();
551 
552  static bool isChild(Key other) {
553  return key() == other || SUPER::isChild(other);
554  }
555 
556  static bool isParent(Key other) {
557  return static_cast<_KeyData *>(other)->childPredicate(key());
558  }
559 
560  // Is machine m in this state?
561  static bool isCurrent(const _MachineBase & machine);
562 
563  // Deprecated!
564  // Is machine m in exactly this state?
565  static bool isCurrentDirect(const _MachineBase & machine);
566 
567  static void clearHistory(const _MachineBase & machine);
568 
569  static void clearHistoryDeep(const _MachineBase & machine);
570 
571  static Alias history(const _MachineBase & machine);
572 
573  protected:
574  // Needed to perform compile time checks.
575  using LINK = Link<C, P>;
576 
577  Link(_StateInstance & instance);
578 
579  // These definitions seem redundant but they are not!
580  // They override parent definitions so each substate gets either
581  // this default or their own, but never its parents definitions.
582  void entry() override {}
583  void init() override {}
584  void exit() override {}
585 
586  // This method keeps '_myStateInstance' attribute private.
587  void * _box();
588 
589  private:
590  // for _getInstance
591  template<class U, class V>
592  friend class Link;
593 
594  // for _getInstance
595  friend class _StateSpecification;
596 
597  // for _getInstance
598  friend class Machine<TOP>;
599 
600  // for _getInstance
601  friend class Alias;
602 
603  // for Tests
604  friend class ::TestAccess;
605 
606  // Create StateInstance object of state.
607  static _StateInstance & _getInstance(_MachineBase & machine);
608 
609  // Box is by default not persistent. Not redundant!
610  void _deleteBox(_StateInstance & instance) override;
611 
612  // Default history strategy (no history). Not redundant!
613  void _saveHistory(_StateInstance & self, _StateInstance & /*shallow*/, _StateInstance & deep) override {
614  // Bubble up history. If no superstate has history, _setHistorySuper will do nothing.
615  this->_setHistorySuper(self, deep);
616  }
617 
618  private:
619  _StateInstance & _myStateInstance;
620  };
621 
622 
624  // Unique identifier for state S.
625  template<class S>
626  class StateID {
627  public:
628  static const ID value;
629  };
630 
631 
633  // StateInstance maintains machine specific data about a state. Keeps history, box
634  // and state object for state. StateInstance object is created the first time state
635  // is entered. There is at most one StateInstance object per state per machine
636  // instance.
638  protected:
640 
641  public:
642  virtual ~_StateInstance();
643 
644  // Perform entry actions.
645  // 'first' is true on very first call.
646  void entry(_StateInstance & previous, bool first = true);
647 
648  // Perform exit actions.
649  void exit(_StateInstance & next);
650 
651  // Perform init action.
652  void init(bool history);
653 
654  void saveHistory(_StateInstance & shallow, _StateInstance & deep) {
655  // Check state's history strategy.
656  mySpecification->_saveHistory(*this, shallow, deep);
657  }
658 
659  // Update superstate's history information:
661  if (myParent != nullptr)
662  // Let it choose between deep or shallow history.
663  myParent->saveHistory(*this, deep);
664  }
665 
666 #ifdef MACHO_SNAPSHOTS
667  // Copy state of another StateInstance object.
668  void copy(_StateInstance & original);
669 
670  // Create a clone of StateInstance object for another machine.
671  _StateInstance * clone(_MachineBase & newMachine);
672 #endif
673 
674  void shutdown() {
676  }
677 
678  void restore(_StateInstance & instance) {
679  mySpecification->_restore(instance);
680  }
681 
682  virtual ID id() = 0;
683 
684  virtual Key key() = 0;
685 
686  virtual const char * name() = 0;
687 
688  // 'Virtual constructor' needed for cloning.
690 
691  virtual void createBox() = 0;
692  virtual void deleteBox() = 0;
693 #ifdef MACHO_SNAPSHOTS
694  virtual void cloneBox(void * box) = 0;
695 #endif
696 
697  // Deprecated!
698  void setBox(void * box) {
699  assert(!myBox);
700 
701  if (myBoxPlace != nullptr) {
702  // Free cached memory of previously used box.
703  ::operator delete(myBoxPlace);
704  myBoxPlace = nullptr;
705  }
706 
707  myBox = box;
708  }
709 
710  // Is 'instance' a superstate?
711  bool isChild(const _StateInstance & instance) {
712  return this == &instance || ((myParent != nullptr) && myParent->isChild(instance));
713  }
714 
716  assert(mySpecification);
717  return *mySpecification;
718  }
719 
720  void * box() {
721  assert(myBox);
722  return myBox;
723  }
724 
726  return myMachine;
727  }
728 
729  // const: History can be manipulated even on a const object.
731  myHistory = history;
732  }
733 
735  return myHistory;
736  }
737 
738  protected:
740  _StateSpecification * mySpecification; // Instance of state class
743  void * myBox;
744  void * myBoxPlace; // Reused box heap memory
745  };
746 
747 
749  // StateInstance for Root state (the real top state).
750  class _RootInstance : public _StateInstance {
751  protected:
752  friend class _StateSpecification;
753 
755  : _StateInstance(machine, parent)
756  {
758  }
759 
760  public:
761  ID id() override {
762  return 0;
763  }
764 
765  Key key() override {
766  // Can't happen: key is only called by users, and they don't know about Root.
767  assert(false); return nullptr;
768  }
769 
770  void createBox() override {}
771  void deleteBox() override {}
772 #ifdef MACHO_SNAPSHOTS
773  virtual void cloneBox(void * box) {}
774 #endif
775 
776  const char * name() override { return "Root"; }
777 
778  // 'Virtual constructor' needed for cloning.
780  return new _RootInstance(machine, parent);
781  }
782 
783  };
784 
785 
787  // StateInstance for substates (including Top ;-)
788  // Has methods to create state specific objects.
789  template<class S>
791  protected:
792  template<class C, class P>
793  friend class Link;
794 
796  : _StateInstance(machine, parent)
797  {
798  assert(parent);
799  this->mySpecification = new S(*this);
800  }
801 
802  public:
803  using Box = typename S::Box;
804 
805  ~_SubstateInstance() override {
806  if (this->myBox)
807  Macho::_deleteBox<Box>(myBox, myBoxPlace);
808  }
809 
810  const char * name() override { return S::_state_name(); }
811 
812  ID id() override {
813  return StateID<S>::value;
814  }
815 
816  Key key() override {
817  return S::key();
818  }
819 
820  // 'Virtual constructor' needed for cloning.
822  return new _SubstateInstance<S>(machine, parent);
823  }
824 
825  void createBox() override {
826  if (!this->myBox)
827  this->myBox = Macho::_createBox<Box>(myBoxPlace);
828  }
829 
830  void deleteBox() override {
831  assert(myBox);
832  Macho::_deleteBox<Box>(myBox, myBoxPlace);
833  }
834 
835 #ifdef MACHO_SNAPSHOTS
836  virtual void cloneBox(void * box) {
837  assert(!myBox);
838  assert(!myBoxPlace);
839  // Needs copy constructor in ALL box types.
840  myBox = Macho::_cloneBox<Box>(box);
841  }
842 #endif
843 
844  };
845 
846 
848  // Definitions for queuable event types
849 
850  // Generic interface for event objects (available only to MachineBase)
851  class _IEventBase {
852  public:
853  virtual ~_IEventBase() = default;
854  virtual void dispatch(_StateInstance &) = 0;
855  };
856 
857 
858  // Interface for event objects (bound to a top state)
859  template<class TOP>
860  class IEvent : protected _IEventBase {
861  friend class Machine<TOP>;
862  friend class TopBase<TOP>;
863  };
864 
865 
866  // Event with four parameters
867  template<class TOP, class R, class P1, class P2, class P3, class P4, class P5, class P6>
868  class _Event6 : public IEvent<TOP> {
869  using Signature = R (TOP::*)(P1, P2, P3, P4, P5, P6);
870 
871  public:
872  _Event6(Signature handler, const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6)
873  : myHandler(handler)
874  , myParam1(p1)
875  , myParam2(p2)
876  , myParam3(p3)
877  , myParam4(p4)
878  , myParam5(p5)
879  , myParam6(p6)
880  {}
881 
882  protected:
883  void dispatch(_StateInstance & instance) {
884  TOP & behaviour = static_cast<TOP &>(instance.specification());
886  }
887 
888  Signature myHandler;
895  };
896 
897 
898  // Event with four parameters
899  template<class TOP, class R, class P1, class P2, class P3, class P4, class P5>
900  class _Event5 : public IEvent<TOP> {
901  using Signature = R (TOP::*)(P1, P2, P3, P4, P5);
902 
903  public:
904  _Event5(Signature handler, const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5)
905  : myHandler(handler)
906  , myParam1(p1)
907  , myParam2(p2)
908  , myParam3(p3)
909  , myParam4(p4)
910  , myParam5(p5)
911  {}
912 
913  protected:
914  void dispatch(_StateInstance & instance) {
915  TOP & behaviour = static_cast<TOP &>(instance.specification());
917  }
918 
919  Signature myHandler;
925  };
926 
927 
928  // Event with four parameters
929  template<class TOP, class R, class P1, class P2, class P3, class P4>
930  class _Event4 : public IEvent<TOP> {
931  using Signature = R (TOP::*)(P1, P2, P3, P4);
932 
933  public:
934  _Event4(Signature handler, const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4)
935  : myHandler(handler)
936  , myParam1(p1)
937  , myParam2(p2)
938  , myParam3(p3)
939  , myParam4(p4)
940  {}
941 
942  protected:
943  void dispatch(_StateInstance & instance) {
944  TOP & behaviour = static_cast<TOP &>(instance.specification());
945  (behaviour.*myHandler)(myParam1, myParam2, myParam3, myParam4);
946  }
947 
948  Signature myHandler;
953  };
954 
955 
956  // Event with three parameters
957  template<class TOP, class R, class P1, class P2, class P3>
958  class _Event3 : public IEvent<TOP> {
959  using Signature = R (TOP::*)(P1, P2, P3);
960 
961  public:
962  _Event3(Signature handler, const P1 & p1, const P2 & p2, const P3 & p3)
963  : myHandler(handler)
964  , myParam1(p1)
965  , myParam2(p2)
966  , myParam3(p3)
967  {}
968 
969  protected:
970  void dispatch(_StateInstance & instance) {
971  TOP & behaviour = static_cast<TOP &>(instance.specification());
972  (behaviour.*myHandler)(myParam1, myParam2, myParam3);
973  }
974 
975  Signature myHandler;
979  };
980 
981 
982  // Event with two parameters
983  template<class TOP, class R, class P1, class P2>
984  class _Event2 : public IEvent<TOP> {
985  using Signature = R (TOP::*)(P1, P2);
986 
987  public:
988  _Event2(Signature handler, const P1 & p1, const P2 & p2)
989  : myHandler(handler)
990  , myParam1(p1)
991  , myParam2(p2)
992  {}
993 
994  protected:
995  void dispatch(_StateInstance & instance) {
996  TOP & behaviour = static_cast<TOP &>(instance.specification());
997  (behaviour.*myHandler)(myParam1, myParam2);
998  }
999 
1000  Signature myHandler;
1003  };
1004 
1005 
1006  // Event with one parameter
1007  template<class TOP, class R, class P1>
1008  class _Event1 : public IEvent<TOP> {
1009  using Signature = R (TOP::*)(P1);
1010 
1011  public:
1012  _Event1(Signature handler, const P1 & p1)
1013  : myHandler(handler)
1014  , myParam1(p1)
1015  {}
1016 
1017  protected:
1018  void dispatch(_StateInstance & instance) override {
1019  TOP & behaviour = static_cast<TOP &>(instance.specification());
1020  (behaviour.*myHandler)(myParam1);
1021  }
1022 
1023  Signature myHandler;
1025  };
1026 
1027 
1028  // Event with no parameters
1029  template<class TOP, class R>
1030  class _Event0 : public IEvent<TOP> {
1031  using Signature = R (TOP::*)();
1032 
1033  public:
1034  _Event0(Signature handler)
1035  : myHandler(handler)
1036  {}
1037 
1038  protected:
1039  void dispatch(_StateInstance & instance) override {
1040  TOP & behaviour = static_cast<TOP &>(instance.specification());
1041  (behaviour.*myHandler)();
1042  }
1043 
1044  Signature myHandler;
1045  };
1046 
1047 
1048  // Event creating functions using type inference
1049  template<class TOP, class R, class P1, class P2, class P3, class P4, class P5, class P6>
1050  inline IEvent<TOP> * Event(R (TOP::*handler)(P1, P2, P3, P4, P5, P6), const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6) {
1051  return new _Event6<TOP, R, P1, P2, P3, P4, P5, P6>(handler, p1, p2, p3, p4, p5, p6);
1052  }
1053 
1054  // Event creating functions using type inference
1055  template<class TOP, class R, class P1, class P2, class P3, class P4, class P5>
1056  inline IEvent<TOP> * Event(R (TOP::*handler)(P1, P2, P3, P4, P5), const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5) {
1057  return new _Event5<TOP, R, P1, P2, P3, P4, P5>(handler, p1, p2, p3, p4, p5);
1058  }
1059 
1060  // Event creating functions using type inference
1061  template<class TOP, class R, class P1, class P2, class P3, class P4>
1062  inline IEvent<TOP> * Event(R (TOP::*handler)(P1, P2, P3, P4), const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4) {
1063  return new _Event4<TOP, R, P1, P2, P3, P4>(handler, p1, p2, p3, p4);
1064  }
1065 
1066  template<class TOP, class R, class P1, class P2, class P3>
1067  inline IEvent<TOP> * Event(R (TOP::*handler)(P1, P2, P3), const P1 & p1, const P2 & p2, const P3 & p3) {
1068  return new _Event3<TOP, R, P1, P2, P3>(handler, p1, p2, p3);
1069  }
1070 
1071  template<class TOP, class R, class P1, class P2>
1072  inline IEvent<TOP> * Event(R (TOP::*handler)(P1, P2), const P1 & p1, const P2 & p2) {
1073  return new _Event2<TOP, R, P1, P2>(handler, p1, p2);
1074  }
1075 
1076  template<class TOP, class R, class P1>
1077  inline IEvent<TOP> * Event(R (TOP::*handler)(P1), const P1 & p1) {
1078  return new _Event1<TOP, R, P1>(handler, p1);
1079  }
1080 
1081  template<class TOP, class R>
1082  inline IEvent<TOP> * Event(R (TOP::*handler)()) {
1083  return new _Event0<TOP, R>(handler);
1084  }
1085 
1086 } // namespace Macho
1087 
1088 
1090 // MSVC++ 8.0 does not handle qualified member template friends
1091 // http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101615
1092 // Otherwise call could happen directly in Initializer classes.
1094 public:
1095  template<class S, class P1>
1096  static inline void execute(Macho::_StateInstance & instance, const P1 & p1) {
1097  S & behaviour = static_cast<S &>(instance.specification());
1098  behaviour.init(p1);
1099  }
1100 
1101  template<class S, class P1, class P2>
1102  static inline void execute(Macho::_StateInstance & instance, const P1 & p1, const P2 & p2) {
1103  S & behaviour = static_cast<S &>(instance.specification());
1104  behaviour.init(p1, p2);
1105  }
1106 
1107  template<class S, class P1, class P2, class P3>
1108  static inline void execute(Macho::_StateInstance & instance, const P1 & p1, const P2 & p2, const P3 & p3) {
1109  S & behaviour = static_cast<S &>(instance.specification());
1110  behaviour.init(p1, p2, p3);
1111  }
1112 
1113  template<class S, class P1, class P2, class P3, class P4>
1114  static inline void execute(Macho::_StateInstance & instance, const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4) {
1115  S & behaviour = static_cast<S &>(instance.specification());
1116  behaviour.init(p1, p2, p3, p4);
1117  }
1118 
1119  template<class S, class P1, class P2, class P3, class P4, class P5>
1120  static inline void execute(Macho::_StateInstance & instance, const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5) {
1121  S & behaviour = static_cast<S &>(instance.specification());
1122  behaviour.init(p1, p2, p3, p4, p5);
1123  }
1124 
1125  template<class S, class P1, class P2, class P3, class P4, class P5, class P6>
1126  static inline void execute(Macho::_StateInstance & instance, const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6) {
1127  S & behaviour = static_cast<S &>(instance.specification());
1128  behaviour.init(p1, p2, p3, p4, p5, p6);
1129  }
1130 
1131 };
1132 
1133 
1135 namespace Macho {
1136 
1138  // Base class for state initializers.
1139  // Initializer are used to provide parameters to states.
1140  // The 'execute' method of Initializers will call a state's init method with
1141  // the data of the initializer object.
1143  public:
1144  virtual ~_Initializer() = default;
1145 
1146  // Create copy of initializer.
1147  virtual _Initializer * clone() = 0;
1148 
1149  // Deallocate object.
1150  virtual void destroy() { delete this; }
1151 
1152  virtual Key adapt(Key key) { return key; }
1153 
1154  // Initialize given state. State is new current state of a state machine.
1155  virtual void execute(_StateInstance & instance) = 0;
1156  };
1157 
1158 
1159  // Base class for Singleton initializers.
1161  // Copy of Singleton is Singleton.
1162  _Initializer * clone() override { return this; }
1163 
1164  // Singletons are never destroyed.
1165  void destroy() override {}
1166  };
1167 
1168 
1169  // Default initializer: provides no parameters, calls state's 'init' method
1170  // only.
1172  public:
1173  void execute(_StateInstance & instance) override {
1174  instance.init(false);
1175  }
1176  };
1177 
1178 
1179  // History initializer: provides no parameters, performs transition to
1180  // history of state if available.
1182  public:
1183  void execute(_StateInstance & instance) override {
1184  instance.init(true);
1185  }
1186  };
1187 
1188 
1189  // Special initializer: Helps alias impersonate as history state of given state.
1191  public:
1192  _AdaptingInitializer(const _MachineBase & machine) : myMachine(machine) {}
1193 
1194  void execute(_StateInstance & instance) override {
1195  instance.init(true);
1196  }
1197 
1198  _Initializer * clone() override {
1199  return new _AdaptingInitializer(myMachine);
1200  }
1201 
1202  Key adapt(Key key) override;
1203 
1204  protected:
1206  };
1207 
1208 
1209  // Initializers with one to six parameters.
1210  template<class S, class P1>
1211  class _Initializer1 : public _Initializer {
1212  public:
1213  _Initializer1(const P1 & p1)
1214  : myParam1(p1)
1215  {}
1216 
1217  _Initializer * clone() override {
1218  return new _Initializer1<S, P1>(myParam1);
1219  }
1220 
1221  void execute(_StateInstance & instance) override {
1222  ::_VS8_Bug_101615::execute<S, P1>(instance, myParam1);
1223  delete this;
1224  }
1225 
1227  };
1228 
1229 
1230  template<class S, class P1, class P2>
1231  class _Initializer2 : public _Initializer {
1232  public:
1233  _Initializer2(const P1 & p1, const P2 & p2)
1234  : myParam1(p1)
1235  , myParam2(p2)
1236  {}
1237 
1238  _Initializer * clone() override {
1240  }
1241 
1242  void execute(_StateInstance & instance) override {
1243  ::_VS8_Bug_101615::execute<S, P1, P2>(instance, myParam1, myParam2);
1244  delete this;
1245  }
1246 
1249  };
1250 
1251 
1252  template<class S, class P1, class P2, class P3>
1253  class _Initializer3 : public _Initializer {
1254  public:
1255  _Initializer3(const P1 & p1, const P2 & p2, const P3 & p3)
1256  : myParam1(p1)
1257  , myParam2(p2)
1258  , myParam3(p3)
1259  {}
1260 
1261  _Initializer * clone() override {
1263  }
1264 
1265  void execute(_StateInstance & instance) override {
1266  ::_VS8_Bug_101615::execute<S, P1, P2, P3>(instance, myParam1, myParam2, myParam3);
1267  delete this;
1268  }
1269 
1273  };
1274 
1275 
1276  template<class S, class P1, class P2, class P3, class P4>
1277  class _Initializer4 : public _Initializer {
1278  public:
1279  _Initializer4(const P1 & p1, const P2 & p2, const P3 & p3, P4 & p4)
1280  : myParam1(p1)
1281  , myParam2(p2)
1282  , myParam3(p3)
1283  , myParam4(p4)
1284  {}
1285 
1286  _Initializer * clone() override {
1288  }
1289 
1290  void execute(_StateInstance & instance) override {
1291  ::_VS8_Bug_101615::execute<S, P1, P2, P3, P4>(instance, myParam1, myParam2, myParam3, myParam4);
1292  delete this;
1293  }
1294 
1299  };
1300 
1301 
1302  template<class S, class P1, class P2, class P3, class P4, class P5>
1303  class _Initializer5 : public _Initializer {
1304  public:
1305  _Initializer5(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5)
1306  : myParam1(p1)
1307  , myParam2(p2)
1308  , myParam3(p3)
1309  , myParam4(p4)
1310  , myParam5(p5)
1311  {}
1312 
1313  _Initializer * clone() override {
1315  }
1316 
1317  void execute(_StateInstance & instance) override {
1318  ::_VS8_Bug_101615::execute<S, P1, P2, P3, P4, P5>(instance, myParam1, myParam2, myParam3, myParam4, myParam5);
1319  delete this;
1320  }
1321 
1327  };
1328 
1329 
1330  template<class S, class P1, class P2, class P3, class P4, class P5, class P6>
1331  class _Initializer6 : public _Initializer {
1332  public:
1333  _Initializer6(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6)
1334  : myParam1(p1)
1335  , myParam2(p2)
1336  , myParam3(p3)
1337  , myParam4(p4)
1338  , myParam5(p5)
1339  , myParam6(p6)
1340  {}
1341 
1342  _Initializer * clone() override {
1344  }
1345 
1346  void execute(_StateInstance & instance) override {
1347  _VS8_Bug_101615::execute<S, P1, P2, P3, P4, P5, P6>(instance, myParam1, myParam2, myParam3, myParam4, myParam5, myParam6);
1348  delete this;
1349  }
1350 
1357  };
1358 
1359 
1361  // Singleton initializers.
1364 
1365 
1367  // Base class for Machine objects.
1369  public:
1370  class Alias currentState() const;
1371 
1372  protected:
1374  virtual ~_MachineBase();
1375 
1376  // Transition to new state.
1377  void setState(_StateInstance & instance, _Initializer * init);
1378 
1379  // Transition to new state specified by state alias.
1380  void setState(const Alias & state);
1381 
1382  // Prepare transition to new state (performed on call to 'rattleOn').
1383  // There can be only one state transition pending (asserts otherwise)!
1384  // 'init' is an initializer for the new state.
1385  void setPendingState(_StateInstance & instance, _Initializer * init) {
1386  assert( (!myPendingState || myPendingState == &instance) &&
1387  "There is already a state transition pending!");
1388 
1389  myPendingState = &instance;
1390  myPendingInit = init;
1391  }
1392 
1393  // Provide event object to be executed on current state.
1395  assert(event);
1396  assert(!myPendingEvent && "There is already an event pending!");
1397 
1398  myPendingEvent = event;
1399  }
1400 
1401  // Performs pending state transition.
1402  void rattleOn();
1403 
1404  // Get StateInstance object for ID.
1406  return myInstances[id];
1407  }
1408 
1409  // Get StateInstance object for ID.
1410  const _StateInstance * getInstance(ID id) const {
1411  return myInstances[id];
1412  }
1413 
1414  // Starts the machine with the specified start state.
1415  void start(_StateInstance & instance);
1416  void start(const Alias & state);
1417 
1418  // Shuts machine down. Will exit any states and free all allocated
1419  // resources.
1420  void shutdown();
1421 
1422  // Allocate space for pointers to StateInstance objects.
1423  void allocate(unsigned int count);
1424 
1425  // Free all StateInstance objects.
1426  void free(unsigned int count);
1427 
1428  // const: History can be manipulated even on a const machine.
1429  void clearHistoryDeep(unsigned int count, const _StateInstance & instance) const;
1430 
1431 #ifdef MACHO_SNAPSHOTS
1432  // Create a copy of another machines StateInstance objects (includes boxes).
1433  void copy(_StateInstance ** other, unsigned int count);
1434 
1435  // Create a copy of another machines StateInstance object.
1436  _StateInstance * createClone(ID id, _StateInstance * original);
1437 #endif
1438 
1439  protected:
1440  // C++ needs something like package visibility
1441 
1442  // for getInstance
1443  template<class C, class P>
1444  friend class Link;
1445 
1446  // for setPendingEvent
1447  template<class T>
1448  friend class TopBase;
1449 
1450  // for getInstance
1451  friend class _StateSpecification;
1452 
1453  // for getInstance
1454  friend class Alias;
1455 
1456  // for getInstance
1457  friend class _AdaptingInitializer;
1458 
1459  // for setPendingState
1460  friend class _StateInstance;
1461 
1462  // for Tests
1463  friend class ::TestAccess;
1464 
1465  // Current state of Machine object.
1467 
1468  // Information about pending state transition.
1471 
1472  // Deprecated!
1473  void * myPendingBox{nullptr};
1474 
1476 
1477  // Array of StateInstance objects.
1479  };
1480 
1481 
1483  // This is the base class for state aliases. A state alias represents a
1484  // state of a machine. A transition to that state can be initiated by
1485  // giving the alias object to the 'setState' method.
1486  //
1487  // State aliases are created by the template functions 'State' further below.
1488  // Parameters can be provided to these functions that will be used to
1489  // initialize the state on transition to it.
1490  class Alias {
1491  public:
1492  Alias(Key key, bool history = false)
1493  : myStateKey(key)
1494  , myInitializer(
1495  history ?
1496  static_cast<_Initializer *>(&_theHistoryInitializer)
1497  :
1498  static_cast<_Initializer *>(&_theDefaultInitializer)
1499  )
1500  {
1501  assert(key);
1502  }
1503 
1505  : myStateKey(key)
1506  , myInitializer(init)
1507  {
1508  assert(key);
1509  }
1510 
1511  Alias(const Alias & other)
1512  : myStateKey(other.myStateKey)
1513  , myInitializer(other.myInitializer->clone())
1514  {}
1515 
1516  Alias & operator=(const Alias & other) {
1517  if (this == &other) return *this;
1518 
1520 
1521  myStateKey = other.myStateKey;
1522  myInitializer = other.myInitializer->clone();
1523 
1524  return *this;
1525  }
1526 
1529  }
1530 
1531  // Use this to test validity: zero means invalid alias.
1532  operator Key() const {
1533  return key();
1534  }
1535 
1536  bool isChild(Key k) const {
1537  return key()->childPredicate(k);
1538  }
1539 
1540  bool isParent(Key k) const {
1541  return static_cast<_KeyData *>(k)->childPredicate(key());
1542  }
1543 
1544  const char * name() const {
1545  return key()->name();
1546  }
1547 
1548  ID id() const {
1549  return key()->id;
1550  }
1551 
1552  protected:
1553  friend class _MachineBase;
1554  friend class _StateSpecification;
1555 
1556  void setState(_MachineBase & machine) const;
1557 
1558  _KeyData * key() const { return static_cast<_KeyData *>(myInitializer->adapt(myStateKey)); }
1559 
1560  protected:
1561  // Key of specified state.
1563 
1564  // Initializer of this alias.
1566  };
1567 
1568  // Deprecated!
1570 
1571 
1572  // Create alias with 0 to 6 parameters.
1573  template<class S>
1575  return Alias(S::key());
1576  }
1577 
1578  template<class S, class P1>
1579  Alias State(const P1 & p1) {
1580  return Alias(S::key(), new _Initializer1<S, P1>(p1));
1581  }
1582 
1583  template<class S, class P1, class P2>
1584  Alias State(const P1 & p1, const P2 & p2) {
1585  return Alias(S::key(), new _Initializer2<S, P1, P2>(p1, p2));
1586  }
1587 
1588  template<class S, class P1, class P2, class P3>
1589  Alias State(const P1 & p1, const P2 & p2, const P3 & p3) {
1590  return Alias(S::key(), new _Initializer3<S, P1, P2, P3>(p1, p2, p3));
1591  }
1592 
1593  template<class S, class P1, class P2, class P3, class P4>
1594  Alias State(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4) {
1595  return Alias(S::key(), new _Initializer4<S, P1, P2, P3, P4>(p1, p2, p3, p4));
1596  }
1597 
1598  template<class S, class P1, class P2, class P3, class P4, class P5>
1599  Alias State(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5) {
1600  return Alias(S::key(), new _Initializer5<S, P1, P2, P3, P4, P5>(p1, p2, p3, p4, p5));
1601  }
1602 
1603  template<class S, class P1, class P2, class P3, class P4, class P5, class P6>
1604  Alias State(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6) {
1605  return Alias(S::key(), new _Initializer6<S, P1, P2, P3, P4, P5, P6>(p1, p2, p3, p4, p5, p6));
1606  }
1607 
1608  // Create alias for state's history: not the current history state, but
1609  // really the history of a state. This means that the alias may point to
1610  // different states during its life. Needs a machine instance to take history from.
1611  template<class S>
1612  Alias StateHistory(const _MachineBase & machine) {
1613  return Alias(S::key(), new _AdaptingInitializer(machine));
1614  }
1615 
1616 
1618  // Snapshot of a machine object.
1619  // Saves the state of a machine object at a specific point in time to be restored
1620  // later (can be used to achieve something like backtracking).
1621  // Includes boxes of current state and persistent boxes.
1622  // Assign a snapshot to a machine (operator=) to restore state.
1623  // Note that no exit/entry actions of the overwritten machine state are performed!
1624  // Box destructors however are executed!
1625 #ifdef MACHO_SNAPSHOTS
1626  template<class TOP>
1627  class Snapshot : public _MachineBase {
1628  public:
1629  Snapshot(Machine<TOP> & machine);
1630 
1631  ~Snapshot() {
1632  free(Machine<TOP>::theStateCount);
1633  }
1634 
1635  private:
1636  friend class Machine<TOP>;
1637 
1638  Snapshot(const Snapshot<TOP> & other);
1639  Snapshot & operator=(const Snapshot<TOP> & other);
1640  };
1641 #endif
1642 
1643 
1645  // A Machine object maintains a current state.
1646  // The state can be any substate of template parameter TOP.
1647  // TOP is the Machine's top most and inital state. TOP must be defined by
1648  // the macro TOPSTATE. Event processing is done by calling methods (event
1649  // handlers) on the current state.
1650  // This is realized by defining an arrow ('->') operator on Machine,
1651  // forwarding to the interface of TOP.
1652  // Every possible event handler to be called must therefore appear in the
1653  // interface of TOP. Events are dispatched by using this operator on a
1654  // Machine object (e.g. 'machine->event()').
1655  template<class TOP>
1656  class Machine : public _MachineBase {
1657  public:
1658 
1659  // This class performs an action in its destructor after an event
1660  // handler has finished. Comparable to an After Advice in AOP.
1661  struct AfterAdvice {
1662  AfterAdvice(Machine<TOP> & m) : myMachine(m) {}
1663 
1664  // Event handler has finished execution. Execute pending transitions now.
1665  ~AfterAdvice() { myMachine.rattleOn(); }
1666 
1667  // this arrow operator finally dispatches to TOP interface.
1668  TOP * operator->() {
1669  return static_cast<TOP *>(& (myMachine.myCurrentState->specification()) );
1670  }
1671 
1672  private:
1673  Machine<TOP> & myMachine;
1674  };
1675 
1677  // Compile time check: TOP must directly derive from TopBase<TOP>
1678  using MustDeriveFromTopBase = typename CheckSameType<TopBase<TOP>, typename TOP::SUPER>::Check;
1679  // suppress unused-typdefs warnig
1680  static_assert(static_cast<MustDeriveFromTopBase*>(nullptr)==nullptr, "dummy");
1681 
1682  allocate(theStateCount);
1683  start(TOP::_getInstance(*this));
1684  }
1685 
1686  // Initialize with a state alias object to have machine go to a state
1687  // other than TOP on startup.
1688  Machine(const Alias & state) {
1689  // Compile time check: TOP must directly derive from TopBase<TOP>
1690  using MustDeriveFromTopBase = typename CheckSameType<TopBase<TOP>, typename TOP::SUPER>::Check;
1691  // suppress unused-typdefs warnig
1692  static_assert(static_cast<MustDeriveFromTopBase*>(nullptr)==nullptr, "dummy");
1693 
1694  allocate(theStateCount);
1695  start(state);
1696  }
1697 
1698 #ifdef MACHO_SNAPSHOTS
1699  // Create machine from a snapshot.
1700  Machine(const Snapshot<TOP> & snapshot) {
1701  allocate(theStateCount);
1702  copy(snapshot.myInstances, theStateCount);
1703  }
1704 
1705  // Overwrite current machine state by snapshot.
1706  Machine<TOP> & operator=(const Snapshot<TOP> & snapshot) {
1707  assert(!myPendingState);
1708  assert(!myPendingEvent);
1709 
1711 
1712  free(theStateCount);
1713  copy(snapshot.myInstances, theStateCount);
1714 
1715  // Go to Root state first
1717 
1718  // Then set previous current state
1719  _StateInstance * current = getInstance(snapshot.myCurrentState->id());
1720  current->restore(*current);
1721  rattleOn();
1722 
1723  return *this;
1724  }
1725 #endif
1726 
1727  ~Machine() override {
1729  free(theStateCount);
1730  }
1731 
1732  // Don't return pointer to interface right now: we need to know when the
1733  // event handler has finished; return an AfterAdvice object instead:
1734  // it allows us to perform actions after access.
1736  assert(myCurrentState);
1737  assert(!myPendingState);
1738 
1739  // We need to know when the event handler has finished.
1740  return AfterAdvice(*this);
1741  }
1742 
1743  // Dispatch an event object to machine.
1744  void dispatch(IEvent<TOP> * event, bool destroy = true) {
1745  assert(event);
1746 
1747  event->dispatch(*myCurrentState);
1748  if (destroy) delete event;
1749 
1750  rattleOn();
1751  }
1752 
1753  // Allow (const) access to top state's box (for state data extraction).
1754  const typename TOP::Box & box() const {
1755  assert(myCurrentState);
1756  return static_cast<TOP &>(myCurrentState->specification()).TOP::box();
1757  }
1758 
1759  private:
1760  template<class C, class P>
1761  friend class Link;
1762 
1763  private:
1764  Machine(const Machine<TOP> & other) = delete;
1765  Machine<TOP> & operator=(const Machine<TOP> & other) = delete;
1766 
1767 #ifdef MACHO_SNAPSHOTS
1768  friend class Snapshot<TOP>;
1769 #endif
1770 
1771  template<class T> friend class StateID;
1772 
1773  // Next free identifier for StateInstance objects.
1774  static ID theStateCount;
1775  };
1776 
1777  // Root is always there and has ID 0, so start from 1
1778  template<class TOP>
1780 
1781  // Each state has a unique ID number.
1782  // The identifiers are consecutive integers starting from zero,
1783  // which allows use as index into a vector for fast access.
1784  // 'Root' always has zero as id.
1785  //template<class S>
1786  //const ID StateID<S>::value = Machine<typename S::TOP>::theStateCount++;
1787 
1788 
1790  // Implementation for StateSpecification
1791 
1792  // Initiate state transition with 0 to six parameters.
1793  template<class S>
1795  _MachineBase & m = _myStateInstance.machine();
1796  _StateInstance & instance = S::_getInstance(m);
1798  }
1799 
1800  template<class S, class P1>
1801  inline void _StateSpecification::setState(const P1 & p1) {
1802  _MachineBase & m = _myStateInstance.machine();
1803  _StateInstance & instance = S::_getInstance(m);
1804  m.setPendingState(instance, new _Initializer1<S, P1>(p1));
1805  }
1806 
1807  template<class S, class P1, class P2>
1808  inline void _StateSpecification::setState(const P1 & p1, const P2 & p2) {
1809  _MachineBase & m = _myStateInstance.machine();
1810  _StateInstance & instance = S::_getInstance(m);
1811  m.setPendingState(instance, new _Initializer2<S, P1, P2>(p1, p2));
1812  }
1813 
1814  template<class S, class P1, class P2, class P3>
1815  inline void _StateSpecification::setState(const P1 & p1, const P2 & p2, const P3 & p3) {
1816  _MachineBase & m = _myStateInstance.machine();
1817  _StateInstance & instance = S::_getInstance(m);
1818  m.setPendingState(instance, new _Initializer3<S, P1, P2, P3>(p1, p2, p3));
1819  }
1820 
1821  template<class S, class P1, class P2, class P3, class P4>
1822  inline void _StateSpecification::setState(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4) {
1823  _MachineBase & m = _myStateInstance.machine();
1824  _StateInstance & instance = S::_getInstance(m);
1825  m.setPendingState(instance, new _Initializer4<S, P1, P2, P3, P4>(p1, p2, p3, p4));
1826  }
1827 
1828  template<class S, class P1, class P2, class P3, class P4, class P5>
1829  inline void _StateSpecification::setState(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5) {
1830  _MachineBase & m = _myStateInstance.machine();
1831  _StateInstance & instance = S::_getInstance(m);
1832  m.setPendingState(instance, new _Initializer5<S, P1, P2, P3, P4, P5>(p1, p2, p3, p4, p5));
1833  }
1834 
1835  template<class S, class P1, class P2, class P3, class P4, class P5, class P6>
1836  inline void _StateSpecification::setState(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6) {
1837  _MachineBase & m = _myStateInstance.machine();
1838  _StateInstance & instance = S::_getInstance(m);
1839  m.setPendingState(instance, new _Initializer6<S, P1, P2, P3, P4, P5, P6>(p1, p2, p3, p4, p5, p6));
1840  }
1841 
1842  // Initiate state transition to a state's history.
1843  template<class S>
1845  _MachineBase & m = _myStateInstance.machine();
1846  _StateInstance & instance = S::_getInstance(m);
1848  }
1849 
1850  // Deprecated!
1851  template<class S>
1852  inline void _StateSpecification::setStateBox(typename S::Box * box) {
1853  _MachineBase & m = _myStateInstance.machine();
1854  _StateInstance & instance = S::_getInstance(m);
1855  m.myPendingBox = box;
1857  }
1858 
1859  // Deprecated!
1860  template<class S>
1861  inline void _StateSpecification::setStateDirect(typename S::Box * box) {
1862  _MachineBase & m = _myStateInstance.machine();
1863  _StateInstance & instance = S::_getInstance(m);
1864  m.myPendingBox = box;
1866  }
1867 
1868 
1870  // Implementation for TopBase
1871  template<class T>
1872  inline void TopBase<T>::dispatch(IEvent<TOP> * event) {
1873  assert(event);
1874  _myStateInstance.machine().setPendingEvent(event);
1875  }
1876 
1877  template<class T>
1878  // Returns current state machine instance.
1879  inline const Machine<T> & TopBase<T>::machine() {
1880  return static_cast<Machine<TOP> &>(this->_myStateInstance.machine());
1881  }
1882 
1883 
1885  // Implementation for Link
1886  template<class C, class P>
1888  : P(P::_getInstance(instance.machine()))
1889  // Can't initialize _myStateInstance with _getInstance,
1890  // because this would result in an endless loop (at least for first call)
1891  , _myStateInstance(instance)
1892  {}
1893 
1894  // This method keeps '_myStateInstance' attribute private.
1895  template<class C, class P>
1896  inline void * Link<C, P>::_box() {
1897  return _myStateInstance.box();
1898  }
1899 
1900  // Default behaviour: free box on exit.
1901  template<class C, class P>
1902  inline void Link<C, P>::_deleteBox(_StateInstance & instance) {
1903  instance.deleteBox();
1904  }
1905 
1906  // Create StateInstance object of state.
1907  template<class C, class P>
1908  /* static */ inline _StateInstance & Link<C, P>::_getInstance(_MachineBase & machine) {
1909  // Look first in machine for existing StateInstance.
1910  _StateInstance * & instance = machine.getInstance(StateID<C>::value);
1911  if (instance == nullptr)
1912  // Will create parent StateInstance object if not already created.
1913  instance = new _SubstateInstance<C>(machine, &P::_getInstance(machine));
1914 
1915  return *instance;
1916  }
1917 
1918  template<class C, class P>
1919  /* static */ inline bool Link<C, P>::isCurrent(const _MachineBase & machine) {
1920  return machine.currentState().isChild(key());
1921  }
1922 
1923  // Deprecated!
1924  template<class C, class P>
1925  /* static */ inline bool Link<C, P>::isCurrentDirect(const _MachineBase & machine) {
1926  return key() == machine.currentState();
1927  }
1928 
1929  template<class C, class P>
1930  /* static */ void Link<C, P>::clearHistory(const _MachineBase & machine) {
1931  const _StateInstance * instance = machine.getInstance(StateID<C>::value);
1932  if (instance != nullptr)
1933  instance->setHistory(nullptr);
1934  }
1935 
1936  template<class C, class P>
1937  /* static */ void Link<C, P>::clearHistoryDeep(const _MachineBase & machine) {
1938  const _StateInstance * instance = machine.getInstance(StateID<C>::value);
1939  if (instance != nullptr)
1940  machine.clearHistoryDeep(Machine<TOP>::theStateCount, *instance);
1941  }
1942 
1943  template<class C, class P>
1944  /* static */ Alias Link<C, P>::history(const _MachineBase & machine) {
1945  const _StateInstance * instance = machine.getInstance(StateID<C>::value);
1946  _StateInstance * history = nullptr;
1947 
1948  if (instance != nullptr)
1949  history = instance->history();
1950 
1951  return history != nullptr ? history->key() : key();
1952  }
1953 
1954  template<class C, class P>
1955  /* static */ inline Key Link<C, P>::key() {
1956  static _KeyData k = { _getInstance, isChild, C::_state_name, StateID<C>::value };
1957  return &k;
1958  }
1959 
1960  template<class C, class P>
1961  /* static */ inline Alias Link<C, P>::alias() {
1962  return Alias(key());
1963  }
1964 
1965 
1967  // Implementation for Snapshot
1968 #ifdef MACHO_SNAPSHOTS
1969  template<class TOP>
1970  Snapshot<TOP>::Snapshot(Machine<TOP> & machine) {
1971  assert(!machine.myPendingState);
1972  assert(!machine.myPendingEvent);
1973  assert(machine.myCurrentState);
1974 
1975  allocate(Machine<TOP>::theStateCount);
1977 
1978  myCurrentState = getInstance(machine.myCurrentState->id());
1979  }
1980 #endif
1981 
1982 } // namespace Macho
1983 
1984 #if defined(__clang__)
1985 #if defined(_WIN32) || defined(_WIN64)
1986 #pragma clang diagnostic pop
1987 #endif
1988 #endif
1989 
1990 
1991 #endif // MACHO_HPP
Definition: Macho.h:1490
Key myStateKey
Definition: Macho.h:1562
bool isChild(Key k) const
Definition: Macho.h:1536
~Alias()
Definition: Macho.h:1527
Alias(Key key, _Initializer *init)
Definition: Macho.h:1504
_Initializer * myInitializer
Definition: Macho.h:1565
const char * name() const
Definition: Macho.h:1544
void setState(_MachineBase &machine) const
Alias(const Alias &other)
Definition: Macho.h:1511
ID id() const
Definition: Macho.h:1548
_KeyData * key() const
Definition: Macho.h:1558
bool isParent(Key k) const
Definition: Macho.h:1540
Alias(Key key, bool history=false)
Definition: Macho.h:1492
Alias & operator=(const Alias &other)
Definition: Macho.h:1516
Definition: Macho.h:860
Definition: Macho.h:1656
Machine()
Definition: Macho.h:1676
~Machine() override
Definition: Macho.h:1727
void dispatch(IEvent< TOP > *event, bool destroy=true)
Definition: Macho.h:1744
AfterAdvice operator->()
Definition: Macho.h:1735
const TOP::Box & box() const
Definition: Macho.h:1754
Machine(const Alias &state)
Definition: Macho.h:1688
Definition: Macho.h:626
static const ID value
Definition: Macho.h:628
Definition: Macho.h:514
T TOP
Definition: Macho.h:517
TopBase(_StateInstance &instance)
Definition: Macho.h:520
void dispatch(IEvent< TOP > *event)
Definition: Macho.h:1872
const Machine< TOP > & machine()
Definition: Macho.h:1879
Definition: Macho.h:1190
_Initializer * clone() override
Definition: Macho.h:1198
const _MachineBase & myMachine
Definition: Macho.h:1205
_AdaptingInitializer(const _MachineBase &machine)
Definition: Macho.h:1192
void execute(_StateInstance &instance) override
Definition: Macho.h:1194
Key adapt(Key key) override
Definition: Macho.h:1171
void execute(_StateInstance &instance) override
Definition: Macho.h:1173
Definition: Macho.h:319
static _EmptyBox theEmptyBox
Definition: Macho.h:321
Definition: Macho.h:1030
void dispatch(_StateInstance &instance) override
Definition: Macho.h:1039
_Event0(Signature handler)
Definition: Macho.h:1034
Signature myHandler
Definition: Macho.h:1044
Definition: Macho.h:1008
Signature myHandler
Definition: Macho.h:1023
_Event1(Signature handler, const P1 &p1)
Definition: Macho.h:1012
P1 myParam1
Definition: Macho.h:1024
void dispatch(_StateInstance &instance) override
Definition: Macho.h:1018
Definition: Macho.h:984
P1 myParam1
Definition: Macho.h:1001
P2 myParam2
Definition: Macho.h:1002
_Event2(Signature handler, const P1 &p1, const P2 &p2)
Definition: Macho.h:988
Signature myHandler
Definition: Macho.h:1000
void dispatch(_StateInstance &instance)
Definition: Macho.h:995
Definition: Macho.h:958
P3 myParam3
Definition: Macho.h:978
_Event3(Signature handler, const P1 &p1, const P2 &p2, const P3 &p3)
Definition: Macho.h:962
P1 myParam1
Definition: Macho.h:976
Signature myHandler
Definition: Macho.h:975
void dispatch(_StateInstance &instance)
Definition: Macho.h:970
P2 myParam2
Definition: Macho.h:977
Definition: Macho.h:930
void dispatch(_StateInstance &instance)
Definition: Macho.h:943
_Event4(Signature handler, const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4)
Definition: Macho.h:934
P4 myParam4
Definition: Macho.h:952
P2 myParam2
Definition: Macho.h:950
P1 myParam1
Definition: Macho.h:949
Signature myHandler
Definition: Macho.h:948
P3 myParam3
Definition: Macho.h:951
Definition: Macho.h:900
P1 myParam1
Definition: Macho.h:920
P2 myParam2
Definition: Macho.h:921
P4 myParam4
Definition: Macho.h:923
Signature myHandler
Definition: Macho.h:919
_Event5(Signature handler, const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5)
Definition: Macho.h:904
P5 myParam5
Definition: Macho.h:924
P3 myParam3
Definition: Macho.h:922
void dispatch(_StateInstance &instance)
Definition: Macho.h:914
Definition: Macho.h:868
void dispatch(_StateInstance &instance)
Definition: Macho.h:883
_Event6(Signature handler, const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5, const P6 &p6)
Definition: Macho.h:872
P3 myParam3
Definition: Macho.h:891
P4 myParam4
Definition: Macho.h:892
P1 myParam1
Definition: Macho.h:889
P6 myParam6
Definition: Macho.h:894
Signature myHandler
Definition: Macho.h:888
P5 myParam5
Definition: Macho.h:893
P2 myParam2
Definition: Macho.h:890
Definition: Macho.h:1181
void execute(_StateInstance &instance) override
Definition: Macho.h:1183
Definition: Macho.h:851
virtual void dispatch(_StateInstance &)=0
virtual ~_IEventBase()=default
Definition: Macho.h:1211
void execute(_StateInstance &instance) override
Definition: Macho.h:1221
P1 myParam1
Definition: Macho.h:1226
_Initializer * clone() override
Definition: Macho.h:1217
_Initializer1(const P1 &p1)
Definition: Macho.h:1213
Definition: Macho.h:1231
_Initializer * clone() override
Definition: Macho.h:1238
_Initializer2(const P1 &p1, const P2 &p2)
Definition: Macho.h:1233
void execute(_StateInstance &instance) override
Definition: Macho.h:1242
P1 myParam1
Definition: Macho.h:1247
P2 myParam2
Definition: Macho.h:1248
Definition: Macho.h:1253
P1 myParam1
Definition: Macho.h:1270
P2 myParam2
Definition: Macho.h:1271
_Initializer * clone() override
Definition: Macho.h:1261
_Initializer3(const P1 &p1, const P2 &p2, const P3 &p3)
Definition: Macho.h:1255
void execute(_StateInstance &instance) override
Definition: Macho.h:1265
P3 myParam3
Definition: Macho.h:1272
Definition: Macho.h:1277
_Initializer * clone() override
Definition: Macho.h:1286
P3 myParam3
Definition: Macho.h:1297
_Initializer4(const P1 &p1, const P2 &p2, const P3 &p3, P4 &p4)
Definition: Macho.h:1279
P1 myParam1
Definition: Macho.h:1295
P2 myParam2
Definition: Macho.h:1296
P4 myParam4
Definition: Macho.h:1298
void execute(_StateInstance &instance) override
Definition: Macho.h:1290
Definition: Macho.h:1303
P3 myParam3
Definition: Macho.h:1324
P4 myParam4
Definition: Macho.h:1325
_Initializer5(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5)
Definition: Macho.h:1305
P5 myParam5
Definition: Macho.h:1326
void execute(_StateInstance &instance) override
Definition: Macho.h:1317
_Initializer * clone() override
Definition: Macho.h:1313
P1 myParam1
Definition: Macho.h:1322
P2 myParam2
Definition: Macho.h:1323
Definition: Macho.h:1331
P1 myParam1
Definition: Macho.h:1351
_Initializer * clone() override
Definition: Macho.h:1342
P2 myParam2
Definition: Macho.h:1352
P6 myParam6
Definition: Macho.h:1356
P4 myParam4
Definition: Macho.h:1354
_Initializer6(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5, const P6 &p6)
Definition: Macho.h:1333
void execute(_StateInstance &instance) override
Definition: Macho.h:1346
P3 myParam3
Definition: Macho.h:1353
P5 myParam5
Definition: Macho.h:1355
Definition: Macho.h:1142
virtual ~_Initializer()=default
virtual Key adapt(Key key)
Definition: Macho.h:1152
virtual void execute(_StateInstance &instance)=0
virtual _Initializer * clone()=0
virtual void destroy()
Definition: Macho.h:1150
Definition: Macho.h:1368
_StateInstance * myPendingState
Definition: Macho.h:1469
void allocate(unsigned int count)
void * myPendingBox
Definition: Macho.h:1473
void setState(_StateInstance &instance, _Initializer *init)
friend class _StateInstance
Definition: Macho.h:1460
class Alias currentState() const
void start(const Alias &state)
_Initializer * myPendingInit
Definition: Macho.h:1470
void setPendingEvent(_IEventBase *event)
Definition: Macho.h:1394
virtual ~_MachineBase()
_StateInstance *& getInstance(ID id)
Definition: Macho.h:1405
void start(_StateInstance &instance)
void setState(const Alias &state)
_StateInstance * myCurrentState
Definition: Macho.h:1466
const _StateInstance * getInstance(ID id) const
Definition: Macho.h:1410
void free(unsigned int count)
void setPendingState(_StateInstance &instance, _Initializer *init)
Definition: Macho.h:1385
_IEventBase * myPendingEvent
Definition: Macho.h:1475
_StateInstance ** myInstances
Definition: Macho.h:1478
void clearHistoryDeep(unsigned int count, const _StateInstance &instance) const
Definition: Macho.h:750
const char * name() override
Definition: Macho.h:776
_RootInstance(_MachineBase &machine, _StateInstance *parent)
Definition: Macho.h:754
_StateInstance * create(_MachineBase &machine, _StateInstance *parent) override
Definition: Macho.h:779
void deleteBox() override
Definition: Macho.h:771
ID id() override
Definition: Macho.h:761
friend class _StateSpecification
Definition: Macho.h:752
Key key() override
Definition: Macho.h:765
void createBox() override
Definition: Macho.h:770
Definition: Macho.h:637
void setBox(void *box)
Definition: Macho.h:698
void exit(_StateInstance &next)
virtual void deleteBox()=0
void * myBoxPlace
Definition: Macho.h:744
void setHistory(_StateInstance *history) const
Definition: Macho.h:730
void shutdown()
Definition: Macho.h:674
_MachineBase & machine()
Definition: Macho.h:725
void entry(_StateInstance &previous, bool first=true)
void setHistorySuper(_StateInstance &deep)
Definition: Macho.h:660
_StateInstance * myHistory
Definition: Macho.h:741
bool isChild(const _StateInstance &instance)
Definition: Macho.h:711
virtual const char * name()=0
void init(bool history)
_MachineBase & myMachine
Definition: Macho.h:739
virtual _StateInstance * create(_MachineBase &machine, _StateInstance *parent)=0
_StateInstance(_MachineBase &machine, _StateInstance *parent)
void restore(_StateInstance &instance)
Definition: Macho.h:678
void * box()
Definition: Macho.h:720
virtual Key key()=0
void * myBox
Definition: Macho.h:743
virtual void createBox()=0
void saveHistory(_StateInstance &shallow, _StateInstance &deep)
Definition: Macho.h:654
_StateInstance * myParent
Definition: Macho.h:742
_StateSpecification * mySpecification
Definition: Macho.h:740
virtual ID id()=0
_StateInstance * history() const
Definition: Macho.h:734
_StateSpecification & specification()
Definition: Macho.h:715
Definition: Macho.h:394
static bool isChild(Key)
Definition: Macho.h:398
friend class _StateInstance
Definition: Macho.h:493
void setStateDirect(typename S::Box *box=0)
Definition: Macho.h:1861
virtual void _setHistorySuper(_StateInstance &, _StateInstance &)
Definition: Macho.h:466
void setStateBox(typename S::Box *box=0)
Definition: Macho.h:1852
void setState(const class Alias &state)
void setState(_StateInstance &current)
void setStateHistory()
Definition: Macho.h:1844
virtual void _restore(_StateInstance &current)
virtual ~_StateSpecification()=default
void setState()
Definition: Macho.h:1794
_StateSpecification(_StateInstance &instance)
Definition: Macho.h:403
Definition: Macho.h:1160
Definition: Macho.h:790
Key key() override
Definition: Macho.h:816
const char * name() override
Definition: Macho.h:810
typename S::Box Box
Definition: Macho.h:803
ID id() override
Definition: Macho.h:812
_StateInstance * create(_MachineBase &machine, _StateInstance *parent) override
Definition: Macho.h:821
void deleteBox() override
Definition: Macho.h:830
_SubstateInstance(_MachineBase &machine, _StateInstance *parent)
Definition: Macho.h:795
void createBox() override
Definition: Macho.h:825
~_SubstateInstance() override
Definition: Macho.h:805
Definition: Macho.h:1093
static void execute(Macho::_StateInstance &instance, const P1 &p1)
Definition: Macho.h:1096
static void execute(Macho::_StateInstance &instance, const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5, const P6 &p6)
Definition: Macho.h:1126
static void execute(Macho::_StateInstance &instance, const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4)
Definition: Macho.h:1114
static void execute(Macho::_StateInstance &instance, const P1 &p1, const P2 &p2)
Definition: Macho.h:1102
static void execute(Macho::_StateInstance &instance, const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5)
Definition: Macho.h:1120
static void execute(Macho::_StateInstance &instance, const P1 &p1, const P2 &p2, const P3 &p3)
Definition: Macho.h:1108
Definition: Macho.h:297
void _deleteBox< _EmptyBox >(void *&box, void *&place)
static _HistoryInitializer _theHistoryInitializer
Definition: Macho.h:1363
void * Key
Definition: Macho.h:310
IEvent< TOP > * Event(R(TOP::*handler)(P1, P2, P3, P4, P5, P6), const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5, const P6 &p6)
Definition: Macho.h:1050
Alias StateHistory(const _MachineBase &machine)
Definition: Macho.h:1612
void * _createBox< _EmptyBox >(void *&place)
static _DefaultInitializer _theDefaultInitializer
Definition: Macho.h:1362
Alias State()
Definition: Macho.h:1574
void _deleteBox(void *&box, void *&place)
Definition: Macho.h:341
void * _createBox(void *&place)
Definition: Macho.h:328
unsigned int ID
Definition: Macho.h:314
bool Check
Definition: Macho.h:227
Definition: Macho.h:222
Definition: Macho.h:1661
TOP * operator->()
Definition: Macho.h:1668
~AfterAdvice()
Definition: Macho.h:1665
AfterAdvice(Machine< TOP > &m)
Definition: Macho.h:1662
Definition: Macho.h:374
const NameFn name
Definition: Macho.h:385
const Generator instanceGenerator
Definition: Macho.h:380
const char *(*)() NameFn
Definition: Macho.h:377
bool(*)(Key) Predicate
Definition: Macho.h:376
_StateInstance &(*)(_MachineBase &) Generator
Definition: Macho.h:375
const ID id
Definition: Macho.h:386
const Predicate childPredicate
Definition: Macho.h:383