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
|
* @author D. Klein, A. Rybalchenko
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
|
||||||
#include <boost/thread.hpp>
|
|
||||||
|
|
||||||
#include "FairMQStateMachine.h"
|
#include "FairMQStateMachine.h"
|
||||||
#include "FairMQLogger.h"
|
#include "FairMQLogger.h"
|
||||||
|
|
||||||
|
FairMQStateMachine::FairMQStateMachine()
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
|
start();
|
||||||
}
|
}
|
||||||
|
|
||||||
FairMQStateMachine::~FairMQStateMachine()
|
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_
|
#define FAIRMQSTATEMACHINE_H_
|
||||||
|
|
||||||
#include <boost/thread.hpp>
|
#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:
|
public:
|
||||||
enum State {
|
enum Event
|
||||||
IDLE, INITIALIZING, SETTINGOUTPUT, SETTINGINPUT, WAITING, RUNNING
|
{
|
||||||
};
|
INIT,
|
||||||
enum Event {
|
SETOUTPUT,
|
||||||
INIT, SETOUTPUT, SETINPUT, PAUSE, RUN, STOP, END
|
SETINPUT,
|
||||||
|
PAUSE,
|
||||||
|
RUN,
|
||||||
|
STOP,
|
||||||
|
END
|
||||||
};
|
};
|
||||||
FairMQStateMachine();
|
FairMQStateMachine();
|
||||||
void ChangeState(int event);
|
|
||||||
virtual ~FairMQStateMachine();
|
virtual ~FairMQStateMachine();
|
||||||
|
void ChangeState(int event);
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FAIRMQSTATEMACHINE_H_ */
|
#endif /* FAIRMQSTATEMACHINE_H_ */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user