-
-
Notifications
You must be signed in to change notification settings - Fork 16
How to write HFSM Code
NOTE: as of https://github.com/finger563/webgme-hfsm/pull/133 the examples for generated code in this page are out of date!
- Attribute descriptions
- Declaring / Defining / Using HFSM-wide members
- Integrating HFSM generated code into your own codebase
- Debugging
- How the generated code is structured
-
State Machine
-
Includes
: this attribute is included in the generated states header file outside of theStateMachine
namespace. It is where you would add any headers that your HFSM code may need for platform specific libraries. -
Declarations
: this attribute is added within the generated HFSM class within theStateMachine
namespace, specifically into its generated states header file. It is where you would add any member functions or data that all states should be able to access. More about how to properly define and access them is described below. -
Definitions
: this attribute is added within the generated HFSM class within theStateMachine
namespace, specifically into its generated states source file. It is where you should define any functions or variables that were declared inDeclarations
. More about how to properly define and access them is described below. -
Initialization
: this attribute is added within the generated HFSM class'initialize
function defined within the generated states source file. It is where you should write any initialization code that should happen first before anything else in the HFSM executes.
-
-
State
-
Entry
: this attribute represents the body of a function that is executed any time a state is entered. That function exists within the state's class definition in the generated states source file. -
Exit
: this attribute represents the body of a function that is executed any time a state is exited. That function exists within the state's class definition in the generated states source file. -
Tick
: this attribute represents the body of a function that is executed any time a state is ticked. That function exists within the state's class definition in the generated states source file.
-
-
Transition
-
Action
: this attribute represents code that will be generated into multiple differenthandleEvent
state class functions at different levels of the class tree structure depending on the structure of the HFSM and its transition pathways.
-
Because of the structure of the generated code (i.e. that each state is declared as a class within the scope of its parent state's class), each state has a different this
pointer - so there are a few options for how to define functions and variables that are accessible within the state functions (e.g. Entry
, Exit
, Tick
).
- Referring to the generated members using the pointer to the HFSM class object, which is generated as
{{{HFSM sanitized name}}}_root
, e.g. for a HFSM namedMotor HFSM
, the root pointer to the HFSM class object would beMotor_HFSM_root
. Note: the name of the HFSM is sanitized, so that spaces are convered to underscores. - Defining the members statically, such that they are immediately accessible to all classes within the HFSM class.
-
Declarations
: -
Definitions
: - Using the members:
When you generate code for the HFSM using the SoftwareGenerator
plugin, you can set Generate Test Bench
to true
, which will generate an additional Makefile
and test.cpp
which can be built using gcc
to do simple testing of your code. This test bench also acts as an example for how to integrate the HFSM generated code into your own project.
Generally, you will want to execute the HFSM following this pattern (in this case the HFSM is named Example hfsm):
int main( int argc, char** argv ) {
// initialize the HFSM
Example_hfsm_root->initialize();
while ( true ) {
// generate any events you need to based on your peripherals / gpio / etc. (or in interrupts)
// e.g. using
eventFactory->spawnEvent( StateMachine::Event::Type::Start );
// where Start is the event name from the model
// NOTE: the event is allocated on the HEAP with using "new"
// then execute the state machine
StateMachine::Event* e = eventFactory->getNextEvent();
while (e != nullptr) {
// tell the HFSM to handle the event
bool handled = Example_hfsm_root->handleEvent( e );
// the event factory allocated the event when it was spawned, but does not own the event
// so we must tell the event factory that we are done with the event so that it can delete it!
eventFactory->consumeEvent( e );
// now see if there are any other events (might have been generated within the HFSM)
e = eventFactory->getNextEvent();
}
}
}
If you use the tick event and want to use the periodicity, you might structure your event handling like so (this is how ROSMOD generates the HFSM (in this case Example hfsm) into a ros::Timer
with a dynamic frequency):
StateMachine::Event* e = nullptr;
// process all pending events
while ( (e = eventFactory->getNextEvent()) != nullptr ) {
Example_hfsm_root->handleEvent( e );
eventFactory->consumeEvent( e );
}
// run the HFSM tick event
Example_hfsm_root->tick();
// process all events that may have been generated by the tick event
while ( (e = eventFactory->getNextEvent()) != nullptr ) {
Example_hfsm_root->handleEvent( e );
eventFactory->consumeEvent( e );
}
// update the timer period according to new active state
ros::Duration newPeriod = ros::Duration( Example_hfsm_root->getActiveLeaf()->getTimerPeriod() );
Example_hfsm_timer.stop();
if (!Example_hfsm_root->hasStopped()) {
Example_hfsm_timer.setPeriod( newPeriod );
Example_hfsm_timer.start();
}
If you're using FreeRTOS, here is an example of how you might want to integrate the HFSM generated code as a Timer
on your system (the HFSM is called Example hfsm):
#include "Example_hfsm_Events.hpp"
#include "Example_hfsm_GeneratedStates.hpp"
#include <string>
#include <iostream>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
#define NUM_TIMERS 1
/* An Array to hold handles to the created timers */
TimerHandle_t xTimers[ NUM_TIMERS ];
#define MS_TO_TICKS( xTimeInMs ) (uint32_t)( ( ( TickType_t ) xTimeInMs * configTICK_RATE_HZ ) / ( TickType_t ) 1000 )
void TimerFunction( TimerHandle_t xTimer ) {
StateMachine::Event* e = eventFactory->getNextEvent();
// handle all events that were generated from the system while we slept
while (e != nullptr) {
bool handled = Example_hfsm_root->handleEvent( e );
// free the memory that was allocated during "spawnEvent"
eventFactory->consumeEvent( e );
e = eventFactory->getNextEvent();
}
// tick the state machine
Example_hfsm_root->tick();
// handle all events that were generated from the tick event
while (e != nullptr) {
bool handled = Example_hfsm_root->handleEvent( e );
// free the memory that was allocated during "spawnEvent"
eventFactory->consumeEvent( e );
e = eventFactory->getNextEvent();
}
if ( Example_hfsm_root->hasStopped() ) {
// the HFSM has reached the top-level END STATE, so we should stop!
xTimerStop( xTimer, 0 ); // block ticks of 0
} else {
// we're still running the HFSM, update the timer period accordingly
double newTimerPeriod = Example_hfsm_root->getActiveLeaf()->getTimerPeriod();
// change the period of the timer if we're changing states
xTimerChangePeriod( xTimer,
MS_TO_TICKS( newTimerPeriod ),
100); // block for up to 100 ticks
}
}
int main( int argc, char** argv ) {
// initialize the HFSM
Example_hfsm_root->initialize();
double newTimerPeriod = Example_hfsm_root->getActiveLeaf()->getTimerPeriod();
// set up timer / task to run the HFSM according to freeRTOS
xTimers[0] = xTimerCreate
("Example_hfsm_timerFunction", // name of the timer (should be short)
MS_TO_TICKS( newTimerPeriod ), // period of the timer in ticks
pdTRUE, // auto-reload the timer function
( void * ) 0, // id of the timer (passed to the callback function)
TimerFunction // function the timer runs
);
// now start the timer
if (xTimerStart( xTimers[0], 0) != pdPASS) {
#ifdef DEBUG_OUTPUT
std::cout << "Timer Start Fail!" << std::endl;
#endif
}
return 0;
};
If you want to use it with a build system such as for the ESP32 running FreeRTOS, here is an example of how you might want to integrate the HFSM generated code as a Timer
on your system (the HFSM is called Example hfsm):
You would probably want to make your HFSM a component
, with the directory structure of:
components
├── Example_hfsm
│ ├── component.mk
│ ├── Example_hfsm_GeneratedStates.cpp
│ └── include
│ ├── DeepHistoryState.hpp
│ ├── Example_hfsm_Events.hpp
│ ├── Example_hfsm_GeneratedStates.hpp
│ ├── ShallowHistoryState.hpp
│ └── StateBase.hpp
.
.
.
And then you might want to create a Timer
for this HFSM in another component, in this case the HFSM_Timer component:
components
├── HFSM_Timer
│ ├── component.mk
│ ├── HFSM_Timer.cpp
│ └── include
│ └── HFSM_Timer.hpp
.
.
.
#ifndef __HFSM_Timer__INCLUDE_GUARD
#define __HFSM_Timer__INCLUDE_GUARD
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
void HFSM_Timer_init( void );
#endif // __HFSM_Timer__INCLUDE_GUARD
#include "Example_hfsm_Events.hpp"
#include "Example_hfsm_GeneratedStates.hpp"
#include "HFSM_Timer.hpp"
#define NUM_TIMERS 1
/* An Array to hold handles to the created timers */
TimerHandle_t xTimers[ NUM_TIMERS ];
#define MS_TO_TICKS( xTimeInMs ) (uint32_t)( ( ( TickType_t ) xTimeInMs * configTICK_RATE_HZ ) / ( TickType_t ) 1000 )
void TimerFunction( TimerHandle_t xTimer ) {
StateMachine::Event* e = eventFactory->getNextEvent();
// handle all events that were generated from the system while we slept
while (e != nullptr) {
bool handled = Example_hfsm_root->handleEvent( e );
// free the memory that was allocated during "spawnEvent"
eventFactory->consumeEvent( e );
e = eventFactory->getNextEvent();
}
// tick the state machine
Example_hfsm_root->tick();
// handle all events that were generated from the tick event
while (e != nullptr) {
bool handled = Example_hfsm_root->handleEvent( e );
// free the memory that was allocated during "spawnEvent"
eventFactory->consumeEvent( e );
e = eventFactory->getNextEvent();
}
if ( Example_hfsm_root->hasStopped() ) {
// the HFSM has reached the top-level END STATE, so we should stop!
xTimerStop( xTimer, 0 ); // block ticks of 0
} else {
// we're still running the HFSM, update the timer period accordingly
double newTimerPeriod = Example_hfsm_root->getActiveLeaf()->getTimerPeriod();
// change the period of the timer if we're changing states
xTimerChangePeriod( xTimer,
MS_TO_TICKS( newTimerPeriod ),
100); // block for up to 100 ticks
}
}
void HFSM_Timer_init( void ) {
// initialize the HFSM
Example_hfsm_root->initialize();
double newTimerPeriod = Example_hfsm_root->getActiveLeaf()->getTimerPeriod();
// set up timer / task to run the HFSM according to freeRTOS
xTimers[0] = xTimerCreate
("Example_hfsm_timerFunction", // name of the timer (should be short)
MS_TO_TICKS( newTimerPeriod ), // period of the timer in ticks
pdTRUE, // auto-reload the timer function
( void * ) 0, // id of the timer (passed to the callback function)
TimerFunction // function the timer runs
);
// now start the timer
if (xTimerStart( xTimers[0], 0) != pdPASS) {
#ifdef DEBUG_OUTPUT
std::cout << "Timer Start Fail!" << std::endl;
#endif
}
}
And then finally in your main.cpp
you would want to simply include the HFSM_Timer.hpp
and call HFSM_Timer_init();
in your app_main
.
By default, debugging is turned off on the HFSM, but if you want the HFSM to output the events that it handles, the transitions that it takes, the guard conditions that evaluate to true, the states it transitions through, and the actions it takes you can add this to your code (or to the test bench code)
#define DEBUG_OUTPUT
which will use std::cout
to print to stdout
logs such as:
GUARD [ someTest ] for EXTERNAL TRANSITION:/3/c/I evaluated to TRUE
NO GUARD on EXTERNAL TRANSITION:/3/c/o
EXIT::Complex::State_1::/3/c/Y
Exiting State 1
TRANSITION::ACTION for /3/c/I
TRANSITION::ACTION for /3/c/o
ENTRY::Complex::State3::/3/c/T
TRANSITION::ACTION for /3/c/T/I
ENTRY::Complex::State3::ChildState::/3/c/T/W
STATE TRANSITION: Complex::State_1->Complex::State3::ChildState
To see example generated code in its entirety (including the static files and build files), you can look at:
#ifndef __EVENT_INCLUDE_GUARD__
#define __EVENT_INCLUDE_GUARD__
#include <deque>
#ifdef DEBUG_OUTPUT
#include <string>
#endif
namespace StateMachine {
class Event {
public:
enum class Type {
ENDEVENT,
EVENT1,
EVENT2,
EVENT3,
EVENT4,
}; // ENUMS GENERATED FROM MODEL
/**
* @brief Constructor for initializing the type.
*/
Event ( Type t ) : _t(t) { }
Type type ( void ) {
return _t;
}
#ifdef DEBUG_OUTPUT
static std::string toString( Event* e ) {
std::string eventString = "";
switch ( e->_t ) {
case Type::ENDEVENT:
eventString = "ENDEVENT";
break;
case Type::EVENT1:
eventString = "EVENT1";
break;
case Type::EVENT2:
eventString = "EVENT2";
break;
case Type::EVENT3:
eventString = "EVENT3";
break;
case Type::EVENT4:
eventString = "EVENT4";
break;
default:
break;
}
return eventString;
}
#endif
protected:
Type _t;
};
/**
* @brief Class handling all Event creation, memory management, and
* ordering.
*/
class EventFactory {
public:
/**
* @brief Destructor; ensures all memory for all Events is
* deallocated.
*/
~EventFactory( void ) {
clearEvents();
}
/**
* @brief Allocates new memory for a new Event of type t and adds
* it to the Q.
*
* @param[in] Event::Type t The type of the event to create
*/
void spawnEvent ( StateMachine::Event::Type t ) {
StateMachine::Event* newEvent = new Event( t );
_eventQ.push_back( newEvent );
}
/**
* @brief Frees the memory associated with the Event.
*
* @param[in] Event* e Pointer to the event to consume
*/
void consumeEvent ( StateMachine::Event* e ) {
delete e;
e = nullptr;
}
/**
* @brief Retrieves the pointer to the next event in the queue, or
* nullptr if the Q is empty.
*
* @return Event* Oldest Event that was in the Queue
*/
StateMachine::Event *getNextEvent ( void ) {
StateMachine::Event* ptr = nullptr;
if (_eventQ.size()) {
ptr = _eventQ.front();
_eventQ.pop_front(); // remove the event from the Q
}
return ptr;
}
/**
* @brief Clears the event queue and frees all memory associated
* with the events.
*/
void clearEvents ( void ) {
StateMachine::Event* ptr = getNextEvent();
while (ptr != nullptr) {
consumeEvent( ptr );
ptr = getNextEvent();
}
}
#ifdef DEBUG_OUTPUT
std::string toString ( void ) {
std::string qStr = "[ ";
for (int i=0; i<_eventQ.size(); i++) {
qStr += Event::toString( _eventQ[i] );
}
qStr += " ]";
return qStr;
}
#endif
protected:
std::deque<StateMachine::Event*> _eventQ;
};
};
extern StateMachine::EventFactory *const eventFactory;
#endif // __EVENT_INCLUDE_GUARD__
#ifndef __GENERATED_STATES_INCLUDE_GUARD__
#define __GENERATED_STATES_INCLUDE_GUARD__
#include "StateBase.hpp"
#include "DeepHistoryState.hpp"
#include "ShallowHistoryState.hpp"
// User Includes for the HFSM
//::::/c::::Includes::::
#include <stdio.h>
namespace StateMachine {
// ROOT OF THE HFSM
class Complex : public StateMachine::StateBase {
public:
// User Declarations for the HFSM
//::::/c::::Declarations::::
static bool goToEnd;
static bool goToChoice;
static bool goToHistory;
static bool nextState;
static bool killedState;
static bool someGuard;
static bool someTest;
static int someNumber;
static int someValue;
// Child Substates
/**
* @brief Declaration for Complex::State_1 : /c/Y
*
* States contain other states and can consume generic
* StateMachine::Event objects if they have internal or external
* transitions on those events and if those transitions' guards are
* satisfied. Only one transition can consume an event in a given
* state machine.
*
* There is also a different kind of Event, the tick event, which is
* not consumed, but instead executes from the top-level state all
* the way to the curently active leaf state.
*
* Entry and Exit actions also occur whenever a state is entered or
* exited, respectively.
*/
class State_1 : public StateMachine::StateBase {
public:
// Timer period
static const double timerPeriod;
// Constructors
State_1 ( void ) : StateBase( ) {}
State_1 ( StateBase* _parent ) : StateBase( _parent ) {}
~State_1 ( void ) {}
/**
* @brief Calls entry() then handles any child
* initialization. Finally calls makeActive on the leaf.
*/
void initialize ( void );
/**
* @brief Runs the entry() function defined in the model.
*/
void entry ( void );
/**
* @brief Runs the exit() function defined in the model.
*/
void exit ( void );
/**
* @brief Runs the tick() function defined in the model and then
* calls _activeState->tick().
*/
void tick ( void );
/**
* @brief The timer period of the state in floating point seconds.
*
* @return double timer period
*/
double getTimerPeriod ( void );
/**
* @brief Calls _activeState->handleEvent( event ), then if the
* event is not nullptr (meaning the event was not consumed by
* the child subtree), it checks the event against all internal
* transitions associated with that Event. If the event is still
* not a nullptr (meaning the event was not consumed by the
* internal transitions), then it checks the event against all
* external transitions associated with that Event.
*
* @param[in] StateMachine::Event* Event needing to be handled
*
* @return true if event is consumed, false otherwise
*/
bool handleEvent ( StateMachine::Event* event );
};
/**
* @brief Declaration for Complex::State_2 : /c/v
*
* States contain other states and can consume generic
* StateMachine::Event objects if they have internal or external
* transitions on those events and if those transitions' guards are
* satisfied. Only one transition can consume an event in a given
* state machine.
*
* There is also a different kind of Event, the tick event, which is
* not consumed, but instead executes from the top-level state all
* the way to the curently active leaf state.
*
* Entry and Exit actions also occur whenever a state is entered or
* exited, respectively.
*/
class State_2 : public StateMachine::StateBase {
public:
/**
* @brief Declaration for Complex::State_2::ChildState : /c/v/K
*
* States contain other states and can consume generic
* StateMachine::Event objects if they have internal or external
* transitions on those events and if those transitions' guards are
* satisfied. Only one transition can consume an event in a given
* state machine.
*
* There is also a different kind of Event, the tick event, which is
* not consumed, but instead executes from the top-level state all
* the way to the curently active leaf state.
*
* Entry and Exit actions also occur whenever a state is entered or
* exited, respectively.
*/
class ChildState : public StateMachine::StateBase {
public:
// Timer period
static const double timerPeriod;
// Constructors
ChildState ( void ) : StateBase( ) {}
ChildState ( StateBase* _parent ) : StateBase( _parent ) {}
~ChildState ( void ) {}
/**
* @brief Calls entry() then handles any child
* initialization. Finally calls makeActive on the leaf.
*/
void initialize ( void );
/**
* @brief Runs the entry() function defined in the model.
*/
void entry ( void );
/**
* @brief Runs the exit() function defined in the model.
*/
void exit ( void );
/**
* @brief Runs the tick() function defined in the model and then
* calls _activeState->tick().
*/
void tick ( void );
/**
* @brief The timer period of the state in floating point seconds.
*
* @return double timer period
*/
double getTimerPeriod ( void );
/**
* @brief Calls _activeState->handleEvent( event ), then if the
* event is not nullptr (meaning the event was not consumed by
* the child subtree), it checks the event against all internal
* transitions associated with that Event. If the event is still
* not a nullptr (meaning the event was not consumed by the
* internal transitions), then it checks the event against all
* external transitions associated with that Event.
*
* @param[in] StateMachine::Event* Event needing to be handled
*
* @return true if event is consumed, false otherwise
*/
bool handleEvent ( StateMachine::Event* event );
};
/**
* @brief Declaration for Complex::State_2::ChildState2 : /c/v/e
*
* States contain other states and can consume generic
* StateMachine::Event objects if they have internal or external
* transitions on those events and if those transitions' guards are
* satisfied. Only one transition can consume an event in a given
* state machine.
*
* There is also a different kind of Event, the tick event, which is
* not consumed, but instead executes from the top-level state all
* the way to the curently active leaf state.
*
* Entry and Exit actions also occur whenever a state is entered or
* exited, respectively.
*/
class ChildState2 : public StateMachine::StateBase {
public:
// Timer period
static const double timerPeriod;
// Constructors
ChildState2 ( void ) : StateBase( ) {}
ChildState2 ( StateBase* _parent ) : StateBase( _parent ) {}
~ChildState2 ( void ) {}
/**
* @brief Calls entry() then handles any child
* initialization. Finally calls makeActive on the leaf.
*/
void initialize ( void );
/**
* @brief Runs the entry() function defined in the model.
*/
void entry ( void );
/**
* @brief Runs the exit() function defined in the model.
*/
void exit ( void );
/**
* @brief Runs the tick() function defined in the model and then
* calls _activeState->tick().
*/
void tick ( void );
/**
* @brief The timer period of the state in floating point seconds.
*
* @return double timer period
*/
double getTimerPeriod ( void );
/**
* @brief Calls _activeState->handleEvent( event ), then if the
* event is not nullptr (meaning the event was not consumed by
* the child subtree), it checks the event against all internal
* transitions associated with that Event. If the event is still
* not a nullptr (meaning the event was not consumed by the
* internal transitions), then it checks the event against all
* external transitions associated with that Event.
*
* @param[in] StateMachine::Event* Event needing to be handled
*
* @return true if event is consumed, false otherwise
*/
bool handleEvent ( StateMachine::Event* event );
};
/**
* @brief Declaration for Complex::State_2::ChildState3 : /c/v/z
*
* States contain other states and can consume generic
* StateMachine::Event objects if they have internal or external
* transitions on those events and if those transitions' guards are
* satisfied. Only one transition can consume an event in a given
* state machine.
*
* There is also a different kind of Event, the tick event, which is
* not consumed, but instead executes from the top-level state all
* the way to the curently active leaf state.
*
* Entry and Exit actions also occur whenever a state is entered or
* exited, respectively.
*/
class ChildState3 : public StateMachine::StateBase {
public:
/**
* @brief Declaration for Complex::State_2::ChildState3::Grand : /c/v/z/6
*
* States contain other states and can consume generic
* StateMachine::Event objects if they have internal or external
* transitions on those events and if those transitions' guards are
* satisfied. Only one transition can consume an event in a given
* state machine.
*
* There is also a different kind of Event, the tick event, which is
* not consumed, but instead executes from the top-level state all
* the way to the curently active leaf state.
*
* Entry and Exit actions also occur whenever a state is entered or
* exited, respectively.
*/
class Grand : public StateMachine::StateBase {
public:
// Timer period
static const double timerPeriod;
// Constructors
Grand ( void ) : StateBase( ) {}
Grand ( StateBase* _parent ) : StateBase( _parent ) {}
~Grand ( void ) {}
/**
* @brief Calls entry() then handles any child
* initialization. Finally calls makeActive on the leaf.
*/
void initialize ( void );
/**
* @brief Runs the entry() function defined in the model.
*/
void entry ( void );
/**
* @brief Runs the exit() function defined in the model.
*/
void exit ( void );
/**
* @brief Runs the tick() function defined in the model and then
* calls _activeState->tick().
*/
void tick ( void );
/**
* @brief The timer period of the state in floating point seconds.
*
* @return double timer period
*/
double getTimerPeriod ( void );
/**
* @brief Calls _activeState->handleEvent( event ), then if the
* event is not nullptr (meaning the event was not consumed by
* the child subtree), it checks the event against all internal
* transitions associated with that Event. If the event is still
* not a nullptr (meaning the event was not consumed by the
* internal transitions), then it checks the event against all
* external transitions associated with that Event.
*
* @param[in] StateMachine::Event* Event needing to be handled
*
* @return true if event is consumed, false otherwise
*/
bool handleEvent ( StateMachine::Event* event );
};
/**
* @brief Declaration for Complex::State_2::ChildState3::Grand2 : /c/v/z/c
*
* States contain other states and can consume generic
* StateMachine::Event objects if they have internal or external
* transitions on those events and if those transitions' guards are
* satisfied. Only one transition can consume an event in a given
* state machine.
*
* There is also a different kind of Event, the tick event, which is
* not consumed, but instead executes from the top-level state all
* the way to the curently active leaf state.
*
* Entry and Exit actions also occur whenever a state is entered or
* exited, respectively.
*/
class Grand2 : public StateMachine::StateBase {
public:
// Timer period
static const double timerPeriod;
// Constructors
Grand2 ( void ) : StateBase( ) {}
Grand2 ( StateBase* _parent ) : StateBase( _parent ) {}
~Grand2 ( void ) {}
/**
* @brief Calls entry() then handles any child
* initialization. Finally calls makeActive on the leaf.
*/
void initialize ( void );
/**
* @brief Runs the entry() function defined in the model.
*/
void entry ( void );
/**
* @brief Runs the exit() function defined in the model.
*/
void exit ( void );
/**
* @brief Runs the tick() function defined in the model and then
* calls _activeState->tick().
*/
void tick ( void );
/**
* @brief The timer period of the state in floating point seconds.
*
* @return double timer period
*/
double getTimerPeriod ( void );
/**
* @brief Calls _activeState->handleEvent( event ), then if the
* event is not nullptr (meaning the event was not consumed by
* the child subtree), it checks the event against all internal
* transitions associated with that Event. If the event is still
* not a nullptr (meaning the event was not consumed by the
* internal transitions), then it checks the event against all
* external transitions associated with that Event.
*
* @param[in] StateMachine::Event* Event needing to be handled
*
* @return true if event is consumed, false otherwise
*/
bool handleEvent ( StateMachine::Event* event );
};
// Timer period
static const double timerPeriod;
// Constructors
ChildState3 ( void ) : StateBase( ) {}
ChildState3 ( StateBase* _parent ) : StateBase( _parent ) {}
~ChildState3 ( void ) {}
/**
* @brief Calls entry() then handles any child
* initialization. Finally calls makeActive on the leaf.
*/
void initialize ( void );
/**
* @brief Runs the entry() function defined in the model.
*/
void entry ( void );
/**
* @brief Runs the exit() function defined in the model.
*/
void exit ( void );
/**
* @brief Runs the tick() function defined in the model and then
* calls _activeState->tick().
*/
void tick ( void );
/**
* @brief The timer period of the state in floating point seconds.
*
* @return double timer period
*/
double getTimerPeriod ( void );
/**
* @brief Calls _activeState->handleEvent( event ), then if the
* event is not nullptr (meaning the event was not consumed by
* the child subtree), it checks the event against all internal
* transitions associated with that Event. If the event is still
* not a nullptr (meaning the event was not consumed by the
* internal transitions), then it checks the event against all
* external transitions associated with that Event.
*
* @param[in] StateMachine::Event* Event needing to be handled
*
* @return true if event is consumed, false otherwise
*/
bool handleEvent ( StateMachine::Event* event );
};
// Timer period
static const double timerPeriod;
// Constructors
State_2 ( void ) : StateBase( ) {}
State_2 ( StateBase* _parent ) : StateBase( _parent ) {}
~State_2 ( void ) {}
/**
* @brief Calls entry() then handles any child
* initialization. Finally calls makeActive on the leaf.
*/
void initialize ( void );
/**
* @brief Runs the entry() function defined in the model.
*/
void entry ( void );
/**
* @brief Runs the exit() function defined in the model.
*/
void exit ( void );
/**
* @brief Runs the tick() function defined in the model and then
* calls _activeState->tick().
*/
void tick ( void );
/**
* @brief The timer period of the state in floating point seconds.
*
* @return double timer period
*/
double getTimerPeriod ( void );
/**
* @brief Calls _activeState->handleEvent( event ), then if the
* event is not nullptr (meaning the event was not consumed by
* the child subtree), it checks the event against all internal
* transitions associated with that Event. If the event is still
* not a nullptr (meaning the event was not consumed by the
* internal transitions), then it checks the event against all
* external transitions associated with that Event.
*
* @param[in] StateMachine::Event* Event needing to be handled
*
* @return true if event is consumed, false otherwise
*/
bool handleEvent ( StateMachine::Event* event );
};
/**
* @brief Declaration for Complex::State3 : /c/T
*
* States contain other states and can consume generic
* StateMachine::Event objects if they have internal or external
* transitions on those events and if those transitions' guards are
* satisfied. Only one transition can consume an event in a given
* state machine.
*
* There is also a different kind of Event, the tick event, which is
* not consumed, but instead executes from the top-level state all
* the way to the curently active leaf state.
*
* Entry and Exit actions also occur whenever a state is entered or
* exited, respectively.
*/
class State3 : public StateMachine::StateBase {
public:
/**
* @brief Declaration for Complex::State3::ChildState2 : /c/T/0
*
* States contain other states and can consume generic
* StateMachine::Event objects if they have internal or external
* transitions on those events and if those transitions' guards are
* satisfied. Only one transition can consume an event in a given
* state machine.
*
* There is also a different kind of Event, the tick event, which is
* not consumed, but instead executes from the top-level state all
* the way to the curently active leaf state.
*
* Entry and Exit actions also occur whenever a state is entered or
* exited, respectively.
*/
class ChildState2 : public StateMachine::StateBase {
public:
// Timer period
static const double timerPeriod;
// Constructors
ChildState2 ( void ) : StateBase( ) {}
ChildState2 ( StateBase* _parent ) : StateBase( _parent ) {}
~ChildState2 ( void ) {}
/**
* @brief Calls entry() then handles any child
* initialization. Finally calls makeActive on the leaf.
*/
void initialize ( void );
/**
* @brief Runs the entry() function defined in the model.
*/
void entry ( void );
/**
* @brief Runs the exit() function defined in the model.
*/
void exit ( void );
/**
* @brief Runs the tick() function defined in the model and then
* calls _activeState->tick().
*/
void tick ( void );
/**
* @brief The timer period of the state in floating point seconds.
*
* @return double timer period
*/
double getTimerPeriod ( void );
/**
* @brief Calls _activeState->handleEvent( event ), then if the
* event is not nullptr (meaning the event was not consumed by
* the child subtree), it checks the event against all internal
* transitions associated with that Event. If the event is still
* not a nullptr (meaning the event was not consumed by the
* internal transitions), then it checks the event against all
* external transitions associated with that Event.
*
* @param[in] StateMachine::Event* Event needing to be handled
*
* @return true if event is consumed, false otherwise
*/
bool handleEvent ( StateMachine::Event* event );
};
/**
* @brief Declaration for Complex::State3::ChildState : /c/T/W
*
* States contain other states and can consume generic
* StateMachine::Event objects if they have internal or external
* transitions on those events and if those transitions' guards are
* satisfied. Only one transition can consume an event in a given
* state machine.
*
* There is also a different kind of Event, the tick event, which is
* not consumed, but instead executes from the top-level state all
* the way to the curently active leaf state.
*
* Entry and Exit actions also occur whenever a state is entered or
* exited, respectively.
*/
class ChildState : public StateMachine::StateBase {
public:
// Timer period
static const double timerPeriod;
// Constructors
ChildState ( void ) : StateBase( ) {}
ChildState ( StateBase* _parent ) : StateBase( _parent ) {}
~ChildState ( void ) {}
/**
* @brief Calls entry() then handles any child
* initialization. Finally calls makeActive on the leaf.
*/
void initialize ( void );
/**
* @brief Runs the entry() function defined in the model.
*/
void entry ( void );
/**
* @brief Runs the exit() function defined in the model.
*/
void exit ( void );
/**
* @brief Runs the tick() function defined in the model and then
* calls _activeState->tick().
*/
void tick ( void );
/**
* @brief The timer period of the state in floating point seconds.
*
* @return double timer period
*/
double getTimerPeriod ( void );
/**
* @brief Calls _activeState->handleEvent( event ), then if the
* event is not nullptr (meaning the event was not consumed by
* the child subtree), it checks the event against all internal
* transitions associated with that Event. If the event is still
* not a nullptr (meaning the event was not consumed by the
* internal transitions), then it checks the event against all
* external transitions associated with that Event.
*
* @param[in] StateMachine::Event* Event needing to be handled
*
* @return true if event is consumed, false otherwise
*/
bool handleEvent ( StateMachine::Event* event );
};
/**
* @brief Declaration for Complex::State3::ChildState3 : /c/T/w
*
* States contain other states and can consume generic
* StateMachine::Event objects if they have internal or external
* transitions on those events and if those transitions' guards are
* satisfied. Only one transition can consume an event in a given
* state machine.
*
* There is also a different kind of Event, the tick event, which is
* not consumed, but instead executes from the top-level state all
* the way to the curently active leaf state.
*
* Entry and Exit actions also occur whenever a state is entered or
* exited, respectively.
*/
class ChildState3 : public StateMachine::StateBase {
public:
// Timer period
static const double timerPeriod;
// Constructors
ChildState3 ( void ) : StateBase( ) {}
ChildState3 ( StateBase* _parent ) : StateBase( _parent ) {}
~ChildState3 ( void ) {}
/**
* @brief Calls entry() then handles any child
* initialization. Finally calls makeActive on the leaf.
*/
void initialize ( void );
/**
* @brief Runs the entry() function defined in the model.
*/
void entry ( void );
/**
* @brief Runs the exit() function defined in the model.
*/
void exit ( void );
/**
* @brief Runs the tick() function defined in the model and then
* calls _activeState->tick().
*/
void tick ( void );
/**
* @brief The timer period of the state in floating point seconds.
*
* @return double timer period
*/
double getTimerPeriod ( void );
/**
* @brief Calls _activeState->handleEvent( event ), then if the
* event is not nullptr (meaning the event was not consumed by
* the child subtree), it checks the event against all internal
* transitions associated with that Event. If the event is still
* not a nullptr (meaning the event was not consumed by the
* internal transitions), then it checks the event against all
* external transitions associated with that Event.
*
* @param[in] StateMachine::Event* Event needing to be handled
*
* @return true if event is consumed, false otherwise
*/
bool handleEvent ( StateMachine::Event* event );
};
// Timer period
static const double timerPeriod;
// Constructors
State3 ( void ) : StateBase( ) {}
State3 ( StateBase* _parent ) : StateBase( _parent ) {}
~State3 ( void ) {}
/**
* @brief Calls entry() then handles any child
* initialization. Finally calls makeActive on the leaf.
*/
void initialize ( void );
/**
* @brief Runs the entry() function defined in the model.
*/
void entry ( void );
/**
* @brief Runs the exit() function defined in the model.
*/
void exit ( void );
/**
* @brief Runs the tick() function defined in the model and then
* calls _activeState->tick().
*/
void tick ( void );
/**
* @brief The timer period of the state in floating point seconds.
*
* @return double timer period
*/
double getTimerPeriod ( void );
/**
* @brief Calls _activeState->handleEvent( event ), then if the
* event is not nullptr (meaning the event was not consumed by
* the child subtree), it checks the event against all internal
* transitions associated with that Event. If the event is still
* not a nullptr (meaning the event was not consumed by the
* internal transitions), then it checks the event against all
* external transitions associated with that Event.
*
* @param[in] StateMachine::Event* Event needing to be handled
*
* @return true if event is consumed, false otherwise
*/
bool handleEvent ( StateMachine::Event* event );
};
// END STATE
/**
* @brief This is the terminal END STATE for the HFSM, after which no
* events or other actions will be processed.
*/
class End_State : public StateMachine::StateBase {
public:
/**
* @brief Empty function for the END STATE.
*/
void entry ( void ) {}
/**
* @brief Empty function for the END STATE.
*/
void exit ( void ) {}
/**
* @brief Empty function for the END STATE.
*/
void tick ( void ) {}
/**
* @brief Empty function for the END STATE. Simply returns true
* since the END STATE trivially handles all events.
*
* @return true
*/
bool handleEvent ( StateMachine::Event* event ) { return true; }
};
// Constructors
Complex ( void ) : StateBase( ) {}
Complex ( StateBase* _parent ) : StateBase( _parent ) {}
~Complex ( void ) {}
/**
* @brief Fully initializes the HFSM. Runs the HFSM Initialization
* code from the model, then sets the inital state and runs the
* initial transition and entry actions accordingly.
*/
void initialize ( void );
/**
* @brief Terminates the HFSM, calling exit functions for the
* active leaf state upwards through its parents all the way to
* the root.
*/
void terminate ( void );
/**
* @brief Restarts the HFSM by calling terminate and then
* initialize.
*/
void restart ( void );
/**
* @brief Returns true if the HFSM has reached its END State
*/
bool hasStopped ( void );
/**
* @brief Calls handleEvent on the activeLeaf.
*
* @param[in] StateMachine::Event* Event needing to be handled
*
* @return true if event is consumed, false otherwise
*/
bool handleEvent ( StateMachine::Event* event );
};
};
// pointers
extern StateMachine::Complex *const Complex_root;
extern StateMachine::Complex *const COMPLEX_OBJ;
extern StateMachine::Complex::State_1 *const COMPLEX_OBJ__STATE_1_OBJ;
extern StateMachine::Complex::State_2 *const COMPLEX_OBJ__STATE_2_OBJ;
extern StateMachine::Complex::State_2::ChildState *const COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE_OBJ;
extern StateMachine::DeepHistoryState *const COMPLEX_OBJ__STATE_2_OBJ__DEEP_HISTORY_PSEUDOSTATE_OBJ;
extern StateMachine::Complex::State_2::ChildState2 *const COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE2_OBJ;
extern StateMachine::Complex::State_2::ChildState3 *const COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ;
extern StateMachine::Complex::State_2::ChildState3::Grand *const COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND_OBJ;
extern StateMachine::Complex::State_2::ChildState3::Grand2 *const COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ;
extern StateMachine::ShallowHistoryState *const COMPLEX_OBJ__STATE_2_OBJ__SHALLOW_HISTORY_PSEUDOSTATE_OBJ;
extern StateMachine::Complex::State3 *const COMPLEX_OBJ__STATE3_OBJ;
extern StateMachine::Complex::State3::ChildState2 *const COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE2_OBJ;
extern StateMachine::ShallowHistoryState *const COMPLEX_OBJ__STATE3_OBJ__SHALLOW_HISTORY_PSEUDOSTATE_OBJ;
extern StateMachine::DeepHistoryState *const COMPLEX_OBJ__STATE3_OBJ__DEEP_HISTORY_PSEUDOSTATE_OBJ;
extern StateMachine::Complex::State3::ChildState *const COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE_OBJ;
extern StateMachine::Complex::State3::ChildState3 *const COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE3_OBJ;
extern StateMachine::StateBase *const COMPLEX_OBJ__END_STATE_OBJ;
#endif // __GENERATED_STATES_INCLUDE_GUARD__
#include "Complex_Events.hpp"
#include "Complex_GeneratedStates.hpp"
#ifdef DEBUG_OUTPUT
#include <iostream>
#endif
namespace StateMachine {
StateMachine::Complex COMPLEX_OBJ_stateObj;
StateMachine::Complex *const COMPLEX_OBJ = &COMPLEX_OBJ_stateObj;
StateMachine::Complex::State_1 COMPLEX_OBJ__STATE_1_OBJ_stateObj( COMPLEX_OBJ );
StateMachine::Complex::State_1 *const COMPLEX_OBJ__STATE_1_OBJ = &COMPLEX_OBJ__STATE_1_OBJ_stateObj;
StateMachine::Complex::State_2 COMPLEX_OBJ__STATE_2_OBJ_stateObj( COMPLEX_OBJ );
StateMachine::Complex::State_2 *const COMPLEX_OBJ__STATE_2_OBJ = &COMPLEX_OBJ__STATE_2_OBJ_stateObj;
StateMachine::Complex::State_2::ChildState COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE_OBJ_stateObj( COMPLEX_OBJ__STATE_2_OBJ );
StateMachine::Complex::State_2::ChildState *const COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE_OBJ = &COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE_OBJ_stateObj;
StateMachine::DeepHistoryState COMPLEX_OBJ__STATE_2_OBJ__DEEP_HISTORY_PSEUDOSTATE_OBJ_stateObj( COMPLEX_OBJ__STATE_2_OBJ );
StateMachine::DeepHistoryState *const COMPLEX_OBJ__STATE_2_OBJ__DEEP_HISTORY_PSEUDOSTATE_OBJ = &COMPLEX_OBJ__STATE_2_OBJ__DEEP_HISTORY_PSEUDOSTATE_OBJ_stateObj;
StateMachine::Complex::State_2::ChildState2 COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE2_OBJ_stateObj( COMPLEX_OBJ__STATE_2_OBJ );
StateMachine::Complex::State_2::ChildState2 *const COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE2_OBJ = &COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE2_OBJ_stateObj;
StateMachine::Complex::State_2::ChildState3 COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ_stateObj( COMPLEX_OBJ__STATE_2_OBJ );
StateMachine::Complex::State_2::ChildState3 *const COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ = &COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ_stateObj;
StateMachine::Complex::State_2::ChildState3::Grand COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND_OBJ_stateObj( COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ );
StateMachine::Complex::State_2::ChildState3::Grand *const COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND_OBJ = &COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND_OBJ_stateObj;
StateMachine::Complex::State_2::ChildState3::Grand2 COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ_stateObj( COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ );
StateMachine::Complex::State_2::ChildState3::Grand2 *const COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ = &COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ_stateObj;
StateMachine::ShallowHistoryState COMPLEX_OBJ__STATE_2_OBJ__SHALLOW_HISTORY_PSEUDOSTATE_OBJ_stateObj( COMPLEX_OBJ__STATE_2_OBJ );
StateMachine::ShallowHistoryState *const COMPLEX_OBJ__STATE_2_OBJ__SHALLOW_HISTORY_PSEUDOSTATE_OBJ = &COMPLEX_OBJ__STATE_2_OBJ__SHALLOW_HISTORY_PSEUDOSTATE_OBJ_stateObj;
StateMachine::Complex::State3 COMPLEX_OBJ__STATE3_OBJ_stateObj( COMPLEX_OBJ );
StateMachine::Complex::State3 *const COMPLEX_OBJ__STATE3_OBJ = &COMPLEX_OBJ__STATE3_OBJ_stateObj;
StateMachine::Complex::State3::ChildState2 COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE2_OBJ_stateObj( COMPLEX_OBJ__STATE3_OBJ );
StateMachine::Complex::State3::ChildState2 *const COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE2_OBJ = &COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE2_OBJ_stateObj;
StateMachine::ShallowHistoryState COMPLEX_OBJ__STATE3_OBJ__SHALLOW_HISTORY_PSEUDOSTATE_OBJ_stateObj( COMPLEX_OBJ__STATE3_OBJ );
StateMachine::ShallowHistoryState *const COMPLEX_OBJ__STATE3_OBJ__SHALLOW_HISTORY_PSEUDOSTATE_OBJ = &COMPLEX_OBJ__STATE3_OBJ__SHALLOW_HISTORY_PSEUDOSTATE_OBJ_stateObj;
StateMachine::DeepHistoryState COMPLEX_OBJ__STATE3_OBJ__DEEP_HISTORY_PSEUDOSTATE_OBJ_stateObj( COMPLEX_OBJ__STATE3_OBJ );
StateMachine::DeepHistoryState *const COMPLEX_OBJ__STATE3_OBJ__DEEP_HISTORY_PSEUDOSTATE_OBJ = &COMPLEX_OBJ__STATE3_OBJ__DEEP_HISTORY_PSEUDOSTATE_OBJ_stateObj;
StateMachine::Complex::State3::ChildState COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE_OBJ_stateObj( COMPLEX_OBJ__STATE3_OBJ );
StateMachine::Complex::State3::ChildState *const COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE_OBJ = &COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE_OBJ_stateObj;
StateMachine::Complex::State3::ChildState3 COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE3_OBJ_stateObj( COMPLEX_OBJ__STATE3_OBJ );
StateMachine::Complex::State3::ChildState3 *const COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE3_OBJ = &COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE3_OBJ_stateObj;
StateMachine::StateBase COMPLEX_OBJ__END_STATE_OBJ_stateObj( COMPLEX_OBJ );
StateMachine::StateBase *const COMPLEX_OBJ__END_STATE_OBJ = &COMPLEX_OBJ__END_STATE_OBJ_stateObj;
// User Definitions for the HFSM
//::::/c::::Definitions::::
bool Complex::goToEnd = false;
bool Complex::goToChoice = true;
bool Complex::goToHistory = false;
bool Complex::nextState = false;
bool Complex::killedState = false;
bool Complex::someGuard = true;
bool Complex::someTest = true;
int Complex::someNumber = 40;
int Complex::someValue = 50;
/* * * Definitions for Complex : /c * * */
// Generated Definitions for the root state
void Complex::initialize ( void ) {
// Run the model's Initialization code
#ifdef DEBUG_OUTPUT
std::cout << "Complex:/c HFSM Initialization" << std::endl;
#endif
//::::/c::::Initialization::::
// now set the states up properly
// External Transition : Action for: /c/m
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/m" << std::endl;
#endif
//::::/c/m::::Action::::
// State : entry for: /c/Y
COMPLEX_OBJ__STATE_1_OBJ->entry();
// initialize our new active state
COMPLEX_OBJ__STATE_1_OBJ->initialize();
};
void Complex::terminate ( void ) {
// will call exit() and exitChildren() on _activeState if it
// exists
exitChildren();
};
void Complex::restart ( void ) {
terminate();
initialize();
};
bool Complex::hasStopped ( void ) {
bool reachedEnd = false;
// Get the currently active leaf state
StateMachine::StateBase* activeLeaf = getActiveLeaf();
if (activeLeaf != nullptr && activeLeaf != this && activeLeaf == COMPLEX_OBJ__END_STATE_OBJ) {
reachedEnd = true;
}
return reachedEnd;
};
bool Complex::handleEvent ( StateMachine::Event* event ) {
bool handled = false;
// Get the currently active leaf state
StateMachine::StateBase* activeLeaf = getActiveLeaf();
if (activeLeaf != nullptr && activeLeaf != this) {
// have the active leaf handle the event, this will bubble up until
// the event is handled or it reaches the root.
handled = activeLeaf->handleEvent( event );
}
return handled;
}
/* * * Definitions for Complex::State_1 : /c/Y * * */
// Timer period
const double Complex::State_1::timerPeriod = 0.1;
void Complex::State_1::initialize ( void ) {
// if we're a leaf state, make sure we're active
makeActive();
}
void Complex::State_1::entry ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "ENTRY::Complex::State_1::/c/Y" << std::endl;
#endif
// Entry action for this state
//::::/c/Y::::Entry::::
int a = 2;
printf("SerialTask :: initializing State 1\n");
}
void Complex::State_1::exit ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "EXIT::Complex::State_1::/c/Y" << std::endl;
#endif
// Call the Exit Action for this state
//::::/c/Y::::Exit::::
printf("Exiting State 1\n");
}
void Complex::State_1::tick ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "TICK::Complex::State_1::/c/Y" << std::endl;
#endif
// Call the Tick Action for this state
//::::/c/Y::::Tick::::
printf("SerialTask::State 1::tick()\n");
if ( _activeState != nullptr && _activeState != this )
_activeState->tick();
}
double Complex::State_1::getTimerPeriod ( void ) {
return timerPeriod;
}
bool Complex::State_1::handleEvent ( StateMachine::Event* event ) {
bool handled = false;
// take care of all event types that this branch will not handle -
// for more consistent run-time performnace
switch ( event->type() ) {
case Event::Type::ENDEVENT:
handled = true;
break;
case Event::Type::EVENT3:
handled = true;
break;
default:
break;
}
if (handled) {
// we didn't actually handle the event, but return anyway
return false;
}
// handle internal transitions first
switch ( event->type() ) {
case Event::Type::EVENT1:
if ( false ) { // makes generation easier :)
}
//::::/c/Y/t::::Guard::::
else if ( someNumber < someValue ) {
#ifdef DEBUG_OUTPUT
std::cout << "GUARD [ someNumber < someValue ] for INTERNAL TRANSITION:/c/Y/t evaluated to TRUE" << std::endl;
#endif
// run transition action
//::::/c/Y/t::::Action::::
int testVal = 32;
for (int i=0; i<testVal; i++) {
printf("Action iterating: %d\n", i);
}
// make sure nothing else handles this event
handled = true;
}
break;
case Event::Type::EVENT2:
if ( false ) { // makes generation easier :)
}
//::::/c/Y/X::::Guard::::
else if ( someNumber > someValue ) {
#ifdef DEBUG_OUTPUT
std::cout << "GUARD [ someNumber > someValue ] for INTERNAL TRANSITION:/c/Y/X evaluated to TRUE" << std::endl;
#endif
// run transition action
//::::/c/Y/X::::Action::::
// make sure nothing else handles this event
handled = true;
}
break;
default:
break;
}
if (!handled) {
// handle external transitions here
switch ( event->type() ) {
case Event::Type::EVENT4:
if ( false ) { } // makes generation easier :)
//::::/c/I::::Guard::::
else if ( someTest ) {
#ifdef DEBUG_OUTPUT
std::cout << "GUARD [ someTest ] for EXTERNAL TRANSITION:/c/I evaluated to TRUE" << std::endl;
#endif
// Going into a choice pseudo-state, let it handle its
// guards and perform the state transition
if (false) { } // makes geneeration easier :)
//::::/c/h::::Guard::::
else if ( goToHistory ) {
#ifdef DEBUG_OUTPUT
std::cout << "GUARD [ goToHistory ] for EXTERNAL TRANSITION:/c/h evaluated to TRUE" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_1_OBJ->exitChildren();
// State : exit for: /c/Y
COMPLEX_OBJ__STATE_1_OBJ->exit();
// External Transition : Action for: /c/I
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/I" << std::endl;
#endif
//::::/c/I::::Action::::
// External Transition : Action for: /c/h
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/h" << std::endl;
#endif
//::::/c/h::::Action::::
// State : entry for: /c/T
COMPLEX_OBJ__STATE3_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_1->Complex::State3::Shallow_History_Pseudostate" << std::endl;
#endif
// going into shallow history pseudo-state
COMPLEX_OBJ__STATE3_OBJ->setShallowHistory();
// make sure nothing else handles this event
handled = true;
}
//::::/c/k::::Guard::::
else if ( nextState ) {
#ifdef DEBUG_OUTPUT
std::cout << "GUARD [ nextState ] for EXTERNAL TRANSITION:/c/k evaluated to TRUE" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_1_OBJ->exitChildren();
// State : exit for: /c/Y
COMPLEX_OBJ__STATE_1_OBJ->exit();
// External Transition : Action for: /c/I
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/I" << std::endl;
#endif
//::::/c/I::::Action::::
// External Transition : Action for: /c/k
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/k" << std::endl;
#endif
//::::/c/k::::Action::::
// State : entry for: /c/v
COMPLEX_OBJ__STATE_2_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_1->Complex::State_2" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE_2_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/o" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_1_OBJ->exitChildren();
// State : exit for: /c/Y
COMPLEX_OBJ__STATE_1_OBJ->exit();
// External Transition : Action for: /c/I
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/I" << std::endl;
#endif
//::::/c/I::::Action::::
// External Transition : Action for: /c/o
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/o" << std::endl;
#endif
//::::/c/o::::Action::::
// State : entry for: /c/T
COMPLEX_OBJ__STATE3_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_1->Complex::State3" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE3_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
}
break;
default:
break;
}
}
// can't buble up, we are a root state.
return handled;
}
/* * * Definitions for Complex::State_2 : /c/v * * */
// Timer period
const double Complex::State_2::timerPeriod = 0;
void Complex::State_2::initialize ( void ) {
// External Transition : Action for: /c/v/u
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/u" << std::endl;
#endif
//::::/c/v/u::::Action::::
// State : entry for: /c/v/K
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE_OBJ->entry();
// initialize our new active state
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE_OBJ->initialize();
}
void Complex::State_2::entry ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "ENTRY::Complex::State_2::/c/v" << std::endl;
#endif
// Entry action for this state
//::::/c/v::::Entry::::
}
void Complex::State_2::exit ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "EXIT::Complex::State_2::/c/v" << std::endl;
#endif
// Call the Exit Action for this state
//::::/c/v::::Exit::::
}
void Complex::State_2::tick ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "TICK::Complex::State_2::/c/v" << std::endl;
#endif
// Call the Tick Action for this state
//::::/c/v::::Tick::::
if ( _activeState != nullptr && _activeState != this )
_activeState->tick();
}
double Complex::State_2::getTimerPeriod ( void ) {
return timerPeriod;
}
bool Complex::State_2::handleEvent ( StateMachine::Event* event ) {
bool handled = false;
// take care of all event types that this branch will not handle -
// for more consistent run-time performnace
switch ( event->type() ) {
case Event::Type::ENDEVENT:
handled = true;
break;
case Event::Type::EVENT1:
handled = true;
break;
default:
break;
}
if (handled) {
// we didn't actually handle the event, but return anyway
return false;
}
// handle internal transitions first
switch ( event->type() ) {
default:
break;
}
if (!handled) {
// handle external transitions here
switch ( event->type() ) {
case Event::Type::EVENT4:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/Q" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ->exitChildren();
// State : exit for: /c/v
COMPLEX_OBJ__STATE_2_OBJ->exit();
// External Transition : Action for: /c/Q
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/Q" << std::endl;
#endif
//::::/c/Q::::Action::::
// State : entry for: /c/T
COMPLEX_OBJ__STATE3_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2->Complex::State3::Deep_History_Pseudostate" << std::endl;
#endif
// going into deep history pseudo-state
COMPLEX_OBJ__STATE3_OBJ->setDeepHistory();
// make sure nothing else handles this event
handled = true;
}
break;
case Event::Type::EVENT2:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/E" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ->exitChildren();
// State : exit for: /c/v
COMPLEX_OBJ__STATE_2_OBJ->exit();
// External Transition : Action for: /c/E
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/E" << std::endl;
#endif
//::::/c/E::::Action::::
// State : entry for: /c/T
COMPLEX_OBJ__STATE3_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2->Complex::State3" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE3_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
break;
case Event::Type::EVENT3:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/t" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ->exitChildren();
// State : exit for: /c/v
COMPLEX_OBJ__STATE_2_OBJ->exit();
// External Transition : Action for: /c/t
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/t" << std::endl;
#endif
//::::/c/t::::Action::::
// State : entry for: /c/T
COMPLEX_OBJ__STATE3_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2->Complex::State3::Shallow_History_Pseudostate" << std::endl;
#endif
// going into shallow history pseudo-state
COMPLEX_OBJ__STATE3_OBJ->setShallowHistory();
// make sure nothing else handles this event
handled = true;
}
break;
default:
break;
}
}
// can't buble up, we are a root state.
return handled;
}
/* * * Definitions for Complex::State_2::ChildState : /c/v/K * * */
// Timer period
const double Complex::State_2::ChildState::timerPeriod = 0.1;
void Complex::State_2::ChildState::initialize ( void ) {
// if we're a leaf state, make sure we're active
makeActive();
}
void Complex::State_2::ChildState::entry ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "ENTRY::Complex::State_2::ChildState::/c/v/K" << std::endl;
#endif
// Entry action for this state
//::::/c/v/K::::Entry::::
}
void Complex::State_2::ChildState::exit ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "EXIT::Complex::State_2::ChildState::/c/v/K" << std::endl;
#endif
// Call the Exit Action for this state
//::::/c/v/K::::Exit::::
}
void Complex::State_2::ChildState::tick ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "TICK::Complex::State_2::ChildState::/c/v/K" << std::endl;
#endif
// Call the Tick Action for this state
//::::/c/v/K::::Tick::::
if ( _activeState != nullptr && _activeState != this )
_activeState->tick();
}
double Complex::State_2::ChildState::getTimerPeriod ( void ) {
return timerPeriod;
}
bool Complex::State_2::ChildState::handleEvent ( StateMachine::Event* event ) {
bool handled = false;
// take care of all event types that this branch will not handle -
// for more consistent run-time performnace
switch ( event->type() ) {
case Event::Type::ENDEVENT:
handled = true;
break;
default:
break;
}
if (handled) {
// we didn't actually handle the event, but return anyway
return false;
}
// handle internal transitions first
switch ( event->type() ) {
default:
break;
}
if (!handled) {
// handle external transitions here
switch ( event->type() ) {
case Event::Type::EVENT1:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/v/S" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE_OBJ->exitChildren();
// State : exit for: /c/v/K
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE_OBJ->exit();
// External Transition : Action for: /c/v/S
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/S" << std::endl;
#endif
//::::/c/v/S::::Action::::
// State : entry for: /c/v/e
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE2_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2::ChildState->Complex::State_2::ChildState2" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE2_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
break;
default:
break;
}
}
if (!handled) {
// now check parent states
handled = _parentState->handleEvent( event );
}
return handled;
}
/* * * Definitions for Complex::State_2::ChildState2 : /c/v/e * * */
// Timer period
const double Complex::State_2::ChildState2::timerPeriod = 0.1;
void Complex::State_2::ChildState2::initialize ( void ) {
// if we're a leaf state, make sure we're active
makeActive();
}
void Complex::State_2::ChildState2::entry ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "ENTRY::Complex::State_2::ChildState2::/c/v/e" << std::endl;
#endif
// Entry action for this state
//::::/c/v/e::::Entry::::
}
void Complex::State_2::ChildState2::exit ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "EXIT::Complex::State_2::ChildState2::/c/v/e" << std::endl;
#endif
// Call the Exit Action for this state
//::::/c/v/e::::Exit::::
}
void Complex::State_2::ChildState2::tick ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "TICK::Complex::State_2::ChildState2::/c/v/e" << std::endl;
#endif
// Call the Tick Action for this state
//::::/c/v/e::::Tick::::
if ( _activeState != nullptr && _activeState != this )
_activeState->tick();
}
double Complex::State_2::ChildState2::getTimerPeriod ( void ) {
return timerPeriod;
}
bool Complex::State_2::ChildState2::handleEvent ( StateMachine::Event* event ) {
bool handled = false;
// take care of all event types that this branch will not handle -
// for more consistent run-time performnace
switch ( event->type() ) {
case Event::Type::ENDEVENT:
handled = true;
break;
case Event::Type::EVENT1:
handled = true;
break;
default:
break;
}
if (handled) {
// we didn't actually handle the event, but return anyway
return false;
}
// handle internal transitions first
switch ( event->type() ) {
default:
break;
}
if (!handled) {
// handle external transitions here
switch ( event->type() ) {
case Event::Type::EVENT2:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/v/W" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE2_OBJ->exitChildren();
// State : exit for: /c/v/e
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE2_OBJ->exit();
// External Transition : Action for: /c/v/W
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/W" << std::endl;
#endif
//::::/c/v/W::::Action::::
// State : entry for: /c/v/z
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2::ChildState2->Complex::State_2::ChildState3" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
break;
default:
break;
}
}
if (!handled) {
// now check parent states
handled = _parentState->handleEvent( event );
}
return handled;
}
/* * * Definitions for Complex::State_2::ChildState3 : /c/v/z * * */
// Timer period
const double Complex::State_2::ChildState3::timerPeriod = 0;
void Complex::State_2::ChildState3::initialize ( void ) {
// External Transition : Action for: /c/v/z/8
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/8" << std::endl;
#endif
//::::/c/v/z/8::::Action::::
// State : entry for: /c/v/z/6
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND_OBJ->entry();
// initialize our new active state
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND_OBJ->initialize();
}
void Complex::State_2::ChildState3::entry ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "ENTRY::Complex::State_2::ChildState3::/c/v/z" << std::endl;
#endif
// Entry action for this state
//::::/c/v/z::::Entry::::
}
void Complex::State_2::ChildState3::exit ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "EXIT::Complex::State_2::ChildState3::/c/v/z" << std::endl;
#endif
// Call the Exit Action for this state
//::::/c/v/z::::Exit::::
}
void Complex::State_2::ChildState3::tick ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "TICK::Complex::State_2::ChildState3::/c/v/z" << std::endl;
#endif
// Call the Tick Action for this state
//::::/c/v/z::::Tick::::
if ( _activeState != nullptr && _activeState != this )
_activeState->tick();
}
double Complex::State_2::ChildState3::getTimerPeriod ( void ) {
return timerPeriod;
}
bool Complex::State_2::ChildState3::handleEvent ( StateMachine::Event* event ) {
bool handled = false;
// take care of all event types that this branch will not handle -
// for more consistent run-time performnace
switch ( event->type() ) {
case Event::Type::ENDEVENT:
handled = true;
break;
case Event::Type::EVENT1:
handled = true;
break;
default:
break;
}
if (handled) {
// we didn't actually handle the event, but return anyway
return false;
}
// handle internal transitions first
switch ( event->type() ) {
default:
break;
}
if (!handled) {
// handle external transitions here
switch ( event->type() ) {
case Event::Type::EVENT3:
if ( false ) { } // makes generation easier :)
//::::/c/v/P::::Guard::::
else if ( someGuard ) {
#ifdef DEBUG_OUTPUT
std::cout << "GUARD [ someGuard ] for EXTERNAL TRANSITION:/c/v/P evaluated to TRUE" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ->exitChildren();
// State : exit for: /c/v/z
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ->exit();
// External Transition : Action for: /c/v/P
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/P" << std::endl;
#endif
//::::/c/v/P::::Action::::
// State : entry for: /c/v/K
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2::ChildState3->Complex::State_2::ChildState" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
break;
default:
break;
}
}
if (!handled) {
// now check parent states
handled = _parentState->handleEvent( event );
}
return handled;
}
/* * * Definitions for Complex::State_2::ChildState3::Grand : /c/v/z/6 * * */
// Timer period
const double Complex::State_2::ChildState3::Grand::timerPeriod = 0.1;
void Complex::State_2::ChildState3::Grand::initialize ( void ) {
// if we're a leaf state, make sure we're active
makeActive();
}
void Complex::State_2::ChildState3::Grand::entry ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "ENTRY::Complex::State_2::ChildState3::Grand::/c/v/z/6" << std::endl;
#endif
// Entry action for this state
//::::/c/v/z/6::::Entry::::
}
void Complex::State_2::ChildState3::Grand::exit ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "EXIT::Complex::State_2::ChildState3::Grand::/c/v/z/6" << std::endl;
#endif
// Call the Exit Action for this state
//::::/c/v/z/6::::Exit::::
}
void Complex::State_2::ChildState3::Grand::tick ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "TICK::Complex::State_2::ChildState3::Grand::/c/v/z/6" << std::endl;
#endif
// Call the Tick Action for this state
//::::/c/v/z/6::::Tick::::
if ( _activeState != nullptr && _activeState != this )
_activeState->tick();
}
double Complex::State_2::ChildState3::Grand::getTimerPeriod ( void ) {
return timerPeriod;
}
bool Complex::State_2::ChildState3::Grand::handleEvent ( StateMachine::Event* event ) {
bool handled = false;
// take care of all event types that this branch will not handle -
// for more consistent run-time performnace
switch ( event->type() ) {
case Event::Type::ENDEVENT:
handled = true;
break;
default:
break;
}
if (handled) {
// we didn't actually handle the event, but return anyway
return false;
}
// handle internal transitions first
switch ( event->type() ) {
default:
break;
}
if (!handled) {
// handle external transitions here
switch ( event->type() ) {
case Event::Type::EVENT1:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/v/z/z" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND_OBJ->exitChildren();
// State : exit for: /c/v/z/6
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND_OBJ->exit();
// External Transition : Action for: /c/v/z/z
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/z" << std::endl;
#endif
//::::/c/v/z/z::::Action::::
// State : entry for: /c/v/z/c
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2::ChildState3::Grand->Complex::State_2::ChildState3::Grand2" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
break;
default:
break;
}
}
if (!handled) {
// now check parent states
handled = _parentState->handleEvent( event );
}
return handled;
}
/* * * Definitions for Complex::State_2::ChildState3::Grand2 : /c/v/z/c * * */
// Timer period
const double Complex::State_2::ChildState3::Grand2::timerPeriod = 0.1;
void Complex::State_2::ChildState3::Grand2::initialize ( void ) {
// if we're a leaf state, make sure we're active
makeActive();
}
void Complex::State_2::ChildState3::Grand2::entry ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "ENTRY::Complex::State_2::ChildState3::Grand2::/c/v/z/c" << std::endl;
#endif
// Entry action for this state
//::::/c/v/z/c::::Entry::::
}
void Complex::State_2::ChildState3::Grand2::exit ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "EXIT::Complex::State_2::ChildState3::Grand2::/c/v/z/c" << std::endl;
#endif
// Call the Exit Action for this state
//::::/c/v/z/c::::Exit::::
}
void Complex::State_2::ChildState3::Grand2::tick ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "TICK::Complex::State_2::ChildState3::Grand2::/c/v/z/c" << std::endl;
#endif
// Call the Tick Action for this state
//::::/c/v/z/c::::Tick::::
if ( _activeState != nullptr && _activeState != this )
_activeState->tick();
}
double Complex::State_2::ChildState3::Grand2::getTimerPeriod ( void ) {
return timerPeriod;
}
bool Complex::State_2::ChildState3::Grand2::handleEvent ( StateMachine::Event* event ) {
bool handled = false;
// take care of all event types that this branch will not handle -
// for more consistent run-time performnace
switch ( event->type() ) {
default:
break;
}
if (handled) {
// we didn't actually handle the event, but return anyway
return false;
}
// handle internal transitions first
switch ( event->type() ) {
default:
break;
}
if (!handled) {
// handle external transitions here
switch ( event->type() ) {
case Event::Type::ENDEVENT:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/v/z/9" << std::endl;
#endif
// Going into an end pseudo-state that is not the root end state,
// follow its parent end transition
if (false) { }
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/v/F" << std::endl;
#endif
// Going into a choice pseudo-state, let it handle its
// guards and perform the state transition
if (false) { } // makes geneeration easier :)
//::::/c/v/g::::Guard::::
else if ( killedState ) {
#ifdef DEBUG_OUTPUT
std::cout << "GUARD [ killedState ] for EXTERNAL TRANSITION:/c/v/g evaluated to TRUE" << std::endl;
#endif
// Going into an end pseudo-state that is not the root end state,
// follow its parent end transition
if (false) { }
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/F" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exitChildren();
// State : exit for: /c/v/z/c
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exit();
// State : exit for: /c/v/z
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ->exit();
// State : exit for: /c/v
COMPLEX_OBJ__STATE_2_OBJ->exit();
// External Transition : Action for: /c/v/z/9
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/9" << std::endl;
#endif
//::::/c/v/z/9::::Action::::
// External Transition : Action for: /c/v/F
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/F" << std::endl;
#endif
//::::/c/v/F::::Action::::
// External Transition : Action for: /c/v/g
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/g" << std::endl;
#endif
//::::/c/v/g::::Action::::
// External Transition : Action for: /c/F
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/F" << std::endl;
#endif
//::::/c/F::::Action::::
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2::ChildState3::Grand2->Complex::End_State" << std::endl;
#endif
// going into end pseudo-state THIS SHOULD BE TOP LEVEL END STATE
COMPLEX_OBJ__END_STATE_OBJ->makeActive();
// make sure nothing else handles this event
handled = true;
}
}
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/v/2" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exitChildren();
// State : exit for: /c/v/z/c
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exit();
// State : exit for: /c/v/z
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ->exit();
// External Transition : Action for: /c/v/z/9
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/9" << std::endl;
#endif
//::::/c/v/z/9::::Action::::
// External Transition : Action for: /c/v/F
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/F" << std::endl;
#endif
//::::/c/v/F::::Action::::
// External Transition : Action for: /c/v/2
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/2" << std::endl;
#endif
//::::/c/v/2::::Action::::
// State : entry for: /c/v/z
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2::ChildState3::Grand2->Complex::State_2::ChildState3" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
}
}
break;
case Event::Type::EVENT2:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/v/z/R" << std::endl;
#endif
// Going into a choice pseudo-state, let it handle its
// guards and perform the state transition
if (false) { } // makes geneeration easier :)
//::::/c/v/z/j::::Guard::::
else if ( goToEnd ) {
#ifdef DEBUG_OUTPUT
std::cout << "GUARD [ goToEnd ] for EXTERNAL TRANSITION:/c/v/z/j evaluated to TRUE" << std::endl;
#endif
// Going into an end pseudo-state that is not the root end state,
// follow its parent end transition
if (false) { }
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/v/F" << std::endl;
#endif
// Going into a choice pseudo-state, let it handle its
// guards and perform the state transition
if (false) { } // makes geneeration easier :)
//::::/c/v/g::::Guard::::
else if ( killedState ) {
#ifdef DEBUG_OUTPUT
std::cout << "GUARD [ killedState ] for EXTERNAL TRANSITION:/c/v/g evaluated to TRUE" << std::endl;
#endif
// Going into an end pseudo-state that is not the root end state,
// follow its parent end transition
if (false) { }
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/F" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exitChildren();
// State : exit for: /c/v/z/c
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exit();
// State : exit for: /c/v/z
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ->exit();
// State : exit for: /c/v
COMPLEX_OBJ__STATE_2_OBJ->exit();
// External Transition : Action for: /c/v/z/R
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/R" << std::endl;
#endif
//::::/c/v/z/R::::Action::::
// External Transition : Action for: /c/v/z/j
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/j" << std::endl;
#endif
//::::/c/v/z/j::::Action::::
// External Transition : Action for: /c/v/F
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/F" << std::endl;
#endif
//::::/c/v/F::::Action::::
// External Transition : Action for: /c/v/g
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/g" << std::endl;
#endif
//::::/c/v/g::::Action::::
// External Transition : Action for: /c/F
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/F" << std::endl;
#endif
//::::/c/F::::Action::::
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2::ChildState3::Grand2->Complex::End_State" << std::endl;
#endif
// going into end pseudo-state THIS SHOULD BE TOP LEVEL END STATE
COMPLEX_OBJ__END_STATE_OBJ->makeActive();
// make sure nothing else handles this event
handled = true;
}
}
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/v/2" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exitChildren();
// State : exit for: /c/v/z/c
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exit();
// State : exit for: /c/v/z
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ->exit();
// External Transition : Action for: /c/v/z/R
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/R" << std::endl;
#endif
//::::/c/v/z/R::::Action::::
// External Transition : Action for: /c/v/z/j
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/j" << std::endl;
#endif
//::::/c/v/z/j::::Action::::
// External Transition : Action for: /c/v/F
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/F" << std::endl;
#endif
//::::/c/v/F::::Action::::
// External Transition : Action for: /c/v/2
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/2" << std::endl;
#endif
//::::/c/v/2::::Action::::
// State : entry for: /c/v/z
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2::ChildState3::Grand2->Complex::State_2::ChildState3" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
}
}
//::::/c/v/z/g::::Guard::::
else if ( goToChoice ) {
#ifdef DEBUG_OUTPUT
std::cout << "GUARD [ goToChoice ] for EXTERNAL TRANSITION:/c/v/z/g evaluated to TRUE" << std::endl;
#endif
// Going into a choice pseudo-state, let it handle its
// guards and perform the state transition
if (false) { } // makes geneeration easier :)
//::::/c/h::::Guard::::
else if ( goToHistory ) {
#ifdef DEBUG_OUTPUT
std::cout << "GUARD [ goToHistory ] for EXTERNAL TRANSITION:/c/h evaluated to TRUE" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exitChildren();
// State : exit for: /c/v/z/c
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exit();
// State : exit for: /c/v/z
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ->exit();
// State : exit for: /c/v
COMPLEX_OBJ__STATE_2_OBJ->exit();
// External Transition : Action for: /c/v/z/R
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/R" << std::endl;
#endif
//::::/c/v/z/R::::Action::::
// External Transition : Action for: /c/v/z/g
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/g" << std::endl;
#endif
//::::/c/v/z/g::::Action::::
// External Transition : Action for: /c/h
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/h" << std::endl;
#endif
//::::/c/h::::Action::::
// State : entry for: /c/T
COMPLEX_OBJ__STATE3_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2::ChildState3::Grand2->Complex::State3::Shallow_History_Pseudostate" << std::endl;
#endif
// going into shallow history pseudo-state
COMPLEX_OBJ__STATE3_OBJ->setShallowHistory();
// make sure nothing else handles this event
handled = true;
}
//::::/c/k::::Guard::::
else if ( nextState ) {
#ifdef DEBUG_OUTPUT
std::cout << "GUARD [ nextState ] for EXTERNAL TRANSITION:/c/k evaluated to TRUE" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exitChildren();
// State : exit for: /c/v/z/c
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exit();
// State : exit for: /c/v/z
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ->exit();
// State : exit for: /c/v
COMPLEX_OBJ__STATE_2_OBJ->exit();
// External Transition : Action for: /c/v/z/R
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/R" << std::endl;
#endif
//::::/c/v/z/R::::Action::::
// External Transition : Action for: /c/v/z/g
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/g" << std::endl;
#endif
//::::/c/v/z/g::::Action::::
// External Transition : Action for: /c/k
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/k" << std::endl;
#endif
//::::/c/k::::Action::::
// State : entry for: /c/v
COMPLEX_OBJ__STATE_2_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2::ChildState3::Grand2->Complex::State_2" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE_2_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/o" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exitChildren();
// State : exit for: /c/v/z/c
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exit();
// State : exit for: /c/v/z
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ->exit();
// State : exit for: /c/v
COMPLEX_OBJ__STATE_2_OBJ->exit();
// External Transition : Action for: /c/v/z/R
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/R" << std::endl;
#endif
//::::/c/v/z/R::::Action::::
// External Transition : Action for: /c/v/z/g
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/g" << std::endl;
#endif
//::::/c/v/z/g::::Action::::
// External Transition : Action for: /c/o
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/o" << std::endl;
#endif
//::::/c/o::::Action::::
// State : entry for: /c/T
COMPLEX_OBJ__STATE3_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2::ChildState3::Grand2->Complex::State3" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE3_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
}
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/v/z/O" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exitChildren();
// State : exit for: /c/v/z/c
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exit();
// External Transition : Action for: /c/v/z/R
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/R" << std::endl;
#endif
//::::/c/v/z/R::::Action::::
// External Transition : Action for: /c/v/z/O
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/O" << std::endl;
#endif
//::::/c/v/z/O::::Action::::
// State : entry for: /c/v/z/c
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2::ChildState3::Grand2->Complex::State_2::ChildState3::Grand2" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
}
break;
case Event::Type::EVENT1:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/v/z/a" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exitChildren();
// State : exit for: /c/v/z/c
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND2_OBJ->exit();
// External Transition : Action for: /c/v/z/a
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/v/z/a" << std::endl;
#endif
//::::/c/v/z/a::::Action::::
// State : entry for: /c/v/z/6
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State_2::ChildState3::Grand2->Complex::State_2::ChildState3::Grand" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE_2_OBJ__CHILDSTATE3_OBJ__GRAND_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
break;
default:
break;
}
}
if (!handled) {
// now check parent states
handled = _parentState->handleEvent( event );
}
return handled;
}
/* * * Definitions for Complex::State3 : /c/T * * */
// Timer period
const double Complex::State3::timerPeriod = 0;
void Complex::State3::initialize ( void ) {
// External Transition : Action for: /c/T/I
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/T/I" << std::endl;
#endif
//::::/c/T/I::::Action::::
// State : entry for: /c/T/W
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE_OBJ->entry();
// initialize our new active state
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE_OBJ->initialize();
}
void Complex::State3::entry ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "ENTRY::Complex::State3::/c/T" << std::endl;
#endif
// Entry action for this state
//::::/c/T::::Entry::::
}
void Complex::State3::exit ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "EXIT::Complex::State3::/c/T" << std::endl;
#endif
// Call the Exit Action for this state
//::::/c/T::::Exit::::
}
void Complex::State3::tick ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "TICK::Complex::State3::/c/T" << std::endl;
#endif
// Call the Tick Action for this state
//::::/c/T::::Tick::::
if ( _activeState != nullptr && _activeState != this )
_activeState->tick();
}
double Complex::State3::getTimerPeriod ( void ) {
return timerPeriod;
}
bool Complex::State3::handleEvent ( StateMachine::Event* event ) {
bool handled = false;
// take care of all event types that this branch will not handle -
// for more consistent run-time performnace
switch ( event->type() ) {
case Event::Type::EVENT1:
handled = true;
break;
default:
break;
}
if (handled) {
// we didn't actually handle the event, but return anyway
return false;
}
// handle internal transitions first
switch ( event->type() ) {
default:
break;
}
if (!handled) {
// handle external transitions here
switch ( event->type() ) {
case Event::Type::EVENT3:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/C" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE3_OBJ->exitChildren();
// State : exit for: /c/T
COMPLEX_OBJ__STATE3_OBJ->exit();
// External Transition : Action for: /c/C
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/C" << std::endl;
#endif
//::::/c/C::::Action::::
// State : entry for: /c/v
COMPLEX_OBJ__STATE_2_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State3->Complex::State_2::Shallow_History_Pseudostate" << std::endl;
#endif
// going into shallow history pseudo-state
COMPLEX_OBJ__STATE_2_OBJ->setShallowHistory();
// make sure nothing else handles this event
handled = true;
}
break;
case Event::Type::ENDEVENT:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/L" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE3_OBJ->exitChildren();
// State : exit for: /c/T
COMPLEX_OBJ__STATE3_OBJ->exit();
// External Transition : Action for: /c/L
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/L" << std::endl;
#endif
//::::/c/L::::Action::::
// State : entry for: /c/Y
COMPLEX_OBJ__STATE_1_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State3->Complex::State_1" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE_1_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
break;
case Event::Type::EVENT2:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/z" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE3_OBJ->exitChildren();
// State : exit for: /c/T
COMPLEX_OBJ__STATE3_OBJ->exit();
// External Transition : Action for: /c/z
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/z" << std::endl;
#endif
//::::/c/z::::Action::::
// State : entry for: /c/v
COMPLEX_OBJ__STATE_2_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State3->Complex::State_2" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE_2_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
break;
case Event::Type::EVENT4:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/w" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE3_OBJ->exitChildren();
// State : exit for: /c/T
COMPLEX_OBJ__STATE3_OBJ->exit();
// External Transition : Action for: /c/w
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/w" << std::endl;
#endif
//::::/c/w::::Action::::
// State : entry for: /c/v
COMPLEX_OBJ__STATE_2_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State3->Complex::State_2::Deep_History_Pseudostate" << std::endl;
#endif
// going into deep history pseudo-state
COMPLEX_OBJ__STATE_2_OBJ->setDeepHistory();
// make sure nothing else handles this event
handled = true;
}
break;
default:
break;
}
}
// can't buble up, we are a root state.
return handled;
}
/* * * Definitions for Complex::State3::ChildState2 : /c/T/0 * * */
// Timer period
const double Complex::State3::ChildState2::timerPeriod = 0.1;
void Complex::State3::ChildState2::initialize ( void ) {
// if we're a leaf state, make sure we're active
makeActive();
}
void Complex::State3::ChildState2::entry ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "ENTRY::Complex::State3::ChildState2::/c/T/0" << std::endl;
#endif
// Entry action for this state
//::::/c/T/0::::Entry::::
}
void Complex::State3::ChildState2::exit ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "EXIT::Complex::State3::ChildState2::/c/T/0" << std::endl;
#endif
// Call the Exit Action for this state
//::::/c/T/0::::Exit::::
}
void Complex::State3::ChildState2::tick ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "TICK::Complex::State3::ChildState2::/c/T/0" << std::endl;
#endif
// Call the Tick Action for this state
//::::/c/T/0::::Tick::::
if ( _activeState != nullptr && _activeState != this )
_activeState->tick();
}
double Complex::State3::ChildState2::getTimerPeriod ( void ) {
return timerPeriod;
}
bool Complex::State3::ChildState2::handleEvent ( StateMachine::Event* event ) {
bool handled = false;
// take care of all event types that this branch will not handle -
// for more consistent run-time performnace
switch ( event->type() ) {
case Event::Type::EVENT1:
handled = true;
break;
default:
break;
}
if (handled) {
// we didn't actually handle the event, but return anyway
return false;
}
// handle internal transitions first
switch ( event->type() ) {
default:
break;
}
if (!handled) {
// handle external transitions here
switch ( event->type() ) {
case Event::Type::ENDEVENT:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/T/h" << std::endl;
#endif
// Going into an end pseudo-state that is not the root end state,
// follow its parent end transition
if (false) { }
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/A" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE2_OBJ->exitChildren();
// State : exit for: /c/T/0
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE2_OBJ->exit();
// State : exit for: /c/T
COMPLEX_OBJ__STATE3_OBJ->exit();
// External Transition : Action for: /c/T/h
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/T/h" << std::endl;
#endif
//::::/c/T/h::::Action::::
// External Transition : Action for: /c/A
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/A" << std::endl;
#endif
//::::/c/A::::Action::::
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State3::ChildState2->Complex::End_State" << std::endl;
#endif
// going into end pseudo-state THIS SHOULD BE TOP LEVEL END STATE
COMPLEX_OBJ__END_STATE_OBJ->makeActive();
// make sure nothing else handles this event
handled = true;
}
}
break;
case Event::Type::EVENT2:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/T/j" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE2_OBJ->exitChildren();
// State : exit for: /c/T/0
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE2_OBJ->exit();
// External Transition : Action for: /c/T/j
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/T/j" << std::endl;
#endif
//::::/c/T/j::::Action::::
// State : entry for: /c/T/w
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE3_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State3::ChildState2->Complex::State3::ChildState3" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE3_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
break;
default:
break;
}
}
if (!handled) {
// now check parent states
handled = _parentState->handleEvent( event );
}
return handled;
}
/* * * Definitions for Complex::State3::ChildState : /c/T/W * * */
// Timer period
const double Complex::State3::ChildState::timerPeriod = 0.1;
void Complex::State3::ChildState::initialize ( void ) {
// if we're a leaf state, make sure we're active
makeActive();
}
void Complex::State3::ChildState::entry ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "ENTRY::Complex::State3::ChildState::/c/T/W" << std::endl;
#endif
// Entry action for this state
//::::/c/T/W::::Entry::::
}
void Complex::State3::ChildState::exit ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "EXIT::Complex::State3::ChildState::/c/T/W" << std::endl;
#endif
// Call the Exit Action for this state
//::::/c/T/W::::Exit::::
}
void Complex::State3::ChildState::tick ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "TICK::Complex::State3::ChildState::/c/T/W" << std::endl;
#endif
// Call the Tick Action for this state
//::::/c/T/W::::Tick::::
if ( _activeState != nullptr && _activeState != this )
_activeState->tick();
}
double Complex::State3::ChildState::getTimerPeriod ( void ) {
return timerPeriod;
}
bool Complex::State3::ChildState::handleEvent ( StateMachine::Event* event ) {
bool handled = false;
// take care of all event types that this branch will not handle -
// for more consistent run-time performnace
switch ( event->type() ) {
default:
break;
}
if (handled) {
// we didn't actually handle the event, but return anyway
return false;
}
// handle internal transitions first
switch ( event->type() ) {
default:
break;
}
if (!handled) {
// handle external transitions here
switch ( event->type() ) {
case Event::Type::EVENT1:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/T/L" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE_OBJ->exitChildren();
// State : exit for: /c/T/W
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE_OBJ->exit();
// External Transition : Action for: /c/T/L
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/T/L" << std::endl;
#endif
//::::/c/T/L::::Action::::
// State : entry for: /c/T/0
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE2_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State3::ChildState->Complex::State3::ChildState2" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE2_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
break;
default:
break;
}
}
if (!handled) {
// now check parent states
handled = _parentState->handleEvent( event );
}
return handled;
}
/* * * Definitions for Complex::State3::ChildState3 : /c/T/w * * */
// Timer period
const double Complex::State3::ChildState3::timerPeriod = 0.1;
void Complex::State3::ChildState3::initialize ( void ) {
// if we're a leaf state, make sure we're active
makeActive();
}
void Complex::State3::ChildState3::entry ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "ENTRY::Complex::State3::ChildState3::/c/T/w" << std::endl;
#endif
// Entry action for this state
//::::/c/T/w::::Entry::::
}
void Complex::State3::ChildState3::exit ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "EXIT::Complex::State3::ChildState3::/c/T/w" << std::endl;
#endif
// Call the Exit Action for this state
//::::/c/T/w::::Exit::::
}
void Complex::State3::ChildState3::tick ( void ) {
#ifdef DEBUG_OUTPUT
std::cout << "TICK::Complex::State3::ChildState3::/c/T/w" << std::endl;
#endif
// Call the Tick Action for this state
//::::/c/T/w::::Tick::::
if ( _activeState != nullptr && _activeState != this )
_activeState->tick();
}
double Complex::State3::ChildState3::getTimerPeriod ( void ) {
return timerPeriod;
}
bool Complex::State3::ChildState3::handleEvent ( StateMachine::Event* event ) {
bool handled = false;
// take care of all event types that this branch will not handle -
// for more consistent run-time performnace
switch ( event->type() ) {
case Event::Type::EVENT1:
handled = true;
break;
default:
break;
}
if (handled) {
// we didn't actually handle the event, but return anyway
return false;
}
// handle internal transitions first
switch ( event->type() ) {
default:
break;
}
if (!handled) {
// handle external transitions here
switch ( event->type() ) {
case Event::Type::EVENT3:
if ( false ) { } // makes generation easier :)
else if ( true ) {
#ifdef DEBUG_OUTPUT
std::cout << "NO GUARD on EXTERNAL TRANSITION:/c/T/p" << std::endl;
#endif
// Transitioning states!
// Call all from prev state down exits
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE3_OBJ->exitChildren();
// State : exit for: /c/T/w
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE3_OBJ->exit();
// External Transition : Action for: /c/T/p
#ifdef DEBUG_OUTPUT
std::cout << "TRANSITION::ACTION for /c/T/p" << std::endl;
#endif
//::::/c/T/p::::Action::::
// State : entry for: /c/T/W
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE_OBJ->entry();
#ifdef DEBUG_OUTPUT
std::cout << "STATE TRANSITION: Complex::State3::ChildState3->Complex::State3::ChildState" << std::endl;
#endif
// going into regular state
COMPLEX_OBJ__STATE3_OBJ__CHILDSTATE_OBJ->initialize();
// make sure nothing else handles this event
handled = true;
}
break;
default:
break;
}
}
if (!handled) {
// now check parent states
handled = _parentState->handleEvent( event );
}
return handled;
}
};
// Root of the HFSM
StateMachine::Complex *const Complex_root = &StateMachine::COMPLEX_OBJ_stateObj;
// Event Factory
StateMachine::EventFactory EVENT_FACTORY;
StateMachine::EventFactory *const eventFactory = &EVENT_FACTORY;