#ifndef FACT_LocalControl #define FACT_LocalControl #include class StateMachineImp; // ************************************************************************** /** @class LocalControl @brief Implements a local control for a StateMachine based on a Readline class This template implements all functions which overwrite any function from the Readline class needed for a local control of a state machien. Since several derivatives of the Readline class implement different kind of Readline access, this class can be derived by any of them due to its template argument. However, the normal case will be deriving it from either Console or Shell. @tparam T The base class for RemoteControl. Either Readlien or a class deriving from it. This is usually either Console or Shell. **/ // ************************************************************************** #include #include "tools.h" #include "WindowLog.h" #include "StateMachineImp.h" using namespace std; template class LocalControl : public T { private: char **Completion(const char *text, int pos, int) { return pos>0 ? 0 : T::Complete(fStateMachine->GetEventNames(), text); } protected: StateMachineImp *fStateMachine; std::ostream &lout; std::string fName; LocalControl(const char *name) : T(name), fStateMachine(0), lout(T::GetStreamIn()), fName(boost::filesystem::path(name).filename()) { } bool PrintGeneralHelp() { T::PrintGeneralHelp(); lout << " " << kUnderline << "Specific commands:" << endl; lout << kBold << " ac,allowed " << kReset << "Display a list of all currently allowed commands." << endl; lout << kBold << " st,states " << kReset << "Display a list of the available states with description." << endl; lout << kBold << " # " << kReset << "Echo to the output stream" << endl; lout << kBold << " .s " << kReset << "Wait for the state-machine to change to the given state." << endl; lout << " " " .s []" << endl; lout << " " " The state id (see 'states') for which to wait (e.g. 3)" << endl; lout << " " " A timeout in millisenconds how long to wait (e.g. 500)" << endl; lout << endl; return true; } bool PrintCommands() { lout << endl << kBold << "List of commands:" << endl; fStateMachine->PrintListOfEvents(lout); lout << endl; return true; } bool Process(const std::string &str) { if (str.substr(0, 2)=="h " || str.substr(0, 5)=="help ") { lout << endl; fStateMachine->PrintListOfEvents(lout, str.substr(str.find_first_of(' ')+1)); lout << endl; return true; } if (str=="states" || str=="st") { fStateMachine->PrintListOfStates(lout); return true; } if (str=="allowed" || str=="ac") { lout << endl << kBold << "List of commands allowed in current state:" << endl; fStateMachine->PrintListOfAllowedEvents(lout); lout << endl; return true; } if (str.substr(0, 3)==".s ") { istringstream in(str.substr(3)); int state=-100, ms=0; in >> state >> ms; if (state==-100) { lout << kRed << "Couldn't parse state id." << endl; return true; } const Time timeout = ms<=0 ? Time(Time::none) : Time()+boost::posix_time::millisec(ms); const int target = stoi(str.substr(3)); while (fStateMachine->GetCurrentState()!=target && timeout>Time()) usleep(1); return true; } if (str[0]=='#') { T::GetStreamOut() << "# " << Time().GetAsStr("%H:%M:%S.%f") << " - " << Tools::Trim(str.substr(1)) << endl; return true; } if (T::Process(str)) return true; return !fStateMachine->PostEvent(lout, str); } public: void SetReceiver(StateMachineImp &imp) { fStateMachine = &imp; } }; // ************************************************************************** /** @class LocalStream @brief Derives the LocalControl from ConsoleStream This is basically a LocalControl, which derives through the template argument from the ConsoleStream class. */ // ************************************************************************** #include "Console.h" class LocalStream : public LocalControl { public: LocalStream(const char *name, bool null = false) : LocalControl(name) { SetNullOutput(null); } }; // ************************************************************************** /** @class LocalConsole @brief Derives the LocalControl from Control and adds prompt This is basically a LocalControl, which derives through the template argument from the Console class. It enhances the functionality of the local control with a proper updated prompt. */ // ************************************************************************** #include "tools.h" class LocalConsole : public LocalControl { public: LocalConsole(const char *name, bool continous=false) : LocalControl(name) { SetContinous(continous); } string GetUpdatePrompt() const { return GetLinePrompt()+" " "\033[34m\033[1m"+fName+"\033[0m:" "\033[32m\033[1m"+fStateMachine->GetStateName()+"\033[0m> "; } }; // ************************************************************************** /** @class LocalShell @brief Derives the LocalControl from Shell and adds a colored prompt This is basically a LocalControl, which derives through the template argument from the Shell class. It enhances the functionality of the local control with a proper updated prompt. */ // ************************************************************************** #include "Shell.h" class LocalShell : public LocalControl { public: LocalShell(const char *name, bool = false) : LocalControl(name) { } string GetUpdatePrompt() const { return GetLinePrompt()+' '+fName+':'+fStateMachine->GetStateName()+"> "; } }; #endif