source: trunk/FACT++/src/RemoteControl.h @ 10341

Last change on this file since 10341 was 10341, checked in by tbretz, 9 years ago
Implemented help for a single server or command.
File size: 8.8 KB
Line 
1#ifndef FACT_RemoteControl
2#define FACT_RemoteControl
3
4// **************************************************************************
5/** @class StateClient
6
7@brief A simple Dim client diriving from MessageDimRX subscribing to the STATE service
8
9This is a simple dim client which subscribes to the MESSAGE and STATE
10service of a server. It stores the last state and its time as well as
11the last message sent.
12
13**/
14// **************************************************************************
15#include "MessageDim.h"
16#include "Time.h"
17
18class StateClient : public MessageDimRX
19{
20private:
21    Time fStateTime;           /// Combine into one MTime (together with value)
22    int  fState;               /// -2 not initialized, -1 not connected, 0>= state of client
23
24    std::string fStateMsg;     /// The message received with the last state change
25
26    DimStampedInfo fInfoState; /// The dim service subscription
27
28protected:
29    void infoHandler();
30
31public:
32    StateClient(const std::string &name, MessageImp &imp);
33
34    bool        IsConnected() const { return fState>=0; }
35    int         GetState() const    { return fState;    }
36    std::string GetMsg() const      { return fStateMsg; }
37};
38
39// **************************************************************************
40/** @class RemoteControlImp
41
42@brief This implements the basic functions of a remote control via dim
43
44Through a ServiceList object this object subscribes to all available
45SERVICE_LISTs  in the dim network. This allows to keep an up-to-date
46list of all servers and services. Its ProcessCommand member function
47allows to emit commands according to the services found in the network.
48Its infoHandler() is called as an update notifier from the ClientList
49object.
50
51**/
52// **************************************************************************
53#include "ServiceList.h"
54#include "DimErrorRedirecter.h"
55
56using namespace std;
57
58class RemoteControlImp : public MessageImp, public DimErrorRedirecter, public DimInfoHandler
59{
60private:
61    std::ostream &lout;          /// Output stream for local synchrounous output
62
63protected:
64    typedef std::map<const std::string, StateClient*> ClientList;
65
66    ServiceList fCommandList;    /// An up-to-date list of all available commands
67    ServiceList fServiceList;    /// An up-to-date list of all available services
68    ClientList  fClientList;     /// A list with all MESSAGE services to which we subscribed
69
70    std::string fCurrentServer;  /// The server to which we currently cd'ed
71
72    void infoHandler();
73
74protected:
75    // Redirect asynchronous output to the output window
76    RemoteControlImp(std::ostream &out, std::ostream &in) :
77        MessageImp(out),
78        DimErrorRedirecter(static_cast<MessageImp&>(*this)),
79        lout(in), fCommandList("CMD", out), fServiceList("", out)
80    {
81        fCommandList.SetHandler(this);
82        fServiceList.SetHandler(this);
83    }
84    bool ProcessCommand(const std::string &str);
85};
86
87// **************************************************************************
88/** @class RemoteControl
89
90@brief Implements a remote control based on a Readline class for the dim network
91
92This template implements all functions which overwrite any function from the
93Readline class. Since several derivatives of the Readline class implement
94different kind of Readline access, this class can be derived by any of them
95due to its template argument. However, the normal case will be
96deriving it from either Console or Shell.
97
98@tparam T
99   The base class for RemoteControl. Either Readlien or a class
100    deriving from it. This is usually either Console or Shell.
101
102**/
103// **************************************************************************
104#include "WindowLog.h"
105#include "ReadlineColor.h"
106#include "tools.h"
107
108template <class T>
109class RemoteControl : public T, public RemoteControlImp
110{
111private:
112    std::ostream &lout; /// Output stream for local synchrounous output
113
114    static void append(std::string &str)
115    {
116        str.append("/");
117    }
118
119    // This funtion defines which generator should be called.
120    // If it returns 0 the standard reaqdline generator are called.
121    // Otherwise set the right generator with rl_completion_matches.
122    char **Completion(const char *text, int start, int)
123    {
124        // Get the whole buffer before the tab-position
125        const string b = string(T::GetBuffer());
126        const string s = b.substr(0, start);
127        const string l = Trim(s.c_str());
128        if (l.empty())
129        {
130            if (fCurrentServer.empty())
131            {
132                const size_t p1 = b.find_first_of(' ');
133                const size_t p2 = b.find_first_of('/');
134
135                if (p1==string::npos && p2!=string::npos)
136                    return T::Complete(fCommandList.GetServiceList(), text);
137
138                std::vector<std::string> v = fCommandList.GetServerList();
139                for_each(v.begin(), v.end(), RemoteControl::append);
140                return T::Complete(v, text);
141            }
142            else
143                return T::Complete(fCommandList.GetServiceList(fCurrentServer), text);
144        }
145        return T::Complete(fCommandList.GetServiceList(l), text);
146    }
147
148    void infoHandler()
149    {
150        RemoteControlImp::infoHandler();
151        if (!fCurrentServer.empty() && !fCommandList.HasServer(fCurrentServer))
152        {
153            fCurrentServer = "";
154            T::UpdatePrompt();
155        }
156    }
157
158public:
159    // Redirect asynchronous output to the output window
160    RemoteControl(const char *name) : T(name),
161        RemoteControlImp(T::GetStreamOut(), T::GetStreamIn()),
162        lout(T::GetStreamIn())
163    {
164    }
165
166
167    bool PrintGeneralHelp()
168    {
169        T::PrintGeneralHelp();
170        lout << " " << kUnderline << "Specific commands:" << endl;
171        lout << kBold << "   h,help <arg> " << kReset << "List help text for given server or command." << endl;
172        lout << kBold << "   s,servers    " << kReset << "List all servers which are connected." << endl;
173        lout << kBold << "   svc,services " << kReset << "List all services in the network." << endl;
174        lout << endl;
175        return true;
176    }
177
178    bool PrintCommands()
179    {
180        lout << endl << kBold << "List of commands:" << endl;
181        fCommandList.PrintDescription(lout);
182        return true;
183    }
184
185    // returns whether a command should be put into the history
186    bool Process(const std::string &str)
187    {
188        if (str.substr(0, 2)=="h " || str.substr(0, 5)=="help ")
189        {
190            const size_t p1 = str.find_first_of(' ');
191            const string svc = str.substr(p1+1);
192
193            const size_t p3 = svc.find_first_of('/');
194            const string s = svc.substr(0, p3);
195            const string c = p3==string::npos?"":svc.substr(p3+1);
196
197            lout << endl;
198            if (!fCurrentServer.empty())
199            {
200                if (fCommandList.PrintDescription(lout, fCurrentServer, svc)==0)
201                    lout << "   " << svc << ": <not found>" << endl;
202            }
203            else
204            {
205                if (fCommandList.PrintDescription(lout, s, c)==0)
206                    lout << "   <no matches found>" <<endl;
207            }
208
209            return true;
210        }
211
212        if (ReadlineColor::Process(lout, str))
213            return true;
214
215        if (T::Process(str))
216            return true;
217
218        if (str=="servers" || str=="s")
219        {
220            fCommandList.PrintServerList(lout);
221            return true;
222        }
223
224        if (str=="services" || str=="svc")
225        {
226            fServiceList.PrintDescription(lout);
227            return true;
228        }
229
230        return ProcessCommand(str);
231    }
232};
233
234
235
236// **************************************************************************
237/** @class RemoteConsole
238
239@brief Derives the RemoteControl from Control and adds a proper prompt
240
241This is basically a RemoteControl, which derives through the template
242argument from the Console class. It enhances the functionality of
243the remote control with a proper updated prompt.
244
245 */
246// **************************************************************************
247#include "Console.h"
248
249class RemoteConsole : public RemoteControl<Console>
250{
251public:
252    RemoteConsole(const char *name, bool continous=false) :
253        RemoteControl<Console>(name)
254    {
255        SetContinous(continous);
256    }
257    string GetUpdatePrompt() const;
258};
259
260// **************************************************************************
261/** @class RemoteShell
262
263@brief Derives the RemoteControl from Shell and adds colored prompt
264
265This is basically a RemoteControl, which derives through the template
266argument from the Shell class. It enhances the functionality of
267the local control with a proper updated prompt.
268
269 */
270// **************************************************************************
271#include "Shell.h"
272
273class RemoteShell : public RemoteControl<Shell>
274{
275public:
276    RemoteShell(const char *name, bool = false) :
277        RemoteControl<Shell>(name)
278    {
279    }
280    string GetUpdatePrompt() const;
281};
282
283#endif
Note: See TracBrowser for help on using the repository browser.