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

Last change on this file since 11050 was 11047, checked in by tbretz, 13 years ago
Added output in case of errors when the .s command is enetered.
File size: 8.7 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 << " .s " << kReset << "Wait for the state-machine to change to the given state." << endl;
133 lout << " " " .s <server> <state> [<timeout>]" << endl;
134 lout << " " "<server> The server for which state to wait (e.g. FTM_CONTROL)" << endl;
135 lout << " " "<state> The state id (see 'states') for which to wait (e.g. 3)" << endl;
136 lout << " " "<imeout> A timeout in millisenconds how long to wait (e.g. 500)" << endl;
137 lout << endl;
138 return true;
139 }
140
141 bool PrintCommands()
142 {
143 lout << endl << kBold << "List of commands:" << endl;
144 PrintDescription(lout, true);
145 return true;
146 }
147
148 // returns whether a command should be put into the history
149 bool Process(const std::string &str)
150 {
151 if (str.substr(0, 2)=="h " || str.substr(0, 5)=="help ")
152 {
153 const size_t p1 = str.find_first_of(' ');
154 const string svc = str.substr(p1+1);
155
156 const size_t p3 = svc.find_first_of('/');
157 const string s = svc.substr(0, p3);
158 const string c = p3==string::npos?"":svc.substr(p3+1);
159
160 lout << endl;
161 if (!fCurrentServer.empty())
162 {
163 if (PrintDescription(lout, true, fCurrentServer, svc)==0)
164 lout << " " << svc << ": <not found>" << endl;
165 }
166 else
167 {
168 if (PrintDescription(lout, true, s, c)==0)
169 lout << " <no matches found>" <<endl;
170 }
171
172 return true;
173 }
174
175 if (str.substr(0, 3)==".s ")
176 {
177 istringstream in(str.substr(3));
178
179 int state=-100, ms=0;
180 string server;
181
182 in >> server >> state >> ms;
183 if (state==-100)
184 {
185 lout << kRed << "Couldn't parse state id." << endl;
186 return true;
187 }
188
189 const ClientList::const_iterator l = fClientList.find(server);
190 if (l==fClientList.end())
191 {
192 lout << kRed << "Server '" << server << "' not found." << endl;
193 return true;
194 }
195
196 const Time timeout = Time()+boost::posix_time::millisec(ms);
197
198 while (l->second->GetState()!=state && timeout>Time())
199 usleep(1);
200
201 return true;
202 }
203
204 if (ReadlineColor::Process(lout, str))
205 return true;
206
207 if (T::Process(str))
208 return true;
209
210 if (str=="services" || str=="svc")
211 {
212 PrintDescription(lout, false);
213 return true;
214 }
215
216 if (str=="states" || str=="st")
217 {
218 PrintStates(lout);
219 return true;
220 }
221
222 return ProcessCommand(str);
223 }
224};
225
226
227
228// **************************************************************************
229/** @class RemoteConsole
230
231@brief Derives the RemoteControl from Control and adds a proper prompt
232
233This is basically a RemoteControl, which derives through the template
234argument from the Console class. It enhances the functionality of
235the remote control with a proper updated prompt.
236
237 */
238// **************************************************************************
239#include "Console.h"
240
241class RemoteConsole : public RemoteControl<Console>
242{
243public:
244 RemoteConsole(const char *name, bool continous=false) :
245 RemoteControl<Console>(name)
246 {
247 SetContinous(continous);
248 }
249 string GetUpdatePrompt() const;
250};
251
252// **************************************************************************
253/** @class RemoteShell
254
255@brief Derives the RemoteControl from Shell and adds colored prompt
256
257This is basically a RemoteControl, which derives through the template
258argument from the Shell class. It enhances the functionality of
259the local control with a proper updated prompt.
260
261 */
262// **************************************************************************
263#include "Shell.h"
264
265class RemoteShell : public RemoteControl<Shell>
266{
267public:
268 RemoteShell(const char *name, bool = false) :
269 RemoteControl<Shell>(name)
270 {
271 }
272 string GetUpdatePrompt() const;
273};
274
275#endif
Note: See TracBrowser for help on using the repository browser.