00001 #ifndef EPSTATEMACHINE_H
00002 #define EPSTATEMACHINE_H
00003
00004 #include "toolbox/fsm/FiniteStateMachine.h"
00005 #include "toolbox/fsm/FailedEvent.h"
00006 #include "xcept/tools.h"
00007 #include "xoap/MessageFactory.h"
00008 #include "xoap/Method.h"
00009 #include "log4cplus/logger.h"
00010 #include "xdata/String.h"
00011 #include "xdaq/NamespaceURI.h"
00012
00013 namespace evf
00014 {
00015 class EPStateMachine : public toolbox::fsm::FiniteStateMachine
00016 {
00017 public:
00018 EPStateMachine(log4cplus::Logger &logger);
00022 toolbox::fsm::State state_;
00023
00024
00029 xdata::String stateName_;
00030
00031
00032 template<class T> void init(T*me)
00033 {
00034
00035 addState('H', "Halted" , this, &EPStateMachine::stateChanged);
00036 addState('R', "Ready" , this, &EPStateMachine::stateChanged);
00037 addState('E', "Enabled" , this, &EPStateMachine::stateChanged);
00038 addState('S', "Suspended", this, &EPStateMachine::stateChanged);
00039
00040
00041 addStateTransition('H', 'R', "Configure", me, &T::configureAction);
00042 addStateTransition('R', 'E', "Enable", me, &T::enableAction);
00043 addStateTransition('E', 'R', "Stop", me, &T::stopAction);
00044 addStateTransition('E', 'S', "Suspend", me, &T::suspendAction);
00045 addStateTransition('S', 'E', "Resume", me, &T::resumeAction);
00046 addStateTransition('H', 'H', "Halt", me, &T::nullAction);
00047 addStateTransition('R', 'H', "Halt", me, &T::haltAction);
00048 addStateTransition('E', 'H', "Halt", me, &T::haltAction);
00049 addStateTransition('S', 'H', "Halt", me, &T::haltAction);
00050
00051 setFailedStateTransitionAction(this,&EPStateMachine::failedTransition);
00052 setFailedStateTransitionChanged(this,&EPStateMachine::stateChanged);
00053
00054 setInitialState('H');
00055 reset();
00056
00057 xoap::bind(me,&T::fireEvent,"Configure", XDAQ_NS_URI);
00058 xoap::bind(me,&T::fireEvent,"Stop" , XDAQ_NS_URI);
00059 xoap::bind(me,&T::fireEvent,"Enable" , XDAQ_NS_URI);
00060 xoap::bind(me,&T::fireEvent,"Suspend" , XDAQ_NS_URI);
00061 xoap::bind(me,&T::fireEvent,"Resume" , XDAQ_NS_URI);
00062 xoap::bind(me,&T::fireEvent,"Halt" , XDAQ_NS_URI);
00063 xoap::bind(me,&T::fireEvent,"Disable" , XDAQ_NS_URI);
00064 xoap::bind(me,&T::fireEvent,"Fail" , XDAQ_NS_URI);
00065 }
00066
00067
00068 void failedTransition(toolbox::Event::Reference e)
00069 throw (toolbox::fsm::exception::Exception)
00070 {
00071 toolbox::fsm::FailedEvent &fe =
00072 dynamic_cast<toolbox::fsm::FailedEvent&>(*e);
00073
00074 LOG4CPLUS_FATAL(logger_,
00075 "Failure occurred when performing transition from: "
00076 << fe.getFromState() << " to: " << fe.getToState()
00077 << " exception: " << fe.getException().what());
00078 }
00079
00080 void stateChanged(toolbox::fsm::FiniteStateMachine & fsm)
00081 throw (toolbox::fsm::exception::Exception)
00082 {
00083 LOG4CPLUS_INFO(logger_,
00084 "Changed to state: "
00085 << getStateName(getCurrentState()));
00086 }
00087
00088
00093 void reset() throw (toolbox::fsm::exception::Exception)
00094 {
00095 FiniteStateMachine::reset();
00096
00097 state_ = FiniteStateMachine::getCurrentState();
00098 stateName_ = FiniteStateMachine::getStateName(state_);
00099 }
00100
00101
00106 void fireEvent(toolbox::Event::Reference e)
00107 throw (toolbox::fsm::exception::Exception)
00108 {
00109 try{
00110 FiniteStateMachine::fireEvent(e);
00111 }
00112 catch(toolbox::fsm::exception::Exception ex)
00113 {
00114 LOG4CPLUS_ERROR(logger_,"EPStateMachine fireEvent failed "
00115 << ex.what());
00116 }
00117 catch(...)
00118 {
00119 LOG4CPLUS_ERROR(logger_,"EPStateMachine fireEvent failed "
00120 << " Unknown Exception " << " state is "
00121 << FiniteStateMachine::getCurrentState());
00122 }
00123
00124
00125 state_ = FiniteStateMachine::getCurrentState();
00126 stateName_ = FiniteStateMachine::getStateName(state_);
00127 }
00128
00129 xoap::MessageReference processFSMCommand(const std::string cmdName)
00130 throw (xoap::exception::Exception);
00131 xoap::MessageReference createFSMReplyMsg(const std::string cmd,
00132 const std::string state);
00133
00134 private:
00135 log4cplus::Logger &logger_;
00136
00137 };
00138 }
00139 #endif