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

Last change on this file since 11788 was 11051, checked in by tbretz, 14 years ago
Added the comment command (#)
File size: 8.9 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 static void append(std::string &str)
64 {
65 str.append("/");
66 }
67 static void chop(std::string &str)
68 {
69 const size_t p = str.find_first_of('/');
70 if (p!=string::npos)
71 str = str.substr(p+1);
72 }
73
74 // This funtion defines which generator should be called.
75 // If it returns 0 the standard reaqdline generator are called.
76 // Otherwise set the right generator with rl_completion_matches.
77 char **Completion(const char *text, int start, int)
78 {
79 // Get the whole buffer before the tab-position
80 const string b = string(T::GetBuffer());
81 const string s = b.substr(0, start);
82 const string l = Tools::Trim(s.c_str());
83 if (l.empty())
84 {
85 if (fCurrentServer.empty())
86 {
87 const size_t p1 = b.find_first_of(' ');
88 const size_t p2 = b.find_first_of('/');
89
90 if (p1==string::npos && p2!=string::npos)
91 return T::Complete(GetCommandList(), text);
92
93 std::vector<std::string> v = GetServerList();
94 for_each(v.begin(), v.end(), RemoteControl::append);
95 return T::Complete(v, text);
96 }
97 else
98 {
99 std::vector<std::string> v = GetCommandList(fCurrentServer);
100 for_each(v.begin(), v.end(), RemoteControl::chop);
101 return T::Complete(v, text);
102 }
103 }
104 return T::Complete(GetCommandList(l), text);
105 }
106
107 void infoHandler()
108 {
109 RemoteControlImp::infoHandler();
110 if (!fCurrentServer.empty() && !HasServer(fCurrentServer))
111 {
112 fCurrentServer = "";
113 T::UpdatePrompt();
114 }
115 }
116
117public:
118 // Redirect asynchronous output to the output window
119 RemoteControl(const char *name) : T(name),
120 RemoteControlImp(T::GetStreamOut(), T::GetStreamIn())
121 {
122 }
123
124 bool PrintGeneralHelp()
125 {
126 T::PrintGeneralHelp();
127 lout << " " << kUnderline << "Specific commands:" << endl;
128 lout << kBold << " h,help <arg> " << kReset << "List help text for given server or command." << endl;
129// lout << kBold << " s,servers " << kReset << "List all servers which are connected." << endl;
130 lout << kBold << " svc,services " << kReset << "List all services in the network." << endl;
131 lout << kBold << " st,states " << kReset << "List all states in the network." << endl;
132 lout << kBold << " # <text> " << kReset << "Echo <text> to the output stream" << endl;
133 lout << kBold << " .s " << kReset << "Wait for the state-machine to change to the given state." << endl;
134 lout << " " " .s <server> [<state> [<timeout>]]" << endl;
135 lout << " " "<server> The server for which state to wait (e.g. FTM_CONTROL)" << endl;
136 lout << " " "<state> The state id (see 'states') for which to wait (e.g. 3)" << endl;
137 lout << " " "<imeout> A timeout in millisenconds how long to wait (e.g. 500)" << endl;
138 lout << endl;
139 return true;
140 }
141
142 bool PrintCommands()
143 {
144 lout << endl << kBold << "List of commands:" << endl;
145 PrintDescription(lout, true);
146 return true;
147 }
148
149 // returns whether a command should be put into the history
150 bool Process(const std::string &str)
151 {
152 if (str.substr(0, 2)=="h " || str.substr(0, 5)=="help ")
153 {
154 const size_t p1 = str.find_first_of(' ');
155 const string svc = str.substr(p1+1);
156
157 const size_t p3 = svc.find_first_of('/');
158 const string s = svc.substr(0, p3);
159 const string c = p3==string::npos?"":svc.substr(p3+1);
160
161 lout << endl;
162 if (!fCurrentServer.empty())
163 {
164 if (PrintDescription(lout, true, fCurrentServer, svc)==0)
165 lout << " " << svc << ": <not found>" << endl;
166 }
167 else
168 {
169 if (PrintDescription(lout, true, s, c)==0)
170 lout << " <no matches found>" <<endl;
171 }
172
173 return true;
174 }
175
176 if (str.substr(0, 3)==".s ")
177 {
178 istringstream in(str.substr(3));
179
180 int state=-100, ms=0;
181 string server;
182
183 in >> server >> state >> ms;
184 if (state==-100)
185 {
186 lout << kRed << "Couldn't parse state id." << endl;
187 return true;
188 }
189
190 const ClientList::const_iterator l = fClientList.find(server);
191 if (l==fClientList.end())
192 {
193 lout << kRed << "Server '" << server << "' not found." << endl;
194 return true;
195 }
196
197 const Time timeout = ms<=0 ? Time(Time::none) : Time()+boost::posix_time::millisec(ms);
198
199 while (l->second->GetState()!=state && timeout>Time())
200 usleep(1);
201
202 return true;
203 }
204
205 if (str[0]=='#')
206 {
207 lout << Tools::Trim(str.substr(1)) << endl;
208 return true;
209 }
210
211 if (ReadlineColor::Process(lout, str))
212 return true;
213
214 if (T::Process(str))
215 return true;
216
217 if (str=="services" || str=="svc")
218 {
219 PrintDescription(lout, false);
220 return true;
221 }
222
223 if (str=="states" || str=="st")
224 {
225 PrintStates(lout);
226 return true;
227 }
228
229 return ProcessCommand(str);
230 }
231};
232
233
234
235// **************************************************************************
236/** @class RemoteConsole
237
238@brief Derives the RemoteControl from Control and adds a proper prompt
239
240This is basically a RemoteControl, which derives through the template
241argument from the Console class. It enhances the functionality of
242the remote control with a proper updated prompt.
243
244 */
245// **************************************************************************
246#include "Console.h"
247
248class RemoteConsole : public RemoteControl<Console>
249{
250public:
251 RemoteConsole(const char *name, bool continous=false) :
252 RemoteControl<Console>(name)
253 {
254 SetContinous(continous);
255 }
256 string GetUpdatePrompt() const;
257};
258
259// **************************************************************************
260/** @class RemoteShell
261
262@brief Derives the RemoteControl from Shell and adds colored prompt
263
264This is basically a RemoteControl, which derives through the template
265argument from the Shell class. It enhances the functionality of
266the local control with a proper updated prompt.
267
268 */
269// **************************************************************************
270#include "Shell.h"
271
272class RemoteShell : public RemoteControl<Shell>
273{
274public:
275 RemoteShell(const char *name, bool = false) :
276 RemoteControl<Shell>(name)
277 {
278 }
279 string GetUpdatePrompt() const;
280};
281
282#endif
Note: See TracBrowser for help on using the repository browser.