1 #include "otsdaq/FiniteStateMachine/FiniteStateMachine.h"
2 #include "otsdaq/MessageFacility/MessageFacility.h"
4 #include "otsdaq/Macros/CoutMacros.h"
12 #define __MF_SUBJECT__ "FSM"
13 #define mfSubject_ std::string("FSM-") + getStateMachineName()
16 FiniteStateMachine::FiniteStateMachine(
const std::string& stateMachineName)
17 : stateEntranceTime_(0), inTransition_(false), provenanceState_(
'X'), theErrorMessage_(
""), stateMachineName_(stateMachineName)
19 __GEN_COUT__ <<
"Constructing FiniteStateMachine" << std::endl;
23 FiniteStateMachine::~FiniteStateMachine(
void) {}
26 toolbox::fsm::State FiniteStateMachine::getProvenanceState(
void) {
return provenanceState_; }
29 toolbox::fsm::State FiniteStateMachine::getTransitionFinalState(
const std::string& transition)
31 if(stateTransitionTable_[currentState_].find(transition) != stateTransitionTable_[currentState_].end())
32 return stateTransitionTable_[currentState_][transition];
35 std::ostringstream error;
36 error <<
"Cannot find transition name with transition: " << transition <<
", unknown!";
37 XCEPT_RAISE(toolbox::fsm::exception::Exception, error.str());
42 std::string FiniteStateMachine::getProvenanceStateName(
void) {
return getStateName(getProvenanceState()); }
45 std::string FiniteStateMachine::getCurrentStateName(
void) {
return getStateName(getCurrentState()); }
52 time_t FiniteStateMachine::getTimeInState(
void) {
return stateEntranceTime_ ? (time(0) - stateEntranceTime_) : 0; }
55 std::string FiniteStateMachine::getCurrentTransitionName(
const std::string& transition)
57 if(stateTransitionNameTable_[currentState_].find(transition) != stateTransitionNameTable_[currentState_].end())
59 return stateTransitionNameTable_[currentState_][transition];
63 std::ostringstream error;
64 error <<
"Cannot find transition name with transition: " << transition <<
", unknown!";
65 XCEPT_RAISE(toolbox::fsm::exception::Exception, error.str());
70 std::string FiniteStateMachine::getTransitionName(
const toolbox::fsm::State from,
const std::string& transition)
72 if(stateTransitionNameTable_[from].find(transition) != stateTransitionNameTable_[from].end())
74 return stateTransitionNameTable_[from][transition];
78 std::ostringstream error;
79 error <<
"Cannot find transition name from " << from <<
" with transition: " << transition <<
", unknown!";
80 XCEPT_RAISE(toolbox::fsm::exception::Exception, error.str());
85 std::string FiniteStateMachine::getTransitionParameter(
const toolbox::fsm::State from,
const std::string& transition)
87 if(stateTransitionParameterTable_[from].find(transition) != stateTransitionParameterTable_[from].end())
89 return stateTransitionParameterTable_[from][transition];
95 std::string FiniteStateMachine::getTransitionFinalStateName(
const std::string& transition) {
return getStateName(getTransitionFinalState(transition)); }
98 bool FiniteStateMachine::execTransition(
const std::string& transition)
100 const xoap::MessageReference message;
101 return execTransition(transition, message);
112 bool FiniteStateMachine::execTransition(
const std::string& transition,
const xoap::MessageReference& message)
114 __GEN_COUTV__(transition);
116 if(transition ==
"fail")
118 __GEN_COUT_INFO__ <<
"Failing now!!" << __E__;
122 __GEN_COUT__ <<
"Currently in a transition executed from current state " << getProvenanceStateName()
123 <<
". Attempting to wait for the transition to complete." << __E__;
132 std::map<std::string, toolbox::fsm::State> transitions = getTransitions(getCurrentState());
133 for(
const auto& transitionPair : transitions)
135 __GEN_COUT__ <<
"Taking transition to indirect failure: " << transitionPair.first << __E__;
136 toolbox::Event::Reference event(
new toolbox::Event(transitionPair.first,
this));
140 this->fireEvent(event);
142 catch(toolbox::fsm::exception::Exception& e)
144 std::ostringstream error;
145 error <<
"Transition " << transition <<
" was not executed from current state " << getStateName(getCurrentState())
146 <<
". There was an error: " << e.what();
147 __GEN_COUT_ERR__ << error.str() << std::endl;
149 inTransition_ =
false;
150 stateEntranceTime_ = time(0);
161 __GEN_COUT_WARN__ <<
"In transition, and received another transition: " << transition <<
". Ignoring..." << __E__;
165 inTransition_ =
true;
166 bool transitionSuccessful =
true;
167 provenanceState_ = getCurrentState();
169 std::map<std::string, toolbox::fsm::State> transitions = getTransitions(getCurrentState());
170 if(transitions.find(transition) == transitions.end())
172 inTransition_ =
false;
173 std::ostringstream error;
174 error << transition <<
" is not in the list of the transitions from current state " << getStateName(getCurrentState());
175 __GEN_COUT_ERR__ << error.str() << std::endl;
176 XCEPT_RAISE(toolbox::fsm::exception::Exception, error.str());
187 toolbox::Event::Reference event(
new toolbox::Event(transition,
this));
188 theMessage_ = message;
191 this->fireEvent(event);
193 catch(toolbox::fsm::exception::Exception& e)
195 inTransition_ =
false;
196 transitionSuccessful =
false;
197 std::ostringstream error;
198 __GEN_SS__ <<
"Transition " << transition <<
" was not executed from current state " << getStateName(getCurrentState())
199 <<
". There was an error: " << e.what();
200 __GEN_COUT_ERR__ << ss.str() << std::endl;
204 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
208 inTransition_ =
false;
209 transitionSuccessful =
false;
210 __GEN_SS__ <<
"Transition " << transition <<
" was not executed from current state " << getStateName(getCurrentState())
211 <<
". There was an unknown error.";
212 __GEN_COUT_ERR__ << ss.str() << std::endl;
216 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
219 inTransition_ =
false;
220 stateEntranceTime_ = time(0);
221 return transitionSuccessful;
225 bool FiniteStateMachine::isInTransition(
void) {
return inTransition_; }
228 void FiniteStateMachine::setErrorMessage(
const std::string& errMessage,
bool append)
231 theErrorMessage_ += errMessage;
233 theErrorMessage_ = errMessage;
237 const std::string& FiniteStateMachine::getErrorMessage()
const {
return theErrorMessage_; }
240 void FiniteStateMachine::setInitialState(toolbox::fsm::State state)
242 toolbox::fsm::FiniteStateMachine::setInitialState(state);
243 provenanceState_ = state;
244 stateEntranceTime_ = time(0);
248 const xoap::MessageReference& FiniteStateMachine::getCurrentMessage(
void) {
return theMessage_; }