Example
This is example shows how the generator works.
State machine diagram
In this example the following state machine will be used:
Model file
For state machine shown above the model file looks like this:
{ "version": "2.0", "event_list": [ { "name": "E1", "ID": 1, "priority": 0 }, { "name": "E2", "ID": 2, "priority": 0 }, { "name": "E3", "ID": 3, "priority": 0 }, { "name": "E4", "ID":4, "priority": 0 }, { "name": "E5", "ID": 5, "priority": 0 }, { "name": "E6", "ID": 6, "priority": 0 }, { "name": "E7", "ID": 7, "priority": 0 } ], "state_machine":{ "transitions": [ { "event_name": [ { "name": "E2" } ], "name": "transition17", "kind": 0, "source": "root/main_region/State5", "target": "root/main_region/State1", "guard": "", "behavior": "" }, { "event_name": [], "name": "transition1", "kind": 0, "source": "root/main_region/Initial", "target": "root/main_region/State1", "guard": "", "behavior": "behavior_function_transition" }, { "event_name": [], "name": "transition2", "kind": 0, "source": "root/main_region/State1/region1/InitialS1r1", "target": "root/main_region/State1/region1/State2", "guard": "", "behavior": "" }, { "event_name": [ { "name": "E2" } ], "name": "transition3", "kind": 0, "source": "root/main_region/State1/region1/State2", "target": "root/main_region/State1/region1/State3", "guard": "", "behavior": "" }, { "event_name": [ { "name": "E1" } ], "name": "transition5", "kind": 0, "source": "root/main_region/State1", "target": "root/main_region/State1/region2/State4a", "guard": "", "behavior": "" }, { "event_name": [ { "name": "E2" } ], "name": "transition19", "kind": 0, "source": "root/main_region/State1/region2/State4a", "target": "root/main_region/State1/region2/State4b", "guard": "", "behavior": "logic::behavior_transition" }, { "event_name": [], "name": "transition4", "kind": 0, "source": "root/main_region/State1/region1/State3", "target": "root/main_region/Join1", "guard": "", "behavior": "" }, { "event_name": [], "name": "transition6", "kind": 0, "source": "root/main_region/State1/region2/State4b", "target": "root/main_region/Join1", "guard": "", "behavior": "" }, { "event_name": [], "name": "transition7", "kind": 0, "source": "root/main_region/Join1", "target": "root/main_region/State5", "guard": "", "behavior": "" }, { "event_name": [], "name": "transition9", "kind": 0, "source": "root/main_region/State5/region1/InitialS6r1", "target": "root/main_region/State5/region1/State8", "guard": "", "behavior": "" }, { "event_name": [], "name": "transition10", "kind": 0, "source": "root/main_region/State5/region1/State8/region1/InitialS8", "target": "root/main_region/State5/region1/State8/region1/State9", "guard": "", "behavior": "" }, { "event_name": [], "name": "transition11", "kind": 0, "source": "root/main_region/State5/region1/InitialS6r2", "target": "root/main_region/State5/region1/State10", "guard": "", "behavior": "" }, { "event_name": [ { "name": "E3" } ], "name": "transition12", "kind": 0, "source": "root/main_region/State5/region1/State10", "target": "root/main_region/State5/region1/State11", "guard": "", "behavior": "" }, { "event_name": [ { "name": "E4" } ], "name": "transition13", "kind": 0, "source": "root/main_region/State5/region1/State10", "target": "root/main_region/State5/region1/State12", "guard": "", "behavior": "" }, { "event_name": [ { "name": "E5" } ], "name": "transition14", "kind": 0, "source": "root/main_region/State5/region1/State10", "target": "root/main_region/State5/region1/State13", "guard": "", "behavior": "" }, { "event_name": [], "name": "transition15", "kind": 0, "source": "root/main_region/State5/region1/InitialS6r3", "target": "root/main_region/State5/region1/State14", "guard": "", "behavior": "" }, { "event_name": [ { "name": "E6" } ], "name": "transition16", "kind": 0, "source": "root/main_region/State5/region1/State6", "target": "root/main_region/State5/region1/State7", "guard": "", "behavior": "" }, { "event_name": [ { "name": "E7" } ], "name": "transition18", "kind": 0, "source": "root/main_region/State5", "target": "root/main_region/Terminate", "guard": "", "behavior": "" }, { "event_name": [], "name": "transition8", "kind": 0, "source": "root/main_region/State5/region1/InitialS5", "target": "root/main_region/State5/region1/State6", "guard": "", "behavior": "" } ], "root":{ "name": "root", "type": "composite_state", "regions": [ { "vertices": [ { "name": "State1", "type": "composite_state", "regions": [ { "vertices": [ { "name": "State4a", "type": "simple_state", "do_behavior": "logic.behavior_do_state_4a", "enter_behavior": "logic.behavior_enter_state_4a", "exit_behavior": "", "deferred_event_name": [], "error_event": [] }, { "name": "State4b", "type": "simple_state", "do_behavior": "logic.behavior_do_state_4b", "enter_behavior": "", "exit_behavior": "", "deferred_event_name": [], "error_event": [] } ], "name": "region2S1" }, { "vertices": [ { "name": "State2", "type": "simple_state", "do_behavior": "", "enter_behavior": "", "exit_behavior": "", "deferred_event_name": [], "error_event": [] }, { "name": "State3", "type": "simple_state", "do_behavior": "behavior_do_state_3", "enter_behavior": "logic::behavior_enter_state_3", "exit_behavior": "logic.behavior_exit_state_3", "deferred_event_name": [], "error_event": [] }, { "type": "initial_pseudostate", "name": "InitialS1r1" } ], "name": "region1S1" } ], "pseudostates": [], "enter_behavior": "logic.behavior_enter_state_1", "exit_behavior": "logic.behavior_exit_state_1", "deferred_event_name": [] }, { "name": "State5", "type": "composite_state", "regions": [ { "vertices": [ { "name": "State6", "type": "composite_state", "regions": [ { "name": "region1S6", "vertices": [ { "name": "State8", "type": "composite_state", "regions": [ { "vertices": [ { "name": "State9", "type": "simple_state", "do_behavior": "behavior_do_state_9", "enter_behavior": "", "exit_behavior": "", "deferred_event_name": [], "error_event": [] }, { "type": "initial_pseudostate", "name": "InitialS8" } ], "name": "region1S8" } ], "pseudostates": [], "enter_behavior": "logic.behavior_enter_state_8", "exit_behavior": "logic.behavior_exit_state_8", "deferred_event_name": [] }, { "type": "initial_pseudostate", "name": "InitialS6r1" } ] }, { "name": "region2S6", "vertices": [ { "name": "State10", "type": "simple_state", "do_behavior": "", "enter_behavior": "", "exit_behavior": "", "deferred_event_name": [], "error_event": [] }, { "name": "State11", "type": "simple_state", "do_behavior": "logic.behavior_do_state_11", "enter_behavior": "", "exit_behavior": "", "deferred_event_name": [], "error_event": [] }, { "name": "State12", "type": "simple_state", "do_behavior": "logic.behavior_do_state_12", "enter_behavior": "", "exit_behavior": "", "deferred_event_name": [], "error_event": [] }, { "name": "State13", "type": "simple_state", "do_behavior": "logic.behavior_do_state_13", "enter_behavior": "", "exit_behavior": "", "deferred_event_name": [], "error_event": [] }, { "type": "initial_pseudostate", "name": "InitialS6r2" } ] }, { "name": "region3S6", "vertices": [ { "name": "State14", "type": "simple_state", "do_behavior": "", "enter_behavior": "", "exit_behavior": "", "deferred_event_name": [], "error_event": [] }, { "type": "initial_pseudostate", "name": "InitialS6r3" } ] } ], "pseudostates": [], "enter_behavior": "", "exit_behavior": "", "deferred_event_name": [] }, { "name": "State7", "type": "simple_state", "do_behavior": "", "enter_behavior": "logic::behavior_enter_state_7", "exit_behavior": "logic::behavior_exit_state_7", "deferred_event_name": [], "error_event": [] }, { "type": "initial_pseudostate", "name": "InitialS5" } ], "name": "region1S5" } ], "pseudostates": [], "enter_behavior": "logic.behavior_enter_state_5", "exit_behavior": "logic.behavior_exit_state_5", "deferred_event_name": [] }, { "type": "initial_pseudostate", "name": "Initial" }, { "type": "terminate_pseudostate", "name": "Terminate" }, { "type": "join", "name": "Join1" } ], "name": "main_region" } ], "pseudostates": [], "enter_behavior": "", "exit_behavior": "", "deferred_event_name": [] } }}Templates and generated code
In this example the standard templates offered by the generator are used.
The code for the event classes looks like this:
This will generate the following result:
Y_EVENT_CREATE(E1, 1)Y_EVENT_CREATE(E2, 2)Y_EVENT_CREATE(E3, 3)Y_EVENT_CREATE(E4, 4)Y_EVENT_CREATE(E5, 5)Y_EVENT_CREATE(E6, 6)Y_EVENT_CREATE(E7, 7)An excerpt from code that creates the states (for the region 'region2S1'):
sxy::simple_state& State4a = region2S1.add_simple_state("State4a", Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_do_state_4a ), Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_enter_state_4a ), Y_EMPTY_BEHAVIOR);sxy::simple_state& State4b = region2S1.add_simple_state("State4b", Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_do_state_4b ), Y_EMPTY_BEHAVIOR, Y_EMPTY_BEHAVIOR);Finally the generated code that creates the transitions looks like this:
// transitions {the_state_machine->add_transition({2}, State5, State1, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, Initial, State1, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_BEHAVIOR_FUNCTION2( behavior_function_transition ));the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, InitialS1r1, State2, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition({2}, State2, State3, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition({1}, State1, State4a, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition({2}, State4a, State4b, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_BEHAVIOR_FUNCTION2( logic::behavior_transition ));the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, State3, Join1, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, State4b, Join1, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, Join1, State5, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, InitialS6r1, State8, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, InitialS8, State9, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, InitialS6r2, State10, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition({3}, State10, State11, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition({4}, State10, State12, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition({5}, State10, State13, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, InitialS6r3, State14, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition({6}, State6, State7, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition({7}, State5, Terminate, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, InitialS5, State6, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR);// } transitionsGenerated files
Complete generated header:
//////////////////////////////////////////////////////////////////////////////////////////////////////// //// This file was generated by yasmine's ygen @ 2017/04/20 14:03:35. //// ////////////////////////////////////////////////////////////////////////////////////////////////////////#ifndef STATE_MACHINE_CREATOR_HPP_#define STATE_MACHINE_CREATOR_HPP_#include "yasmine.hpp"#include "logic.hpp"namespace examples {Y_EVENT_CREATE(E1, 1)Y_EVENT_CREATE(E2, 2)Y_EVENT_CREATE(E3, 3)Y_EVENT_CREATE(E4, 4)Y_EVENT_CREATE(E5, 5)Y_EVENT_CREATE(E6, 6)Y_EVENT_CREATE(E7, 7)using state_machine_uptr = std::unique_ptr<sxy::sync_state_machine>;state_machine_uptr create_state_machine(const std::string& _name, examples::logic& _logic ); }#endifAnd, the generated source file:
//////////////////////////////////////////////////////////////////////////////////////////////////////// //// This file was generated by yasmine's ygen @ 2017/04/20 14:03:35. //// ////////////////////////////////////////////////////////////////////////////////////////////////////////#include "state_machine_creator.hpp"#include <iostream> namespace examples {state_machine_uptr create_state_machine(const std::string& _name, examples::logic& _logic ){ state_machine_uptr the_state_machine = std::make_unique< sxy::sync_state_machine >( _name ); // vertices { sxy::composite_state& root = the_state_machine->get_root_state(); sxy::region& main_region = root.add_region("main_region"); sxy::composite_state& State1 = main_region.add_composite_state("State1", Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_enter_state_1 ), Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_exit_state_1 )); sxy::region& region2S1 = State1.add_region("region2S1"); sxy::simple_state& State4a = region2S1.add_simple_state("State4a", Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_do_state_4a ), Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_enter_state_4a ), Y_EMPTY_BEHAVIOR); sxy::simple_state& State4b = region2S1.add_simple_state("State4b", Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_do_state_4b ), Y_EMPTY_BEHAVIOR, Y_EMPTY_BEHAVIOR); sxy::region& region1S1 = State1.add_region("region1S1"); sxy::simple_state& State2 = region1S1.add_simple_state("State2", Y_EMPTY_BEHAVIOR, Y_EMPTY_BEHAVIOR, Y_EMPTY_BEHAVIOR); sxy::simple_state& State3 = region1S1.add_simple_state("State3", Y_BEHAVIOR_FUNCTION2( behavior_do_state_3 ), Y_BEHAVIOR_FUNCTION2( logic::behavior_enter_state_3 ), Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_exit_state_3 )); sxy::initial_pseudostate& InitialS1r1 = region1S1.add_initial_pseudostate("InitialS1r1"); sxy::composite_state& State5 = main_region.add_composite_state("State5", Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_enter_state_5 ), Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_exit_state_5 )); sxy::region& region1S5 = State5.add_region("region1S5"); sxy::composite_state& State6 = region1S5.add_composite_state("State6", Y_EMPTY_BEHAVIOR, Y_EMPTY_BEHAVIOR); sxy::region& region1S6 = State6.add_region("region1S6"); sxy::composite_state& State8 = region1S6.add_composite_state("State8", Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_enter_state_8 ), Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_exit_state_8 )); sxy::region& region1S8 = State8.add_region("region1S8"); sxy::simple_state& State9 = region1S8.add_simple_state("State9", Y_BEHAVIOR_FUNCTION2( behavior_do_state_9 ), Y_EMPTY_BEHAVIOR, Y_EMPTY_BEHAVIOR); sxy::initial_pseudostate& InitialS8 = region1S8.add_initial_pseudostate("InitialS8"); sxy::initial_pseudostate& InitialS6r1 = region1S6.add_initial_pseudostate("InitialS6r1"); sxy::region& region2S6 = State6.add_region("region2S6"); sxy::simple_state& State10 = region2S6.add_simple_state("State10", Y_EMPTY_BEHAVIOR, Y_EMPTY_BEHAVIOR, Y_EMPTY_BEHAVIOR); sxy::simple_state& State11 = region2S6.add_simple_state("State11", Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_do_state_11 ), Y_EMPTY_BEHAVIOR, Y_EMPTY_BEHAVIOR); sxy::simple_state& State12 = region2S6.add_simple_state("State12", Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_do_state_12 ), Y_EMPTY_BEHAVIOR, Y_EMPTY_BEHAVIOR); sxy::simple_state& State13 = region2S6.add_simple_state("State13", Y_BEHAVIOR_METHOD2( &_logic, &logic::behavior_do_state_13 ), Y_EMPTY_BEHAVIOR, Y_EMPTY_BEHAVIOR); sxy::initial_pseudostate& InitialS6r2 = region2S6.add_initial_pseudostate("InitialS6r2"); sxy::region& region3S6 = State6.add_region("region3S6"); sxy::simple_state& State14 = region3S6.add_simple_state("State14", Y_EMPTY_BEHAVIOR, Y_EMPTY_BEHAVIOR, Y_EMPTY_BEHAVIOR); sxy::initial_pseudostate& InitialS6r3 = region3S6.add_initial_pseudostate("InitialS6r3"); sxy::simple_state& State7 = region1S5.add_simple_state("State7", Y_EMPTY_BEHAVIOR, Y_BEHAVIOR_FUNCTION2( logic::behavior_enter_state_7 ), Y_BEHAVIOR_FUNCTION2( logic::behavior_exit_state_7 )); sxy::initial_pseudostate& InitialS5 = region1S5.add_initial_pseudostate("InitialS5"); sxy::initial_pseudostate& Initial = main_region.add_initial_pseudostate("Initial"); sxy::terminate_pseudostate& Terminate = main_region.add_terminate_pseudostate("Terminate"); sxy::join& Join1 = main_region.add_join("Join1"); // } vertices // transitions { the_state_machine->add_transition({2}, State5, State1, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, Initial, State1, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_BEHAVIOR_FUNCTION2( behavior_function_transition )); the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, InitialS1r1, State2, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition({2}, State2, State3, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition({1}, State1, State4a, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition({2}, State4a, State4b, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_BEHAVIOR_FUNCTION2( logic::behavior_transition )); the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, State3, Join1, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, State4b, Join1, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, Join1, State5, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, InitialS6r1, State8, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, InitialS8, State9, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, InitialS6r2, State10, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition({3}, State10, State11, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition({4}, State10, State12, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition({5}, State10, State13, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, InitialS6r3, State14, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition({6}, State6, State7, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition({7}, State5, Terminate, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); the_state_machine->add_transition(sxy::Y_COMPLETION_EVENT_ID, InitialS5, State6, sxy::transition_kind::EXTERNAL, Y_EMPTY_GUARD, Y_EMPTY_BEHAVIOR); // } transitions return(std::move(the_state_machine));}}Source code
The source code can be found on GitHub.
The generated files are state_machine_creator.hpp and state_machine_creator.cpp.