#ifndef FACT_RemoteControl #define FACT_RemoteControl // ************************************************************************** /** @class StateClient @brief A simple Dim client diriving from MessageDimRX subscribing to the STATE service This is a simple dim client which subscribes to the MESSAGE and STATE service of a server. It stores the last state and its time as well as the last message sent. **/ // ************************************************************************** #include "MessageDim.h" #include "Time.h" class StateClient : public MessageDimRX { private: Time fStateTime; /// Combine into one MTime (together with value) int fState; /// -2 not initialized, -1 not connected, 0>= state of client std::string fStateMsg; /// The message received with the last state change DimStampedInfo fInfoState; /// The dim service subscription protected: void infoHandler(); public: StateClient(const std::string &name, MessageImp &imp); bool IsConnected() const { return fState>=0; } int GetState() const { return fState; } std::string GetMsg() const { return fStateMsg; } }; // ************************************************************************** /** @class RemoteControlImp @brief This implements the basic functions of a remote control via dim Through a ServiceList object this object subscribes to all available SERVICE_LISTs in the dim network. This allows to keep an up-to-date list of all servers and services. Its ProcessCommand member function allows to emit commands according to the services found in the network. Its infoHandler() is called as an update notifier from the ClientList object. **/ // ************************************************************************** #include "ServiceList.h" #include "DimErrorRedirecter.h" using namespace std; class RemoteControlImp : public MessageImp, public DimErrorRedirecter, public DimInfoHandler { private: std::ostream &lout; /// Output stream for local synchrounous output protected: typedef std::map ClientList; ServiceList fCommandList; /// An up-to-date list of all available commands ServiceList fServiceList; /// An up-to-date list of all available services ClientList fClientList; /// A list with all MESSAGE services to which we subscribed std::string fCurrentServer; /// The server to which we currently cd'ed void infoHandler(); protected: // Redirect asynchronous output to the output window RemoteControlImp(std::ostream &out, std::ostream &in) : MessageImp(out), DimErrorRedirecter(static_cast(*this)), lout(in), fCommandList("CMD", out), fServiceList("", out) { fCommandList.SetHandler(this); fServiceList.SetHandler(this); } bool ProcessCommand(const std::string &str); }; // ************************************************************************** /** @class RemoteControl @brief Implements a remote control based on a Readline class for the dim network This template implements all functions which overwrite any function from the Readline class. 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 "WindowLog.h" template class RemoteControl : public T, public RemoteControlImp { private: std::ostream &lout; /// Output stream for local synchrounous output // This funtion defines which generator should be called. // If it returns 0 the standard reaqdline generator are called. // Otherwise set the right generator with rl_completion_matches. char **Completion(const char *text, int start, int) { // Get the whole buffer before the tab-position const string s = string(T::GetBuffer(), 0, start); const string l = T::TrimSpaces(s.c_str()); if (l.empty()) { if (fCurrentServer.empty()) return T::Complete(fCommandList.GetServerList(), text); else return T::Complete(fCommandList.GetServiceList(fCurrentServer), text); } return T::Complete(fCommandList.GetServiceList(l), text); } void infoHandler() { RemoteControlImp::infoHandler(); if (!fCurrentServer.empty() && !fCommandList.HasServer(fCurrentServer)) { fCurrentServer = ""; T::UpdatePrompt(); } } public: // Redirect asynchronous output to the output window RemoteControl(const char *name) : T(name), RemoteControlImp(T::GetStreamOut(), T::GetStreamIn()), lout(T::GetStreamIn()) { } bool PrintGeneralHelp() { T::PrintGeneralHelp(); lout << " " << kUnderline << "Specific commands:" << endl; lout << kBold << " s,servers " << kReset << "List all servers which are connected." << endl; lout << kBold << " svc,service " << kReset << "List all services in the network." << endl; lout << endl; return true; } bool PrintCommands() { lout << endl << kBold << "List of commands:" << endl; fCommandList.PrintDescription(lout); return true; } // returns whether a command should be put into the history bool Process(const std::string &str) { if (T::Process(str)) return true; if (str=="servers" || str=="s") { fCommandList.PrintServerList(lout); return true; } if (str=="service" || str=="svc") { fServiceList.PrintDescription(lout); return true; } return ProcessCommand(str); } void Run(const char * = 0) { lout << endl; lout << kBlue << kBold << "You are on the terminal of the MCP -" << endl; lout << kBlue << kBold << "the Master Control Program." << endl; lout << endl; lout << kBlue << kBold << "Hello Flynn..." << endl; lout << endl; T::Run(); } }; // ************************************************************************** /** @class RemoteConsole @brief Derives the RemoteControl from Control and adds a proper prompt This is basically a RemoteControl, which derives through the template argument from the Console class. It enhances the functionality of the remote control with a proper updated prompt. */ // ************************************************************************** #include "Console.h" class RemoteConsole : public RemoteControl { public: RemoteConsole(const char *name, bool continous=false) : RemoteControl(name) { SetContinous(continous); } string GetUpdatePrompt() const; }; // ************************************************************************** /** @class RemoteShell @brief Derives the RemoteControl from Shell and adds colored prompt This is basically a RemoteControl, 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 RemoteShell : public RemoteControl { public: RemoteShell(const char *name, bool = false) : RemoteControl(name) { } string GetUpdatePrompt() const; }; #endif