mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-13 00:31:14 +00:00
Using boost::msm inside FairMQStateMachine.
This commit is contained in:
parent
adc7443aa5
commit
24d26e802a
|
@ -5,166 +5,43 @@
|
|||
* @author D. Klein, A. Rybalchenko
|
||||
*/
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
#include "FairMQStateMachine.h"
|
||||
#include "FairMQLogger.h"
|
||||
|
||||
|
||||
FairMQStateMachine::FairMQStateMachine() :
|
||||
fState(IDLE)
|
||||
{
|
||||
}
|
||||
|
||||
void FairMQStateMachine::ChangeState(int event)
|
||||
{
|
||||
switch(fState) {
|
||||
|
||||
case IDLE:
|
||||
switch(event) {
|
||||
|
||||
case INIT:
|
||||
LOG(STATE) << "IDLE --init--> INITIALIZING";
|
||||
fState = INITIALIZING;
|
||||
Init();
|
||||
return;
|
||||
|
||||
case END:
|
||||
LOG(STATE) << "IDLE --end--> (o)";
|
||||
return;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case INITIALIZING:
|
||||
switch(event) {
|
||||
|
||||
case SETOUTPUT:
|
||||
LOG(STATE) << "INITIALIZING --bind--> SETTINGOUTPUT";
|
||||
fState = SETTINGOUTPUT;
|
||||
InitOutput();
|
||||
return;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case SETTINGOUTPUT:
|
||||
switch(event) {
|
||||
|
||||
case SETINPUT:
|
||||
LOG(STATE) << "SETTINGOUTPUT --connect--> SETTINGINPUT";
|
||||
fState = SETTINGINPUT;
|
||||
InitInput();
|
||||
return;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case SETTINGINPUT:
|
||||
switch(event) {
|
||||
|
||||
case PAUSE:
|
||||
LOG(STATE) << "SETTINGINPUT --pause--> WAITING";
|
||||
fState = WAITING;
|
||||
Pause();
|
||||
return;
|
||||
|
||||
case RUN:
|
||||
LOG(STATE) << "SETTINGINPUT --run--> RUNNING";
|
||||
fState = RUNNING;
|
||||
running_state = boost::thread(boost::bind(&FairMQStateMachine::Run, this));
|
||||
return;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case WAITING:
|
||||
switch(event) {
|
||||
|
||||
case RUN:
|
||||
LOG(STATE) << "WAITING --run--> RUNNING";
|
||||
fState = RUNNING;
|
||||
running_state = boost::thread(boost::bind(&FairMQStateMachine::Run, this));
|
||||
return;
|
||||
|
||||
case STOP:
|
||||
LOG(STATE) << "WAITING --stop--> IDLE";
|
||||
fState = IDLE;
|
||||
Shutdown();
|
||||
return;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case RUNNING:
|
||||
switch(event) {
|
||||
|
||||
case PAUSE:
|
||||
LOG(STATE) << "RUNNING --pause--> WAITING";
|
||||
fState = WAITING;
|
||||
running_state.join();
|
||||
return;
|
||||
|
||||
case STOP:
|
||||
LOG(STATE) << "RUNNING --stop--> IDLE";
|
||||
fState = IDLE;
|
||||
running_state.join();
|
||||
Shutdown();
|
||||
return;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}//switch fState
|
||||
}
|
||||
|
||||
void FairMQStateMachine::Init()
|
||||
{
|
||||
}
|
||||
|
||||
void FairMQStateMachine::Run()
|
||||
{
|
||||
}
|
||||
|
||||
void FairMQStateMachine::Pause()
|
||||
{
|
||||
}
|
||||
|
||||
void FairMQStateMachine::Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
void FairMQStateMachine::InitOutput()
|
||||
{
|
||||
}
|
||||
|
||||
void FairMQStateMachine::InitInput()
|
||||
FairMQStateMachine::FairMQStateMachine()
|
||||
{
|
||||
start();
|
||||
}
|
||||
|
||||
FairMQStateMachine::~FairMQStateMachine()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
void FairMQStateMachine::ChangeState(int event)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case INIT:
|
||||
process_event(FairMQFSM::INIT());
|
||||
return;
|
||||
case SETOUTPUT:
|
||||
process_event(FairMQFSM::SETOUTPUT());
|
||||
return;
|
||||
case SETINPUT:
|
||||
process_event(FairMQFSM::SETINPUT());
|
||||
return;
|
||||
case RUN:
|
||||
process_event(FairMQFSM::RUN());
|
||||
return;
|
||||
case PAUSE:
|
||||
process_event(FairMQFSM::PAUSE());
|
||||
return;
|
||||
case STOP:
|
||||
process_event(FairMQFSM::STOP());
|
||||
return;
|
||||
case END:
|
||||
process_event(FairMQFSM::END());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,31 +9,219 @@
|
|||
#define FAIRMQSTATEMACHINE_H_
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
#include <boost/msm/front/euml/common.hpp>
|
||||
#include <boost/msm/front/euml/operator.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
#include "FairMQLogger.h"
|
||||
|
||||
class FairMQStateMachine
|
||||
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<FairMQFSM_>
|
||||
{
|
||||
template <class Event, class FSM>
|
||||
void on_entry(Event const&, FSM&)
|
||||
{
|
||||
LOG(STATE) << "Entering FairMQ state machine";
|
||||
fState = IDLE;
|
||||
}
|
||||
template <class Event, class FSM>
|
||||
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 <class EVT, class FSM, class SourceState, class TargetState>
|
||||
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 <class EVT, class FSM, class SourceState, class TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = INITIALIZING;
|
||||
fsm.Init();
|
||||
}
|
||||
};
|
||||
struct SetOutputFct
|
||||
{
|
||||
template <class EVT, class FSM, class SourceState, class TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = SETTINGOUTPUT;
|
||||
fsm.InitOutput();
|
||||
}
|
||||
};
|
||||
struct SetInputFct
|
||||
{
|
||||
template <class EVT, class FSM, class SourceState, class TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = SETTINGINPUT;
|
||||
fsm.InitInput();
|
||||
}
|
||||
};
|
||||
struct RunFct
|
||||
{
|
||||
template <class EVT, class FSM, class SourceState, class TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = RUNNING;
|
||||
fsm.running_state = boost::thread(boost::bind(&FairMQFSM_::Run, &fsm));
|
||||
}
|
||||
};
|
||||
struct StopFct
|
||||
{
|
||||
template <class EVT, class FSM, class SourceState, class TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = IDLE;
|
||||
fsm.running_state.join();
|
||||
fsm.Shutdown();
|
||||
}
|
||||
};
|
||||
struct PauseFct
|
||||
{
|
||||
template <class EVT, class FSM, class SourceState, class TargetState>
|
||||
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()
|
||||
{
|
||||
}
|
||||
// Transition table for FairMQFMS
|
||||
struct transition_table : mpl::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +---------+---------+-------+---------+--------+
|
||||
msmf::Row<IDLE_FSM, INIT, INITIALIZING_FSM, InitFct, msmf::none>,
|
||||
msmf::Row<IDLE_FSM, END, msmf::none, TestFct, msmf::none>, // this is an invalid transition...
|
||||
msmf::Row<INITIALIZING_FSM, SETOUTPUT, SETTINGOUTPUT_FSM, SetOutputFct, msmf::none>,
|
||||
msmf::Row<SETTINGOUTPUT_FSM, SETINPUT, SETTINGINPUT_FSM, SetInputFct, msmf::none>,
|
||||
msmf::Row<SETTINGINPUT_FSM, PAUSE, WAITING_FSM, PauseFct, msmf::none>,
|
||||
msmf::Row<SETTINGINPUT_FSM, RUN, RUNNING_FSM, RunFct, msmf::none>,
|
||||
msmf::Row<WAITING_FSM, RUN, RUNNING_FSM, RunFct, msmf::none>,
|
||||
msmf::Row<WAITING_FSM, STOP, IDLE_FSM, StopFct, msmf::none>,
|
||||
msmf::Row<RUNNING_FSM, PAUSE, WAITING_FSM, PauseFct, msmf::none>,
|
||||
msmf::Row<RUNNING_FSM, STOP, IDLE_FSM, StopFct, msmf::none> >
|
||||
{
|
||||
};
|
||||
// Replaces the default no-transition response.
|
||||
template <class FSM, class Event>
|
||||
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_> FairMQFSM;
|
||||
}
|
||||
|
||||
class FairMQStateMachine : public FairMQFSM::FairMQFSM
|
||||
{
|
||||
public:
|
||||
enum State {
|
||||
IDLE, INITIALIZING, SETTINGOUTPUT, SETTINGINPUT, WAITING, RUNNING
|
||||
};
|
||||
enum Event {
|
||||
INIT, SETOUTPUT, SETINPUT, PAUSE, RUN, STOP, END
|
||||
enum Event
|
||||
{
|
||||
INIT,
|
||||
SETOUTPUT,
|
||||
SETINPUT,
|
||||
PAUSE,
|
||||
RUN,
|
||||
STOP,
|
||||
END
|
||||
};
|
||||
FairMQStateMachine();
|
||||
void ChangeState(int event);
|
||||
virtual ~FairMQStateMachine();
|
||||
|
||||
protected:
|
||||
State fState;
|
||||
Event fEvent;
|
||||
virtual void Init();
|
||||
virtual void Run();
|
||||
virtual void Pause();
|
||||
virtual void Shutdown();
|
||||
virtual void InitOutput();
|
||||
virtual void InitInput();
|
||||
boost::thread running_state;
|
||||
void ChangeState(int event);
|
||||
};
|
||||
|
||||
#endif /* FAIRMQSTATEMACHINE_H_ */
|
||||
|
|
Loading…
Reference in New Issue
Block a user