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

Last change on this file since 11045 was 11045, checked in by tbretz, 13 years ago
Added possibility to block execution until the state machine has reached a given state.
File size: 8.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 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 return true;
185
186 const ClientList::const_iterator l = fClientList.find(server);
187 if (l==fClientList.end())
188 return true;
189
190 const Time timeout = Time()+boost::posix_time::millisec(ms);
191
192 while (l->second->GetState()!=state && timeout>Time())
193 usleep(1);
194
195 return true;
196 }
197
198 if (ReadlineColor::Process(lout, str))
199 return true;
200
201 if (T::Process(str))
202 return true;
203
204 if (str=="services" || str=="svc")
205 {
206 PrintDescription(lout, false);
207 return true;
208 }
209
210 if (str=="states" || str=="st")
211 {
212 PrintStates(lout);
213 return true;
214 }
215
216 return ProcessCommand(str);
217 }
218};
219
220
221
222// **************************************************************************
223/** @class RemoteConsole
224
225@brief Derives the RemoteControl from Control and adds a proper prompt
226
227This is basically a RemoteControl, which derives through the template
228argument from the Console class. It enhances the functionality of
229the remote control with a proper updated prompt.
230
231 */
232// **************************************************************************
233#include "Console.h"
234
235class RemoteConsole : public RemoteControl<Console>
236{
237public:
238 RemoteConsole(const char *name, bool continous=false) :
239 RemoteControl<Console>(name)
240 {
241 SetContinous(continous);
242 }
243 string GetUpdatePrompt() const;
244};
245
246// **************************************************************************
247/** @class RemoteShell
248
249@brief Derives the RemoteControl from Shell and adds colored prompt
250
251This is basically a RemoteControl, which derives through the template
252argument from the Shell class. It enhances the functionality of
253the local control with a proper updated prompt.
254
255 */
256// **************************************************************************
257#include "Shell.h"
258
259class RemoteShell : public RemoteControl<Shell>
260{
261public:
262 RemoteShell(const char *name, bool = false) :
263 RemoteControl<Shell>(name)
264 {
265 }
266 string GetUpdatePrompt() const;
267};
268
269#endif
Note: See TracBrowser for help on using the repository browser.