smach.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*! ========================================================================
  2. ** Extended Template and Library Test Suite
  3. ** Angle Class Test
  4. **
  5. ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
  6. **
  7. ** This package is free software; you can redistribute it and/or
  8. ** modify it under the terms of the GNU General Public License as
  9. ** published by the Free Software Foundation; either version 2 of
  10. ** the License, or (at your option) any later version.
  11. **
  12. ** This package is distributed in the hope that it will be useful,
  13. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. ** General Public License for more details.
  16. **
  17. ** === N O T E S ===========================================================
  18. **
  19. ** ========================================================================= */
  20. #include <ETL/smach>
  21. #include <cstdio>
  22. using namespace std;
  23. using namespace etl;
  24. enum EventKey {
  25. EVENT_1,
  26. EVENT_2,
  27. EVENT_3,
  28. EVENT_4
  29. };
  30. struct MachineContext {
  31. smach<MachineContext, EventKey> machine;
  32. MachineContext(): machine(this)
  33. {
  34. }
  35. };
  36. typedef smach<MachineContext, EventKey> Smach;
  37. class Event1 : public Smach::event
  38. {
  39. public:
  40. Event1(): Smach::event(EVENT_1) { }
  41. };
  42. class DefaultStateContext
  43. {
  44. MachineContext *context;
  45. public:
  46. DefaultStateContext(MachineContext *context): context(context)
  47. {
  48. printf("Entered Default State\n");
  49. }
  50. ~DefaultStateContext()
  51. {
  52. printf("Left Default State\n");
  53. }
  54. Smach::event_result event1_handler(const Smach::event& x __attribute__((unused)))
  55. {
  56. printf("DEFAULT STATE: Received Event 1\n");
  57. return Smach::RESULT_ACCEPT;
  58. }
  59. };
  60. class DefaultState : public Smach::state<DefaultStateContext>
  61. {
  62. public:
  63. DefaultState(): Smach::state<DefaultStateContext>("DefaultState")
  64. {
  65. insert(event_def(EVENT_1, &DefaultStateContext::event1_handler));
  66. }
  67. } default_state;
  68. class State1Context
  69. {
  70. MachineContext *context;
  71. public:
  72. State1Context(MachineContext *context): context(context)
  73. {
  74. printf("Entered State 1\n");
  75. }
  76. ~State1Context()
  77. {
  78. printf("Left State 1\n");
  79. }
  80. Smach::event_result event1_handler(const Smach::event& x __attribute__((unused)))
  81. {
  82. printf("STATE1: Received Event 1\n");
  83. return Smach::RESULT_OK;
  84. }
  85. Smach::event_result event3_handler(const Smach::event& x);
  86. };
  87. class State1 : public Smach::state<State1Context>
  88. {
  89. public:
  90. State1(): Smach::state<State1Context>("State1")
  91. {
  92. insert(event_def(EVENT_1, &State1Context::event1_handler));
  93. insert(event_def(EVENT_3, &State1Context::event3_handler));
  94. }
  95. } state_1;
  96. class State2Context
  97. {
  98. MachineContext *context;
  99. public:
  100. State2Context(MachineContext *context): context(context)
  101. {
  102. printf("Entered State 2\n");
  103. }
  104. ~State2Context()
  105. {
  106. printf("Left State 2\n");
  107. }
  108. Smach::event_result event1_handler(const Smach::event& x __attribute__((unused)))
  109. {
  110. printf("STATE2: Received Event 1\n");
  111. return Smach::RESULT_OK;
  112. }
  113. Smach::event_result event2_handler(const Smach::event& x __attribute__((unused)))
  114. {
  115. printf("STATE2: Received Event 2\n");
  116. return Smach::RESULT_OK;
  117. }
  118. Smach::event_result event3_handler(const Smach::event& x __attribute__((unused)))
  119. {
  120. printf("STATE2: Received Event 3\n");
  121. return Smach::RESULT_OK;
  122. }
  123. };
  124. class State2 : public Smach::state<State2Context>
  125. {
  126. public:
  127. State2(): Smach::state<State2Context>("State2")
  128. {
  129. insert(event_def(EVENT_1, &State2Context::event1_handler));
  130. insert(event_def(EVENT_2, &State2Context::event2_handler));
  131. insert(event_def(EVENT_3, &State2Context::event3_handler));
  132. }
  133. } state_2;
  134. Smach::event_result
  135. State1Context::event3_handler(const Smach::event& x __attribute__((unused)))
  136. {
  137. printf("STATE1: Received Event 3, throwing state to change to...\n");
  138. throw &state_2;
  139. }
  140. int main()
  141. {
  142. int error = 0;
  143. MachineContext context;
  144. try {
  145. Smach& state_machine(context.machine);
  146. state_machine.set_default_state(&default_state);
  147. state_machine.enter(&state_1);
  148. state_machine.process_event(Event1());
  149. state_machine.process_event(EVENT_1);
  150. state_machine.process_event(EVENT_2);
  151. state_machine.process_event(EVENT_3);
  152. state_machine.process_event(Event1());
  153. state_machine.process_event(EVENT_1);
  154. state_machine.process_event(EVENT_2);
  155. state_machine.process_event(EVENT_3);
  156. state_machine.process_event(Event1());
  157. state_machine.process_event(EVENT_1);
  158. state_machine.process_event(EVENT_2);
  159. state_machine.process_event(EVENT_3);
  160. } catch (...) {
  161. printf("Uncaught exception\n");
  162. error++;
  163. }
  164. return error;
  165. }