otsdaq  v1_01_02
 All Classes Namespaces Functions
FiniteStateMachine.cc
1 #include "otsdaq-core/FiniteStateMachine/FiniteStateMachine.h"
2 #include "otsdaq-core/MessageFacility/MessageFacility.h"
3 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
4 
5 #include <sstream>
6 #include <map>
7 
8 using namespace ots;
9 
10 //========================================================================================================================
11 FiniteStateMachine::FiniteStateMachine(void)
12 : stateEntranceTime_(0)
13 , inTransition_ (false)
14 , provenanceState_ ('X')
15 , theErrorMessage_ ("")
16 {
17  __MOUT__ << "Transition? "<< inTransition_ << std::endl;
18 }
19 
20 //========================================================================================================================
21 FiniteStateMachine::~FiniteStateMachine(void)
22 {}
23 
24 //========================================================================================================================
25 toolbox::fsm::State FiniteStateMachine::getProvenanceState(void)
26 {
27  return provenanceState_;
28 }
29 
30 //========================================================================================================================
31 toolbox::fsm::State FiniteStateMachine::getTransitionFinalState(const std::string& transition) throw (toolbox::fsm::exception::Exception)
32 {
33  if(stateTransitionTable_[currentState_].find(transition) != stateTransitionTable_[currentState_].end())
34  return stateTransitionTable_[currentState_][transition];
35  else
36  {
37  std::ostringstream error;
38  error << "Cannot find transition name with transition: " << transition << ", unknown!";
39  XCEPT_RAISE (toolbox::fsm::exception::Exception, error.str());
40  }
41 }
42 
43 //========================================================================================================================
44 std::string FiniteStateMachine::getProvenanceStateName(void)
45 {
46  return getStateName(getProvenanceState());
47 }
48 
49 //========================================================================================================================
50 std::string FiniteStateMachine::getCurrentStateName(void)
51 {
52  return getStateName(getCurrentState());
53 }
54 
55 //========================================================================================================================
56 //getTimeInState
57 // returns number of seconds elapsed while in current state
58 // returns 0 if invalid (i.e. stateEntranceTime_ is not set - stateEntranceTime_ is initialized to 0)
59 time_t FiniteStateMachine::getTimeInState (void)
60 {
61  return stateEntranceTime_?(time(0) - stateEntranceTime_):0;
62 }
63 
64 //========================================================================================================================
65 std::string FiniteStateMachine::getCurrentTransitionName(const std::string& transition) throw (toolbox::fsm::exception::Exception)
66 {
67  if(stateTransitionNameTable_[currentState_].find(transition) != stateTransitionNameTable_[currentState_].end())
68  {
69  return stateTransitionNameTable_[currentState_][transition];
70  }
71  else
72  {
73  std::ostringstream error;
74  error << "Cannot find transition name with transition: " << transition << ", unknown!";
75  XCEPT_RAISE (toolbox::fsm::exception::Exception, error.str());
76  }
77 }
78 
79 //========================================================================================================================
80 std::string FiniteStateMachine::getTransitionName(const toolbox::fsm::State from, const std::string& transition) throw (toolbox::fsm::exception::Exception)
81 {
82  if(stateTransitionNameTable_[from].find(transition) != stateTransitionNameTable_[from].end())
83  {
84  return stateTransitionNameTable_[from][transition];
85  }
86  else
87  {
88  std::ostringstream error;
89  error << "Cannot find transition name from " << from << " with transition: " << transition << ", unknown!";
90  XCEPT_RAISE (toolbox::fsm::exception::Exception, error.str());
91  }
92 }
93 
94 //========================================================================================================================
95 std::string FiniteStateMachine::getTransitionParameter(const toolbox::fsm::State from, const std::string& transition) throw (toolbox::fsm::exception::Exception)
96 {
97  if(stateTransitionParameterTable_[from].find(transition) != stateTransitionParameterTable_[from].end())
98  {
99  return stateTransitionParameterTable_[from][transition];
100  }
101  return "";
102 }
103 
104 //========================================================================================================================
105 std::string FiniteStateMachine::getTransitionFinalStateName(const std::string& transition) throw (toolbox::fsm::exception::Exception)
106 {
107  return getStateName(getTransitionFinalState(transition));
108 }
109 
110 //========================================================================================================================
111 bool FiniteStateMachine::execTransition(const std::string& transition) throw (toolbox::fsm::exception::Exception)
112 {
113  const xoap::MessageReference message;//FIXME I would like to have everything in 1 line but like this is not a big deal
114  return execTransition(transition,message);
115 }
116 
117 //========================================================================================================================
118 bool FiniteStateMachine::execTransition(const std::string& transition, const xoap::MessageReference& message) throw (toolbox::fsm::exception::Exception)
119 {
120 // __MOUT__ << "Transition?" << inTransition_ << std::endl;
121  if(inTransition_) return false;
122  inTransition_ = true;
123  bool transitionSuccessful = true;
124  provenanceState_ = getCurrentState();
125 
126  std::map<std::string, toolbox::fsm::State> transitions = getTransitions(getCurrentState());
127  if(transitions.find(transition) == transitions.end())
128  {
129  inTransition_ = false;
130  std::ostringstream error;
131  error << transition << " is not in the list of the transitions from current state " << getStateName (getCurrentState());
132  XCEPT_RAISE (toolbox::fsm::exception::Exception, error.str());
133  //__MOUT__ << error << std::endl;
134 // __MOUT__ << "Transition?" << inTransition_ << std::endl;
135  return false;
136  }
137 
138  try
139  {
140  toolbox::Event::Reference e(new toolbox::Event(transition, this));
141  theMessage_ = message;//Even if it is bad, there can only be 1 transition at a time so this parameter should not change during all transition
142  this->fireEvent(e);
143  }
144  catch (toolbox::fsm::exception::Exception& e)
145  {
146  inTransition_ = false;
147  transitionSuccessful = false;
148  std::ostringstream error;
149  error << "Transition " << transition << " cannot be executed from current state " << getStateName (getCurrentState());
150  __MOUT__ << error.str() << std::endl;
151  //diagService_->reportError(err.str(),DIAGERROR);
152  XCEPT_RAISE (toolbox::fsm::exception::Exception, error.str());//This make everything crash so you know for sure there is something wrong
153  }
154 // __MOUT__ << "Transition?" << inTransition_ << std::endl;
155  inTransition_ = false;
156 // __MOUT__ << "Done with fsm transition" << std::endl;
157 // __MOUT__ << "Transition?" << inTransition_ << std::endl;
158  stateEntranceTime_ = time(0);
159  return transitionSuccessful;
160 }
161 
162 //========================================================================================================================
163 bool FiniteStateMachine::isInTransition(void)
164 {
165  return inTransition_;
166 }
167 
168 //========================================================================================================================
169 void FiniteStateMachine::setErrorMessage(const std::string &errMessage)
170 {
171  theErrorMessage_ = errMessage;
172 }
173 
174 //========================================================================================================================
175 const std::string& FiniteStateMachine::getErrorMessage() const
176 {
177  return theErrorMessage_;
178 }
179 
180 //========================================================================================================================
181 void FiniteStateMachine::setInitialState(toolbox::fsm::State state)
182 {
183  toolbox::fsm::FiniteStateMachine::setInitialState(state);
184  provenanceState_ = state;
185  stateEntranceTime_ = time(0);
186 }
187 
188 //========================================================================================================================
189 const xoap::MessageReference& FiniteStateMachine::getCurrentMessage(void)
190 {
191  return theMessage_;
192 }