/******************************************************************************** * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * * This software is distributed under the terms of the * * GNU Lesser General Public Licence version 3 (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ /** * FairMQStateMachine.h * * @since 2012-10-25 * @author D. Klein, A. Rybalchenko */ #ifndef FAIRMQSTATEMACHINE_H_ #define FAIRMQSTATEMACHINE_H_ #include #include #include #include #include #include #include #include #include "FairMQLogger.h" namespace msm = boost::msm; namespace mpl = boost::mpl; namespace msmf = boost::msm::front; namespace FairMQFSM { // defining events for the boost MSM state machine struct INIT {}; struct SETOUTPUT {}; struct SETINPUT {}; struct PAUSE {}; struct RUN {}; struct STOP {}; struct END {}; // defining the boost MSM state machine struct FairMQFSM_ : public msm::front::state_machine_def { template void on_entry(Event const&, FSM&) { LOG(STATE) << "Entering FairMQ state machine"; fState = IDLE; } template void on_exit(Event const&, FSM&) { LOG(STATE) << "Exiting FairMQ state machine"; } // The list of FSM states struct IDLE_FSM : public msm::front::state<> {}; struct INITIALIZING_FSM : public msm::front::state<> {}; struct SETTINGOUTPUT_FSM : public msm::front::state<> {}; struct SETTINGINPUT_FSM : public msm::front::state<> {}; struct WAITING_FSM : public msm::front::state<> {}; struct RUNNING_FSM : public msm::front::state<> {}; // Define initial state typedef IDLE_FSM initial_state; // Actions struct TestFct { template void operator()(EVT const&, FSM&, SourceState&, TargetState&) { LOG(STATE) << "Transition from " << typeid(SourceState).name() << " to " << typeid(TargetState).name() << " with event:" << typeid(EVT).name(); } }; struct InitFct { template void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) { fsm.fState = INITIALIZING; fsm.Init(); } }; struct SetOutputFct { template void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) { fsm.fState = SETTINGOUTPUT; fsm.InitOutput(); } }; struct SetInputFct { template void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) { fsm.fState = SETTINGINPUT; fsm.InitInput(); } }; struct RunFct { template void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) { fsm.fState = RUNNING; fsm.running_state = boost::thread(boost::bind(&FairMQFSM_::Run, &fsm)); } }; struct StopFct { template void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) { fsm.fState = IDLE; fsm.Terminate(); fsm.running_state.join(); } }; struct PauseFct { template void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) { fsm.fState = WAITING; fsm.running_state.join(); fsm.Pause(); } }; // actions to be overwritten by derived classes virtual void Init() {} virtual void Run() {} virtual void Pause() {} virtual void Shutdown() {} virtual void InitOutput() {} virtual void InitInput() {} virtual void Terminate() {} // Termination method called during StopFct action. // Transition table for FairMQFMS struct transition_table : mpl::vector< // Start Event Next Action Guard // +------------------+----------+------------------+-------------+---------+ msmf::Row, msmf::Row, // this is an invalid transition... msmf::Row, msmf::Row, msmf::Row, msmf::Row, msmf::Row, msmf::Row, msmf::Row, msmf::Row > { }; // Replaces the default no-transition response. template void no_transition(Event const& e, FSM&, int state) { LOG(STATE) << "no transition from state " << state << " on event " << typeid(e).name() << std::endl; } // this is to run certain functions (e.g. Run()) as separate task boost::thread running_state; // backward compatibility to FairMQStateMachine enum State { IDLE, INITIALIZING, SETTINGOUTPUT, SETTINGINPUT, WAITING, RUNNING }; State fState; }; typedef msm::back::state_machine FairMQFSM; } class FairMQStateMachine : public FairMQFSM::FairMQFSM { public: enum Event { INIT, SETOUTPUT, SETINPUT, PAUSE, RUN, STOP, END }; FairMQStateMachine(); virtual ~FairMQStateMachine(); void ChangeState(int event); }; #endif /* FAIRMQSTATEMACHINE_H_ */