// ; -*- mode: C++; -*- #include "chsm.h" #include #include /** * DAQ state machine interface. */ class JDAQCHSM : public CHSM::machine { public: /** * DAQ state class. * * The member method enter() makes a call to the virtual method JDAQCHSM::enterState(...), * where: * - first argument is the state entered; * - second argument is the event that caused the transition; * * This method should be overwritten by the run control client to reply to the run control. */ class JDAQState : public CHSM::state { public: /** * Default CHSM constructor. */ JDAQState(CHSM_STATE_ARGS) : CHSM::state(CHSM_STATE_INIT) {} /** * Enter this state. * * \param event event that triggered transition * \param from pointer to state from where transition started * \return true if all OK; else false */ bool enter(const CHSM::event& event, CHSM::state* from) { try { dynamic_cast(this->chsm()).enterState(*this, event); return CHSM::state::enter(event, from); } catch(const std::exception& error) { return false; } } }; /** * Constructor. * * \param __name name of state machine */ JDAQCHSM(CHSM_MACHINE_ARGS, const std::string& __name) : CHSM::machine(CHSM_MACHINE_INIT), name (__name), detector_id(-1), run_number (-1) {} /** * Get name of state machine. * * \return name */ const std::string& getName() const { return name; } /** * Get detector identifier. * * \return detector identifier. */ int getDetectorID() const { return detector_id; } /** * Get run number. * * \return run number */ int getRunNumber() const { return run_number; } /** * Interface methods for actions corresponding to state transitions. */ virtual void actionEnter() {} virtual void actionExit() {} virtual void actionInit (int, const char*) {} virtual void actionConfigure (int, const char*) {} virtual void actionStart (int, const char*) {} virtual void actionPause (int, const char*) {} virtual void actionContinue (int, const char*) {} virtual void actionStop (int, const char*) {} virtual void actionReset (int, const char*) {} virtual void actionQuit (int, const char*) {} virtual void actionCheck(int, const char*) {} virtual void actionInput(int, const char*) {} virtual void actionError() {} virtual void actionRecover(int, const char*) {} protected: /** * Action when entering state. * * \param state entered state * \param event event that triggered transition */ virtual void enterState(const CHSM::state& state, const CHSM::event& event) = 0; /** * Type definition of action method. */ typedef void (JDAQCHSM::*action)(int, const char*); /** * The method to execute the action. * * This method shall be implemented in the derived class. * * \param __action pointer to action method * \param __event event that triggered the action */ virtual void execute(action __action, const CHSM::event& __event) = 0; std::string name; int detector_id; int run_number; }; %% chsm JDAQStateMachine(const std::string __name) { upon enter %{ actionEnter(); %} upon exit %{ actionExit(); %} } is { /** * Type definition of an event with additional data */ event ev_daq(int length, const char* buffer); event ev_init; event ev_configure; event ev_start; event ev_pause; event ev_continue; event ev_stop; event ev_reset; event ev_quit; event ev_off; event ev_check; event ev_input; event ev_recover; set Main(RunControl, Responder) is { /** * The run control cluster. */ cluster RunControl(Operational, Error) is { cluster Operational(Idle, Standby, Ready, Paused, Running) { ev_error->Error %{ actionError(); %}; } is { state Idle { ev_init->Standby %{ execute(&JDAQCHSM::actionInit, event); %}; ev_off %{ JDAQCHSM::exit(); %}; } state Standby { ev_configure->Ready %{ execute(&JDAQCHSM::actionConfigure, event); %}; ev_reset->Idle %{ execute(&JDAQCHSM::actionReset, event); %}; } state Ready { ev_start->Running %{ std::istringstream is(std::string(ev_start->buffer, ev_start->length)); is >> run_number >> detector_id; execute(&JDAQCHSM::actionStart, event); %}; ev_quit->Standby %{ execute(&JDAQCHSM::actionQuit, event); %}; } state Paused { ev_continue->Running %{ execute(&JDAQCHSM::actionContinue, event); %}; ev_stop->Standby %{ execute(&JDAQCHSM::actionStop, event); %}; } state Running { ev_pause->Paused %{ execute(&JDAQCHSM::actionPause, event); %}; } } state Error { ev_recover->Operational %{ execute(&JDAQCHSM::actionRecover, event); %}; ev_off %{ JDAQCHSM::exit(); %}; } } /** * This state is used to repond to user commands that are not part of the run control state machine. */ state Responder { ev_check %{ execute(&JDAQCHSM::actionCheck, event); %}; ev_input %{ execute(&JDAQCHSM::actionInput, event); %}; } } } %%