123 :
MessageImp(out), fName(name), fCurrentState(kSM_NotReady),
124 fBufferEvents(true), fRunning(false), fExitRequested(0)
167 const lock_guard<mutex> guard(
fMutex);
183 const lock_guard<mutex> guard(
fMutex);
214 size_t p0 = str.find_first_of(
' ');
215 if (p0==string::npos)
219 const string name =
fName +
"/" + str.substr(0, p0);
225 lout <<
kRed <<
"Unknown command '" << name <<
"'" << endl;
242 lout <<
kRed <<
"Couldn't properly parse the format... ignored." << endl;
249 lout <<
kBlue << name;
251 const vector<char> v = conv.
GetVector(str.substr(p0));
256 return PostEvent(*evt, v.data(), v.size());
258 catch (
const std::runtime_error &e)
260 lout << endl <<
kRed << e.what() << endl;
299 Out() <<
kYellow <<
"State<0 or FatalError: Event ignored." << endl;
315 const Event event(evt, ptr, siz);
347 Out() <<
kYellow <<
"State<0 or FatalError: Event ignored." << endl;
375 const string &name =
fName +
"/";
376 const int len = name.length();
378 const lock_guard<mutex> guard(
fMutexEvt);
383 const string evt = (*i)->GetName();
385 v.push_back(evt.substr(0, len)==name ? evt.substr(len) : evt);
404 const lock_guard<mutex> guard(
fMutexEvt);
407 if (evt.empty() ||
GetName()+
'/'+evt==(*c)->GetName())
408 (*c)->Print(out,
true);
422 const lock_guard<mutex> guard(
fMutexEvt);
426 (*c)->Print(out,
true);
452 out <<
kBold <<
"List of available states:" << endl;
457 out <<
" -[" <<
kBold << state.str() <<
kReset <<
"]:" << setfill(
' ') << setw(6-state.str().length()) <<
' ' <<
kYellow <<
i->second.first <<
kBlue <<
" (" <<
i->second.second <<
")" << endl;
481 const lock_guard<mutex> guard(
fMutexEvt);
497 const lock_guard<mutex> guard(
fMutexEvt);
499 if (evt == (*c)->GetName())
537 Out() <<
" - Adding command " << evt->
GetName();
541 const lock_guard<mutex> guard(
fMutexEvt);
564 str << s1 <<
' ' << s2 <<
' ' << s3 <<
' ' << s4 <<
' ' << s5;
565 return AddEvent(name, str.str(),
"");
592 str << s1 <<
' ' << s2 <<
' ' << s3 <<
' ' << s4 <<
' ' << s5;
593 return AddEvent(name, str.str(), fmt);
607 const lock_guard<mutex> guard(
fMutexEvt);
615 const lock_guard<mutex> guard(
fMutexEvt);
668 if (it->second.first==name)
686 const StateNames::const_iterator
i =
fStateNames.find(state);
687 return i==
fStateNames.end() || i->second.first.empty() ? to_string(state) : i->second.first;
715 const StateNames::const_iterator
i =
fStateNames.find(state);
716 return i==
fStateNames.end() ?
"" : i->second.second;
742 return str.empty() ? s.str() : (str+
'['+s.str()+
']');
778 Out() <<
"'" << cmd <<
"' ignored.";
788 string msg = nnew +
" " + txt;
790 msg +=
" (" + cmd +
")";
799 str <<
"State Transition from " << nold <<
" to " << nnew <<
" (" << txt;
886 Warn(evt.
GetName()+
": No function assigned... ignored.");
893 out <<
"Handle: " << evt.
GetName() <<
"[" << evt.
GetSize() <<
"]";
905 "by ExecFunc function-call");
998 Error(
"Run() can only be called in the NotReady state.");
1008 std::unique_lock<std::mutex> lock(
fMutex);
1015 fCond.wait_for(lock, chrono::microseconds(10000));
1029 const shared_ptr<Event> cmd(
PopEvent());
1043 Fatal(
"Fatal Error occured... shutting down.");
int GetStateIndex(const std::string &name) const
void AddAllowedStates(const std::string &states)
int fCurrentState
Name of the state-machine / server (e.g. DRIVE)
void PrintListOfAllowedEvents()
EventImp & AddEvent(const std::string &name, const std::string &states, const std::string &fmt)
int fExitRequested
Machine is in main-loop.
virtual void Stop(int code=0)
Request to stop the mainloop.
Mainloop running, state machine in operation.
int GetCurrentState() const
return the current state of the machine
A general base-class describing events issues in a state machine.
void PrintListOfStates() const
Print a list of all states with descriptions.
std::list< std::shared_ptr< Event > > fEventQueue
List of available commands as setup by user.
bool PostEvent(std::ostream &lout, const std::string &str)
Post an event to the event queue.
int Debug(const std::string &str)
The base implementation of a distributed messaging system.
const std::string & GetName() const
Fatal error: stop program.
Adds some functionality to boost::posix_time::ptime for our needs.
bool HandleEvent(const EventImp &evt)
EventImp * FindEvent(const std::string &evt)
std::ostream & Out() const
void SetDefaultStateNames()
bool HandleNewState(int newstate, const EventImp *evt, const char *txt)
bool HasEvent(const EventImp *cmd)
bool fRunning
Flag if events should be buffered outside the event loop.
const std::string GetStateDesc() const
virtual std::string GetFormat() const
int Error(const std::string &str)
virtual EventImp * CreateEvent(const std::string &name, const std::string &fmt)=0
Is called when a configuration event is to be processed (no transition of state)
bool IsStateAllowed(int state) const
Mainloop not running, state machine stopped.
int Warn(const std::string &str)
bool HasState(int index) const
std::vector< EventImp * > fListOfEvents
const std::vector< std::string > GetEventNames()
EventImp & Subscribe(const std::string &name)
virtual void PushEvent(Event *cmd)
This is a flag which is set true if the main loop should stop.
const std::string GetStateDescription() const
StateNames fStateNames
Human readable names associated with the states.
Concerete implementation of an EventImp stroring name, format, data and time.
virtual std::string GetName() const
virtual std::string SetCurrentState(int state, const char *txt="", const std::string &cmd="")
void PrintListOfEvents(std::ostream &out, const std::string &evt="")
Error states should be between 0x100 and 0xffff.
Possible return value for GetStateIndex.
int Message(const std::string &str)
int Fatal(const std::string &str)
void Unsubscribe(EventImp *evt)
bool IsQueueEmpty() const
virtual bool AddStateName(const int state, const std::string &name, const std::string &doc="")
std::condition_variable fCond
Mutex to ensure thread-safe access to the command fifo.
std::string GetAsStr(const char *fmt="%Y-%m-%d %H:%M:%S") const
const std::string GetStateName() const
std::mutex fMutexEvt
Mutex to ensure thread-safe access to the command fifo.
std::shared_ptr< Event > PopEvent()
Pop a command from the fifo.
bool IsRunning() const
Used to check if the main loop is already running or still running.
bool fBufferEvents
Conditional to signal run the an event is waiting.
A compiler for the DIM data format string.
virtual int Execute()
Is called continously to execute actions in the current state.
~StateMachineImp()
delete all object stored in fListOfEvent and in fEventQueue
StateMachineImp(std::ostream &out=std::cout, const std::string &name="")
virtual EventImp * CreateService(const std::string &)
std::mutex fMutex
Event queue (fifo) for the received commands.
std::vector< char > GetVector(const void *d, size_t size) const
virtual size_t GetSize() const