otsdaq  v2_01_00
FiniteStateMachine.cc
1 #include "otsdaq-core/FiniteStateMachine/FiniteStateMachine.h"
2 #include "otsdaq-core/MessageFacility/MessageFacility.h"
3 #include "otsdaq-core/Macros/CoutMacros.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  __COUT__ << "Constructing FiniteStateMachine" << 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)
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)
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)
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)
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)
106 {
107  return getStateName(getTransitionFinalState(transition));
108 }
109 
110 //========================================================================================================================
111 bool FiniteStateMachine::execTransition(const std::string& transition)
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)
119 {
120 // __COUT__ << "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  __COUT_ERR__ << error.str() << std::endl;
133  XCEPT_RAISE (toolbox::fsm::exception::Exception, error.str());
134  //__COUT__ << error << std::endl;
135 // __COUT__ << "Transition?" << inTransition_ << std::endl;
136  return false;
137  }
138 
139  try
140  {
141  toolbox::Event::Reference e(new toolbox::Event(transition, this));
142  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
143  this->fireEvent(e);
144  }
145  catch (toolbox::fsm::exception::Exception& e)
146  {
147  inTransition_ = false;
148  transitionSuccessful = false;
149  std::ostringstream error;
150  error << "Transition " << transition << " cannot be executed from current state " << getStateName (getCurrentState());
151  __COUT_ERR__ << error.str() << std::endl;
152  //diagService_->reportError(err.str(),DIAGERROR);
153  XCEPT_RAISE (toolbox::fsm::exception::Exception, error.str());//This make everything crash so you know for sure there is something wrong
154  }
155 // __COUT__ << "Transition?" << inTransition_ << std::endl;
156  inTransition_ = false;
157 // __COUT__ << "Done with fsm transition" << std::endl;
158 // __COUT__ << "Transition?" << inTransition_ << std::endl;
159  stateEntranceTime_ = time(0);
160  return transitionSuccessful;
161 }
162 
163 //========================================================================================================================
164 bool FiniteStateMachine::isInTransition(void)
165 {
166  return inTransition_;
167 }
168 
169 //========================================================================================================================
170 void FiniteStateMachine::setErrorMessage(const std::string &errMessage)
171 {
172  theErrorMessage_ = errMessage;
173 }
174 
175 //========================================================================================================================
176 const std::string& FiniteStateMachine::getErrorMessage() const
177 {
178  return theErrorMessage_;
179 }
180 
181 //========================================================================================================================
182 void FiniteStateMachine::setInitialState(toolbox::fsm::State state)
183 {
184  toolbox::fsm::FiniteStateMachine::setInitialState(state);
185  provenanceState_ = state;
186  stateEntranceTime_ = time(0);
187 }
188 
189 //========================================================================================================================
190 const xoap::MessageReference& FiniteStateMachine::getCurrentMessage(void)
191 {
192  return theMessage_;
193 }