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

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