Stefan Scholz / ETL
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers fsm.h Source File

fsm.h

00001 /******************************************************************************
00002 The MIT License(MIT)
00003 
00004 Embedded Template Library.
00005 https://github.com/ETLCPP/etl
00006 https://www.etlcpp.com
00007 
00008 Copyright(c) 2017 jwellbelove
00009 
00010 Permission is hereby granted, free of charge, to any person obtaining a copy
00011 of this software and associated documentation files(the "Software"), to deal
00012 in the Software without restriction, including without limitation the rights
00013 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
00014 copies of the Software, and to permit persons to whom the Software is
00015 furnished to do so, subject to the following conditions :
00016 
00017 The above copyright notice and this permission notice shall be included in all
00018 copies or substantial portions of the Software.
00019 
00020 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00021 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00022 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
00023 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00024 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00025 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00026 SOFTWARE.
00027 ******************************************************************************/
00028 
00029 #if 0
00030 #error THIS HEADER IS A GENERATOR. DO NOT INCLUDE.
00031 #endif
00032 
00033 //***************************************************************************
00034 // This file has been auto generated. Do not edit this file.
00035 //***************************************************************************
00036 
00037 //***************************************************************************
00038 // To generate to header file, run this at the command line.
00039 // Note: You will need Python and COG installed.
00040 //
00041 // python -m cogapp -d -e -ofsm.h -DHandlers=<n> fsm_generator.h
00042 // Where <n> is the number of messages to support.
00043 //
00044 // e.g.
00045 // To generate handlers for up to 16 events...
00046 // python -m cogapp -d -e -ofsm.h -DHandlers=16 fsm_generator.h
00047 //
00048 // See generate.bat
00049 //***************************************************************************
00050 
00051 #ifndef __ETL_FSM__
00052 #define __ETL_FSM__
00053 
00054 #include <stdint.h>
00055 
00056 #include "platform.h "
00057 #include "array.h "
00058 #include "nullptr.h "
00059 #include "error_handler.h "
00060 #include "exception.h "
00061 #include "user_type.h "
00062 #include "message_router.h"
00063 #include "integral_limits.h "
00064 #include "largest.h "
00065 
00066 #undef ETL_FILE
00067 #define ETL_FILE "34"
00068 
00069 #ifdef ETL_COMPILER_MICROSOFT
00070 #undef max
00071 #endif
00072 
00073 namespace etl
00074 {
00075   class fsm;
00076 
00077   /// Allow alternative type for state id.
00078 #if !defined(ETL_FSM_STATE_ID_TYPE)
00079     typedef uint_least8_t fsm_state_id_t;
00080 #else
00081     typedef ETL_FSM_STATE_ID_TYPE fsm_state_id_t;
00082 #endif
00083 
00084   // For internal FSM use.
00085   typedef typename etl::larger_type<etl::message_id_t>::type fsm_internal_id_t;
00086 
00087   //***************************************************************************
00088   /// Base exception class for FSM.
00089   //***************************************************************************
00090   class fsm_exception : public etl::exception
00091   {
00092   public:
00093 
00094     fsm_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
00095       : etl::exception(reason_, file_name_, line_number_)
00096     {
00097     }
00098   };
00099 
00100   //***************************************************************************
00101   /// Exception for null state pointer.
00102   //***************************************************************************
00103   class fsm_null_state_exception : public etl::fsm_exception
00104   {
00105   public:
00106 
00107     fsm_null_state_exception(string_type file_name_, numeric_type line_number_)
00108       : etl::fsm_exception(ETL_ERROR_TEXT("fsm:null state", ETL_FILE"A"), file_name_, line_number_)
00109     {
00110     }
00111   };
00112 
00113   //***************************************************************************
00114   /// Exception for invalid state id.
00115   //***************************************************************************
00116   class fsm_state_id_exception : public etl::fsm_exception
00117   {
00118   public:
00119 
00120     fsm_state_id_exception(string_type file_name_, numeric_type line_number_)
00121       : etl::fsm_exception(ETL_ERROR_TEXT("fsm:state id", ETL_FILE"B"), file_name_, line_number_)
00122     {
00123     }
00124   };
00125 
00126   //***************************************************************************
00127   /// Exception for incompatible state list.
00128   //***************************************************************************
00129   class fsm_state_list_exception : public etl::fsm_exception
00130   {
00131   public:
00132 
00133     fsm_state_list_exception(string_type file_name_, numeric_type line_number_)
00134       : etl::fsm_exception(ETL_ERROR_TEXT("fsm:state list", ETL_FILE"C"), file_name_, line_number_)
00135     {
00136     }
00137   };
00138 
00139   //***************************************************************************
00140   /// Interface class for FSM states.
00141   //***************************************************************************
00142   class ifsm_state
00143   {
00144   public:
00145 
00146     /// Allows ifsm_state functions to be private.
00147     friend class etl::fsm;
00148 
00149     //*******************************************
00150     /// Gets the id for this state.
00151     //*******************************************
00152     etl::fsm_state_id_t get_state_id() const
00153     {
00154       return state_id;
00155     }
00156 
00157   protected:
00158 
00159     //*******************************************
00160     /// Constructor.
00161     //*******************************************
00162     ifsm_state(etl::fsm_state_id_t state_id_)
00163       : state_id(state_id_),
00164         p_context(std::nullptr)
00165     {
00166     }
00167 
00168     //*******************************************
00169     inline etl::fsm& get_fsm_context() const
00170     {
00171       return *p_context;
00172     }
00173 
00174   private:
00175 
00176     virtual fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) = 0;
00177 
00178     virtual fsm_state_id_t on_enter_state() { return state_id; } // By default, do nothing.
00179     virtual void on_exit_state() {}  // By default, do nothing.
00180 
00181     //*******************************************
00182     void set_fsm_context(etl::fsm& context)
00183     {
00184       p_context = &context;
00185     }
00186 
00187     // The state id.
00188     const etl::fsm_state_id_t state_id;
00189 
00190     // A pointer to the FSM context.
00191     etl::fsm* p_context;
00192 
00193     // Disabled.
00194     ifsm_state(const ifsm_state&);
00195     ifsm_state& operator =(const ifsm_state&);
00196   };
00197 
00198   //***************************************************************************
00199   /// The FSM class.
00200   //***************************************************************************
00201   class fsm : public etl::imessage_router
00202   {
00203   public:
00204 
00205     //*******************************************
00206     /// Constructor.
00207     //*******************************************
00208     fsm(etl::message_router_id_t id)
00209       : imessage_router(id),
00210         p_state(std::nullptr)
00211     {
00212     }
00213 
00214     //*******************************************
00215     /// Set the states for the FSM
00216     //*******************************************
00217     template <typename TSize>
00218     void set_states(etl::ifsm_state** p_states, TSize size)
00219     {
00220       state_list       = p_states;
00221       number_of_states = etl::fsm_state_id_t(size);
00222 
00223       ETL_ASSERT((number_of_states > 0), ETL_ERROR(etl::fsm_state_list_exception));
00224 
00225       for (etl::fsm_state_id_t i = 0; i < size; ++i)
00226       {
00227         ETL_ASSERT((state_list[i] != std::nullptr), ETL_ERROR(etl::fsm_null_state_exception));
00228         state_list[i]->set_fsm_context(*this);
00229       }
00230     }
00231 
00232     //*******************************************
00233     /// Starts the FSM.
00234     /// Can only be called once.
00235     /// Subsequent calls will do nothing.
00236     //*******************************************
00237     void start()
00238     {
00239       // Can only be started once.
00240       if (p_state == std::nullptr)
00241       {
00242         p_state = state_list[0];
00243         ETL_ASSERT(p_state != std::nullptr, ETL_ERROR(etl::fsm_null_state_exception));
00244 
00245         p_state->on_enter_state();
00246       }
00247     }
00248 
00249     //*******************************************
00250     /// Top level message handler for the FSM.
00251     //*******************************************
00252     void receive(const etl::imessage& message)
00253     {
00254       etl::null_message_router nmr;
00255       receive(nmr, message);
00256     }
00257 
00258     //*******************************************
00259     /// Top level message handler for the FSM.
00260     //*******************************************
00261     void receive(etl::imessage_router& source, const etl::imessage& message)
00262     {
00263       etl::fsm_state_id_t next_state_id = p_state->process_event(source, message);
00264       ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
00265 
00266       etl::ifsm_state* p_next_state = state_list[next_state_id];
00267 
00268       // Have we changed state?
00269       if (p_next_state != p_state)
00270       {
00271         do
00272         {
00273           p_state->on_exit_state();
00274           p_state = p_next_state;
00275 
00276           next_state_id = p_state->on_enter_state();
00277           ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
00278 
00279           p_next_state = state_list[next_state_id];
00280 
00281         } while (p_next_state != p_state); // Have we changed state again?
00282       }
00283     }
00284 
00285     using imessage_router::accepts;
00286 
00287     //*******************************************
00288     /// Does this FSM accept the message id?
00289     /// Yes, it accepts everything!
00290     //*******************************************
00291     bool accepts(etl::message_id_t id) const
00292     {
00293       return true;
00294     }
00295 
00296     //*******************************************
00297     /// Gets the current state id.
00298     //*******************************************
00299     etl::fsm_state_id_t get_state_id() const
00300     {
00301       ETL_ASSERT(p_state != std::nullptr, ETL_ERROR(etl::fsm_null_state_exception));
00302       return p_state->get_state_id();
00303     }
00304 
00305     //*******************************************
00306     /// Gets a reference to the current state interface.
00307     //*******************************************
00308     ifsm_state& get_state()
00309     {
00310       ETL_ASSERT(p_state != std::nullptr, ETL_ERROR(etl::fsm_null_state_exception));
00311       return *p_state;
00312     }
00313 
00314     //*******************************************
00315     /// Gets a const reference to the current state interface.
00316     //*******************************************
00317     const ifsm_state& get_state() const
00318     {
00319       ETL_ASSERT(p_state != std::nullptr, ETL_ERROR(etl::fsm_null_state_exception));
00320       return *p_state;
00321     }
00322 
00323     //*******************************************
00324     /// Checks if the FSM has been started.
00325     //*******************************************
00326     bool is_started() const
00327     {
00328       return p_state != std::nullptr;
00329     }
00330 
00331     //*******************************************
00332     /// Reset the FSM to pre-started state.
00333     //*******************************************
00334     void reset()
00335     {
00336       p_state = std::nullptr;
00337     }
00338 
00339   private:
00340 
00341     etl::ifsm_state*    p_state;          ///< A pointer to the current state.
00342     etl::ifsm_state**   state_list;       ///< The list of added states.
00343     etl::fsm_state_id_t number_of_states; ///< The number of states.
00344   };
00345 
00346   //***************************************************************************
00347   // The definition for all 16 message types.
00348   //***************************************************************************
00349   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
00350             typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void, 
00351             typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void, 
00352             typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void, 
00353             typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void>
00354   class fsm_state : public ifsm_state
00355   {
00356   public:
00357 
00358     enum
00359     {
00360       STATE_ID = STATE_ID_
00361     };
00362 
00363     fsm_state()
00364       : ifsm_state(STATE_ID)
00365     {
00366     }
00367 
00368   protected:
00369 
00370     inline TContext& get_fsm_context() const
00371     {
00372       return static_cast<TContext&>(ifsm_state::get_fsm_context());
00373     }
00374 
00375   private:
00376 
00377     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
00378     {
00379       etl::fsm_state_id_t new_state_id;
00380       etl::message_id_t event_id = message.message_id;
00381 
00382       switch (event_id)
00383       {
00384         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
00385         case T2::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T2&>(message)); break;
00386         case T3::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T3&>(message)); break;
00387         case T4::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T4&>(message)); break;
00388         case T5::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T5&>(message)); break;
00389         case T6::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T6&>(message)); break;
00390         case T7::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T7&>(message)); break;
00391         case T8::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T8&>(message)); break;
00392         case T9::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T9&>(message)); break;
00393         case T10::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T10&>(message)); break;
00394         case T11::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T11&>(message)); break;
00395         case T12::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T12&>(message)); break;
00396         case T13::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T13&>(message)); break;
00397         case T14::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T14&>(message)); break;
00398         case T15::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T15&>(message)); break;
00399         case T16::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T16&>(message)); break;
00400         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
00401       }
00402 
00403       return new_state_id;
00404     }
00405   };
00406 
00407   //***************************************************************************
00408   // Specialisation for 15 message types.
00409   //***************************************************************************
00410   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
00411             typename T1, typename T2, typename T3, typename T4, 
00412             typename T5, typename T6, typename T7, typename T8, 
00413             typename T9, typename T10, typename T11, typename T12, 
00414             typename T13, typename T14, typename T15>
00415   class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, void> : public ifsm_state
00416   {
00417   public:
00418 
00419     enum
00420     {
00421       STATE_ID = STATE_ID_
00422     };
00423 
00424     fsm_state()
00425       : ifsm_state(STATE_ID)
00426     {
00427     }
00428 
00429   protected:
00430 
00431     inline TContext& get_fsm_context() const
00432     {
00433       return static_cast<TContext&>(ifsm_state::get_fsm_context());
00434     }
00435 
00436   private:
00437 
00438     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
00439     {
00440       etl::fsm_state_id_t new_state_id;
00441       etl::message_id_t event_id = message.message_id;
00442 
00443       switch (event_id)
00444       {
00445         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
00446         case T2::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T2&>(message)); break;
00447         case T3::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T3&>(message)); break;
00448         case T4::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T4&>(message)); break;
00449         case T5::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T5&>(message)); break;
00450         case T6::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T6&>(message)); break;
00451         case T7::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T7&>(message)); break;
00452         case T8::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T8&>(message)); break;
00453         case T9::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T9&>(message)); break;
00454         case T10::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T10&>(message)); break;
00455         case T11::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T11&>(message)); break;
00456         case T12::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T12&>(message)); break;
00457         case T13::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T13&>(message)); break;
00458         case T14::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T14&>(message)); break;
00459         case T15::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T15&>(message)); break;
00460         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
00461       }
00462 
00463       return new_state_id;
00464     }
00465   };
00466 
00467   //***************************************************************************
00468   // Specialisation for 14 message types.
00469   //***************************************************************************
00470   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
00471             typename T1, typename T2, typename T3, typename T4, 
00472             typename T5, typename T6, typename T7, typename T8, 
00473             typename T9, typename T10, typename T11, typename T12, 
00474             typename T13, typename T14>
00475   class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, void, void> : public ifsm_state
00476   {
00477   public:
00478 
00479     enum
00480     {
00481       STATE_ID = STATE_ID_
00482     };
00483 
00484     fsm_state()
00485       : ifsm_state(STATE_ID)
00486     {
00487     }
00488 
00489   protected:
00490 
00491     inline TContext& get_fsm_context() const
00492     {
00493       return static_cast<TContext&>(ifsm_state::get_fsm_context());
00494     }
00495 
00496   private:
00497 
00498     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
00499     {
00500       etl::fsm_state_id_t new_state_id;
00501       etl::message_id_t event_id = message.message_id;
00502 
00503       switch (event_id)
00504       {
00505         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
00506         case T2::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T2&>(message)); break;
00507         case T3::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T3&>(message)); break;
00508         case T4::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T4&>(message)); break;
00509         case T5::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T5&>(message)); break;
00510         case T6::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T6&>(message)); break;
00511         case T7::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T7&>(message)); break;
00512         case T8::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T8&>(message)); break;
00513         case T9::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T9&>(message)); break;
00514         case T10::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T10&>(message)); break;
00515         case T11::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T11&>(message)); break;
00516         case T12::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T12&>(message)); break;
00517         case T13::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T13&>(message)); break;
00518         case T14::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T14&>(message)); break;
00519         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
00520       }
00521 
00522       return new_state_id;
00523     }
00524   };
00525 
00526   //***************************************************************************
00527   // Specialisation for 13 message types.
00528   //***************************************************************************
00529   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
00530             typename T1, typename T2, typename T3, typename T4, 
00531             typename T5, typename T6, typename T7, typename T8, 
00532             typename T9, typename T10, typename T11, typename T12, 
00533             typename T13>
00534   class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, void, void, void> : public ifsm_state
00535   {
00536   public:
00537 
00538     enum
00539     {
00540       STATE_ID = STATE_ID_
00541     };
00542 
00543     fsm_state()
00544       : ifsm_state(STATE_ID)
00545     {
00546     }
00547 
00548   protected:
00549 
00550     inline TContext& get_fsm_context() const
00551     {
00552       return static_cast<TContext&>(ifsm_state::get_fsm_context());
00553     }
00554 
00555   private:
00556 
00557     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
00558     {
00559       etl::fsm_state_id_t new_state_id;
00560       etl::message_id_t event_id = message.message_id;
00561 
00562       switch (event_id)
00563       {
00564         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
00565         case T2::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T2&>(message)); break;
00566         case T3::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T3&>(message)); break;
00567         case T4::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T4&>(message)); break;
00568         case T5::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T5&>(message)); break;
00569         case T6::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T6&>(message)); break;
00570         case T7::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T7&>(message)); break;
00571         case T8::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T8&>(message)); break;
00572         case T9::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T9&>(message)); break;
00573         case T10::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T10&>(message)); break;
00574         case T11::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T11&>(message)); break;
00575         case T12::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T12&>(message)); break;
00576         case T13::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T13&>(message)); break;
00577         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
00578       }
00579 
00580       return new_state_id;
00581     }
00582   };
00583 
00584   //***************************************************************************
00585   // Specialisation for 12 message types.
00586   //***************************************************************************
00587   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
00588             typename T1, typename T2, typename T3, typename T4, 
00589             typename T5, typename T6, typename T7, typename T8, 
00590             typename T9, typename T10, typename T11, typename T12>
00591   class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, void, void, void, void> : public ifsm_state
00592   {
00593   public:
00594 
00595     enum
00596     {
00597       STATE_ID = STATE_ID_
00598     };
00599 
00600     fsm_state()
00601       : ifsm_state(STATE_ID)
00602     {
00603     }
00604 
00605   protected:
00606 
00607     inline TContext& get_fsm_context() const
00608     {
00609       return static_cast<TContext&>(ifsm_state::get_fsm_context());
00610     }
00611 
00612   private:
00613 
00614     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
00615     {
00616       etl::fsm_state_id_t new_state_id;
00617       etl::message_id_t event_id = message.message_id;
00618 
00619       switch (event_id)
00620       {
00621         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
00622         case T2::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T2&>(message)); break;
00623         case T3::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T3&>(message)); break;
00624         case T4::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T4&>(message)); break;
00625         case T5::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T5&>(message)); break;
00626         case T6::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T6&>(message)); break;
00627         case T7::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T7&>(message)); break;
00628         case T8::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T8&>(message)); break;
00629         case T9::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T9&>(message)); break;
00630         case T10::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T10&>(message)); break;
00631         case T11::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T11&>(message)); break;
00632         case T12::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T12&>(message)); break;
00633         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
00634       }
00635 
00636       return new_state_id;
00637     }
00638   };
00639 
00640   //***************************************************************************
00641   // Specialisation for 11 message types.
00642   //***************************************************************************
00643   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
00644             typename T1, typename T2, typename T3, typename T4, 
00645             typename T5, typename T6, typename T7, typename T8, 
00646             typename T9, typename T10, typename T11>
00647   class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, void, void, void, void, void> : public ifsm_state
00648   {
00649   public:
00650 
00651     enum
00652     {
00653       STATE_ID = STATE_ID_
00654     };
00655 
00656     fsm_state()
00657       : ifsm_state(STATE_ID)
00658     {
00659     }
00660 
00661   protected:
00662 
00663     inline TContext& get_fsm_context() const
00664     {
00665       return static_cast<TContext&>(ifsm_state::get_fsm_context());
00666     }
00667 
00668   private:
00669 
00670     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
00671     {
00672       etl::fsm_state_id_t new_state_id;
00673       etl::message_id_t event_id = message.message_id;
00674 
00675       switch (event_id)
00676       {
00677         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
00678         case T2::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T2&>(message)); break;
00679         case T3::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T3&>(message)); break;
00680         case T4::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T4&>(message)); break;
00681         case T5::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T5&>(message)); break;
00682         case T6::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T6&>(message)); break;
00683         case T7::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T7&>(message)); break;
00684         case T8::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T8&>(message)); break;
00685         case T9::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T9&>(message)); break;
00686         case T10::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T10&>(message)); break;
00687         case T11::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T11&>(message)); break;
00688         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
00689       }
00690 
00691       return new_state_id;
00692     }
00693   };
00694 
00695   //***************************************************************************
00696   // Specialisation for 10 message types.
00697   //***************************************************************************
00698   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
00699             typename T1, typename T2, typename T3, typename T4, 
00700             typename T5, typename T6, typename T7, typename T8, 
00701             typename T9, typename T10>
00702   class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, void, void, void, void, void, void> : public ifsm_state
00703   {
00704   public:
00705 
00706     enum
00707     {
00708       STATE_ID = STATE_ID_
00709     };
00710 
00711     fsm_state()
00712       : ifsm_state(STATE_ID)
00713     {
00714     }
00715 
00716   protected:
00717 
00718     inline TContext& get_fsm_context() const
00719     {
00720       return static_cast<TContext&>(ifsm_state::get_fsm_context());
00721     }
00722 
00723   private:
00724 
00725     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
00726     {
00727       etl::fsm_state_id_t new_state_id;
00728       etl::message_id_t event_id = message.message_id;
00729 
00730       switch (event_id)
00731       {
00732         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
00733         case T2::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T2&>(message)); break;
00734         case T3::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T3&>(message)); break;
00735         case T4::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T4&>(message)); break;
00736         case T5::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T5&>(message)); break;
00737         case T6::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T6&>(message)); break;
00738         case T7::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T7&>(message)); break;
00739         case T8::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T8&>(message)); break;
00740         case T9::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T9&>(message)); break;
00741         case T10::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T10&>(message)); break;
00742         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
00743       }
00744 
00745       return new_state_id;
00746     }
00747   };
00748 
00749   //***************************************************************************
00750   // Specialisation for 9 message types.
00751   //***************************************************************************
00752   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
00753             typename T1, typename T2, typename T3, typename T4, 
00754             typename T5, typename T6, typename T7, typename T8, 
00755             typename T9>
00756   class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, T9, void, void, void, void, void, void, void> : public ifsm_state
00757   {
00758   public:
00759 
00760     enum
00761     {
00762       STATE_ID = STATE_ID_
00763     };
00764 
00765     fsm_state()
00766       : ifsm_state(STATE_ID)
00767     {
00768     }
00769 
00770   protected:
00771 
00772     inline TContext& get_fsm_context() const
00773     {
00774       return static_cast<TContext&>(ifsm_state::get_fsm_context());
00775     }
00776 
00777   private:
00778 
00779     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
00780     {
00781       etl::fsm_state_id_t new_state_id;
00782       etl::message_id_t event_id = message.message_id;
00783 
00784       switch (event_id)
00785       {
00786         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
00787         case T2::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T2&>(message)); break;
00788         case T3::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T3&>(message)); break;
00789         case T4::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T4&>(message)); break;
00790         case T5::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T5&>(message)); break;
00791         case T6::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T6&>(message)); break;
00792         case T7::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T7&>(message)); break;
00793         case T8::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T8&>(message)); break;
00794         case T9::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T9&>(message)); break;
00795         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
00796       }
00797 
00798       return new_state_id;
00799     }
00800   };
00801 
00802   //***************************************************************************
00803   // Specialisation for 8 message types.
00804   //***************************************************************************
00805   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
00806             typename T1, typename T2, typename T3, typename T4, 
00807             typename T5, typename T6, typename T7, typename T8>
00808   class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, void, void, void, void, void, void, void, void> : public ifsm_state
00809   {
00810   public:
00811 
00812     enum
00813     {
00814       STATE_ID = STATE_ID_
00815     };
00816 
00817     fsm_state()
00818       : ifsm_state(STATE_ID)
00819     {
00820     }
00821 
00822   protected:
00823 
00824     inline TContext& get_fsm_context() const
00825     {
00826       return static_cast<TContext&>(ifsm_state::get_fsm_context());
00827     }
00828 
00829   private:
00830 
00831     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
00832     {
00833       etl::fsm_state_id_t new_state_id;
00834       etl::message_id_t event_id = message.message_id;
00835 
00836       switch (event_id)
00837       {
00838         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
00839         case T2::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T2&>(message)); break;
00840         case T3::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T3&>(message)); break;
00841         case T4::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T4&>(message)); break;
00842         case T5::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T5&>(message)); break;
00843         case T6::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T6&>(message)); break;
00844         case T7::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T7&>(message)); break;
00845         case T8::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T8&>(message)); break;
00846         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
00847       }
00848 
00849       return new_state_id;
00850     }
00851   };
00852 
00853   //***************************************************************************
00854   // Specialisation for 7 message types.
00855   //***************************************************************************
00856   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
00857             typename T1, typename T2, typename T3, typename T4, 
00858             typename T5, typename T6, typename T7>
00859   class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, void, void, void, void, void, void, void, void, void> : public ifsm_state
00860   {
00861   public:
00862 
00863     enum
00864     {
00865       STATE_ID = STATE_ID_
00866     };
00867 
00868     fsm_state()
00869       : ifsm_state(STATE_ID)
00870     {
00871     }
00872 
00873   protected:
00874 
00875     inline TContext& get_fsm_context() const
00876     {
00877       return static_cast<TContext&>(ifsm_state::get_fsm_context());
00878     }
00879 
00880   private:
00881 
00882     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
00883     {
00884       etl::fsm_state_id_t new_state_id;
00885       etl::message_id_t event_id = message.message_id;
00886 
00887       switch (event_id)
00888       {
00889         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
00890         case T2::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T2&>(message)); break;
00891         case T3::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T3&>(message)); break;
00892         case T4::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T4&>(message)); break;
00893         case T5::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T5&>(message)); break;
00894         case T6::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T6&>(message)); break;
00895         case T7::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T7&>(message)); break;
00896         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
00897       }
00898 
00899       return new_state_id;
00900     }
00901   };
00902 
00903   //***************************************************************************
00904   // Specialisation for 6 message types.
00905   //***************************************************************************
00906   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
00907             typename T1, typename T2, typename T3, typename T4, 
00908             typename T5, typename T6>
00909   class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, void, void, void, void, void, void, void, void, void, void> : public ifsm_state
00910   {
00911   public:
00912 
00913     enum
00914     {
00915       STATE_ID = STATE_ID_
00916     };
00917 
00918     fsm_state()
00919       : ifsm_state(STATE_ID)
00920     {
00921     }
00922 
00923   protected:
00924 
00925     inline TContext& get_fsm_context() const
00926     {
00927       return static_cast<TContext&>(ifsm_state::get_fsm_context());
00928     }
00929 
00930   private:
00931 
00932     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
00933     {
00934       etl::fsm_state_id_t new_state_id;
00935       etl::message_id_t event_id = message.message_id;
00936 
00937       switch (event_id)
00938       {
00939         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
00940         case T2::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T2&>(message)); break;
00941         case T3::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T3&>(message)); break;
00942         case T4::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T4&>(message)); break;
00943         case T5::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T5&>(message)); break;
00944         case T6::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T6&>(message)); break;
00945         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
00946       }
00947 
00948       return new_state_id;
00949     }
00950   };
00951 
00952   //***************************************************************************
00953   // Specialisation for 5 message types.
00954   //***************************************************************************
00955   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
00956             typename T1, typename T2, typename T3, typename T4, 
00957             typename T5>
00958   class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, void, void, void, void, void, void, void, void, void, void, void> : public ifsm_state
00959   {
00960   public:
00961 
00962     enum
00963     {
00964       STATE_ID = STATE_ID_
00965     };
00966 
00967     fsm_state()
00968       : ifsm_state(STATE_ID)
00969     {
00970     }
00971 
00972   protected:
00973 
00974     inline TContext& get_fsm_context() const
00975     {
00976       return static_cast<TContext&>(ifsm_state::get_fsm_context());
00977     }
00978 
00979   private:
00980 
00981     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
00982     {
00983       etl::fsm_state_id_t new_state_id;
00984       etl::message_id_t event_id = message.message_id;
00985 
00986       switch (event_id)
00987       {
00988         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
00989         case T2::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T2&>(message)); break;
00990         case T3::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T3&>(message)); break;
00991         case T4::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T4&>(message)); break;
00992         case T5::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T5&>(message)); break;
00993         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
00994       }
00995 
00996       return new_state_id;
00997     }
00998   };
00999 
01000   //***************************************************************************
01001   // Specialisation for 4 message types.
01002   //***************************************************************************
01003   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
01004             typename T1, typename T2, typename T3, typename T4>
01005   class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, void, void, void, void, void, void, void, void, void, void, void, void> : public ifsm_state
01006   {
01007   public:
01008 
01009     enum
01010     {
01011       STATE_ID = STATE_ID_
01012     };
01013 
01014     fsm_state()
01015       : ifsm_state(STATE_ID)
01016     {
01017     }
01018 
01019   protected:
01020 
01021     inline TContext& get_fsm_context() const
01022     {
01023       return static_cast<TContext&>(ifsm_state::get_fsm_context());
01024     }
01025 
01026   private:
01027 
01028     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
01029     {
01030       etl::fsm_state_id_t new_state_id;
01031       etl::message_id_t event_id = message.message_id;
01032 
01033       switch (event_id)
01034       {
01035         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
01036         case T2::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T2&>(message)); break;
01037         case T3::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T3&>(message)); break;
01038         case T4::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T4&>(message)); break;
01039         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
01040       }
01041 
01042       return new_state_id;
01043     }
01044   };
01045 
01046   //***************************************************************************
01047   // Specialisation for 3 message types.
01048   //***************************************************************************
01049   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
01050             typename T1, typename T2, typename T3>
01051   class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, void, void, void, void, void, void, void, void, void, void, void, void, void> : public ifsm_state
01052   {
01053   public:
01054 
01055     enum
01056     {
01057       STATE_ID = STATE_ID_
01058     };
01059 
01060     fsm_state()
01061       : ifsm_state(STATE_ID)
01062     {
01063     }
01064 
01065   protected:
01066 
01067     inline TContext& get_fsm_context() const
01068     {
01069       return static_cast<TContext&>(ifsm_state::get_fsm_context());
01070     }
01071 
01072   private:
01073 
01074     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
01075     {
01076       etl::fsm_state_id_t new_state_id;
01077       etl::message_id_t event_id = message.message_id;
01078 
01079       switch (event_id)
01080       {
01081         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
01082         case T2::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T2&>(message)); break;
01083         case T3::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T3&>(message)); break;
01084         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
01085       }
01086 
01087       return new_state_id;
01088     }
01089   };
01090 
01091   //***************************************************************************
01092   // Specialisation for 2 message types.
01093   //***************************************************************************
01094   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
01095             typename T1, typename T2>
01096   class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, void, void, void, void, void, void, void, void, void, void, void, void, void, void> : public ifsm_state
01097   {
01098   public:
01099 
01100     enum
01101     {
01102       STATE_ID = STATE_ID_
01103     };
01104 
01105     fsm_state()
01106       : ifsm_state(STATE_ID)
01107     {
01108     }
01109 
01110   protected:
01111 
01112     inline TContext& get_fsm_context() const
01113     {
01114       return static_cast<TContext&>(ifsm_state::get_fsm_context());
01115     }
01116 
01117   private:
01118 
01119     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
01120     {
01121       etl::fsm_state_id_t new_state_id;
01122       etl::message_id_t event_id = message.message_id;
01123 
01124       switch (event_id)
01125       {
01126         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
01127         case T2::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T2&>(message)); break;
01128         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
01129       }
01130 
01131       return new_state_id;
01132     }
01133   };
01134 
01135   //***************************************************************************
01136   // Specialisation for 1 message type.
01137   //***************************************************************************
01138   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, 
01139             typename T1>
01140   class fsm_state<TContext, TDerived, STATE_ID_, T1, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void> : public ifsm_state
01141   {
01142   public:
01143 
01144     enum
01145     {
01146       STATE_ID = STATE_ID_
01147     };
01148 
01149     fsm_state()
01150       : ifsm_state(STATE_ID)
01151     {
01152     }
01153 
01154   protected:
01155 
01156     inline TContext& get_fsm_context() const
01157     {
01158       return static_cast<TContext&>(ifsm_state::get_fsm_context());
01159     }
01160 
01161   private:
01162 
01163     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
01164     {
01165       etl::fsm_state_id_t new_state_id;
01166       etl::message_id_t event_id = message.message_id;
01167 
01168       switch (event_id)
01169       {
01170         case T1::ID: new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T1&>(message)); break;
01171         default: new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message); break;
01172       }
01173 
01174       return new_state_id;
01175     }
01176   };
01177 
01178   //***************************************************************************
01179   // Specialisation for 0 message types.
01180   //***************************************************************************
01181   template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_>
01182   class fsm_state<TContext, TDerived, STATE_ID_, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void> : public ifsm_state
01183   {
01184   public:
01185 
01186     enum
01187     {
01188       STATE_ID = STATE_ID_
01189     };
01190 
01191     fsm_state()
01192       : ifsm_state(STATE_ID)
01193     {
01194     }
01195 
01196     inline TContext& get_fsm_context() const
01197     {
01198       return static_cast<TContext&>(ifsm_state::get_fsm_context());
01199     }
01200   private:
01201 
01202     etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
01203     {
01204       return static_cast<TDerived*>(this)->on_event_unknown(source, message);
01205     }
01206   };
01207 }
01208 
01209 #undef ETL_FILE
01210 
01211 #ifdef ETL_COMPILER_MICROSOFT
01212 #define max(a,b) (((a) > (b)) ? (a) : (b))
01213 #endif
01214 
01215 #endif
01216