CognitiveProgrammer / State-Machine-Using-Boost-Statechart

A mini eBook on using Boost::statechart library for creating state machines in C++
MIT License
90 stars 12 forks source link

actually this book do have some errors๐Ÿ˜“๐Ÿ˜“๐Ÿ˜“ #8

Closed love1angel closed 1 year ago

love1angel commented 1 year ago

e.x.

  1. event will stay in rather than overwritten. [page 5.3] "overwritten by new events".
    
    #include <boost/mpl/list.hpp>
    #include <boost/statechart/event.hpp>
    #include <boost/statechart/simple_state.hpp>
    #include <boost/statechart/state_machine.hpp>
    #include <boost/statechart/custom_reaction.hpp>
    #include <boost/statechart/transition.hpp>
    #include <boost/statechart/deferral.hpp>
    #include <iostream>

namespace sc = boost::statechart;

struct event_go : sc::event { }; struct event_green : sc::event { }; struct event_blue : sc::event { };

class InitialState; class WorkingState;

class StateMachine : public sc::state_machine<StateMachine, InitialState> { };

class InitialState : public sc::simple_state<InitialState, StateMachine> { public: using reactions = boost::mpl::list<sc::transition<event_go, WorkingState>, sc::deferral, sc::deferral>; };

class WorkingState : public sc::simple_state<WorkingState, StateMachine> { public: using reactions = boost::mpl::list < sc::custom_reaction, sc::custom_reaction>;

sc::result react(const event_green& event)
{
    std::cout << "WorkingState : event_green" << std::endl;
    return this->discard_event();
}

sc::result react(const event_blue& event)
{
    std::cout << "WorkingState : event_blue" << std::endl;
    return this->discard_event();
}

};

int main() { StateMachine sm; sm.initiate(); sm.process_event(event_blue{}); sm.process_event(event_blue{}); sm.process_event(event_green{}); sm.process_event(event_go{}); return 0; }

it's output is: 
``` text
WorkingState : event_blue
WorkingState : event_blue
WorkingState : event_green

environment

-- The C compiler identification is AppleClang 14.0.3.14030022
-- The CXX compiler identification is AppleClang 14.0.3.14030022
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Boost: /opt/homebrew/lib/cmake/Boost-1.81.0/BoostConfig.cmake (found version "1.81.0")
love1angel commented 1 year ago
  1. exit() will call when terminate. [page 7] "This only thing to remember is that the function gets called ONLY IF state gets terminated because state machine is moved to another state."
#include <boost/mpl/list.hpp>
#include <boost/statechart/event.hpp>
#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/state_machine.hpp>
#include <boost/statechart/custom_reaction.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/statechart/deferral.hpp>
#include <iostream>

namespace sc = boost::statechart;

struct event_go : sc::event<event_go> { };
struct event_green : sc::event<event_green> { };
struct event_blue : sc::event<event_blue> { };

class InitialState;
class WorkingState;

class StateMachine : public sc::state_machine<StateMachine, InitialState> {
};

class InitialState : public sc::simple_state<InitialState, StateMachine> {
public:
    using reactions = boost::mpl::list<sc::transition<event_go, WorkingState>, sc::deferral<event_green>, sc::deferral<event_blue>>;
};

class WorkingState : public sc::simple_state<WorkingState, StateMachine> {
public:
    using reactions = boost::mpl::list < sc::custom_reaction<event_green>, sc::custom_reaction<event_blue>>;

    sc::result react(const event_green& event)
    {
        std::cout << "WorkingState : event_green" << std::endl;
        return this->discard_event();
    }

    sc::result react(const event_blue& event)
    {
        std::cout << "WorkingState : event_blue" << std::endl;
        return this->discard_event();
    }

    void exit()
    {
        std::cout << "exit test" << std::endl;
    }
};

int main()
{
    StateMachine sm;
    sm.initiate();
    sm.process_event(event_blue{});
    sm.process_event(event_blue{});
    sm.process_event(event_green{});
    sm.process_event(event_go{});
    sm.terminate();
    return 0;
}

output

WorkingState : event_blue
WorkingState : event_blue
WorkingState : event_green
exit test
love1angel commented 1 year ago

I do think if aims at green hand, at least example illustrated should be right. right?