source: trunk/FACT++/src/LocalControl.h@ 20115

Last change on this file since 20115 was 20015, checked in by tbretz, 4 years ago
Readline needs to be told which are the printable charcters in the prompt and which are not... this was why it sometimes bevahed a bit erratic.
File size: 7.1 KB
Line 
1#ifndef FACT_LocalControl
2#define FACT_LocalControl
3
4#include <ostream>
5
6// **************************************************************************
7/** @class LocalControl
8
9@brief Implements a local control for a StateMachine based on a Readline class
10
11This template implements all functions which overwrite any function from the
12Readline class needed for a local control of a state machien. Since
13several derivatives of the Readline class implement different kind of
14Readline access, this class can be derived by any of them due to its
15template argument. However, the normal case will be deriving it from
16either Console or Shell.
17
18@tparam T
19 The base class for RemoteControl. Either Readlien or a class
20 deriving from it. This is usually either Console or Shell.
21
22**/
23// **************************************************************************
24#include <boost/version.hpp>
25#include <boost/filesystem.hpp>
26
27#include "tools.h"
28
29#include "WindowLog.h"
30#include "StateMachineImp.h"
31
32using namespace std;
33
34template <class T>
35class LocalControl : public T
36{
37private:
38 char **Completion(const char *text, int pos, int)
39 {
40 return pos>0 ? 0 : T::Complete(fStateMachine->GetEventNames(), text);
41 }
42
43protected:
44 StateMachineImp *fStateMachine;
45
46 std::ostream &lout;
47
48 std::string fName;
49
50 LocalControl(const char *name) : T(name),
51 fStateMachine(0), lout(T::GetStreamIn()),
52#if BOOST_VERSION < 104600
53 fName(boost::filesystem::path(name).filename())
54#else
55 fName(boost::filesystem::path(name).filename().string())
56#endif
57 { }
58
59 bool PrintGeneralHelp()
60 {
61 T::PrintGeneralHelp();
62 lout << " " << kUnderline << "Specific commands:" << endl;
63 lout << kBold << " ac,allowed " << kReset << "Display a list of all currently allowed commands." << endl;
64 lout << kBold << " st,states " << kReset << "Display a list of the available states with description." << endl;
65 lout << kBold << " > <text> " << kReset << "Echo <text> to the output stream" << endl;
66 lout << kBold << " .s " << kReset << "Wait for the state-machine to change to the given state.\n";
67 lout << " " " .s <server> [<state> [<timeout> [<label>]]]\n";
68 lout << " " "<server> The server for which state to wait (e.g. FTM_CONTROL)\n";
69 lout << " " "<state> The state id (see 'states') for which to wait (e.g. 3)\n";
70 lout << " " "<imeout> A timeout in millisenconds how long to wait (e.g. 500)\n";
71 lout << " " "<label> A label until which everything is skipped in case of timeout\n";
72 lout << endl;
73 return true;
74 }
75 bool PrintCommands()
76 {
77 lout << endl << kBold << "List of commands:" << endl;
78 fStateMachine->PrintListOfEvents(lout);
79 lout << endl;
80
81 return true;
82 }
83
84 bool Process(const std::string &str)
85 {
86 if (str.substr(0, 2)=="h " || str.substr(0, 5)=="help ")
87 {
88 lout << endl;
89 fStateMachine->PrintListOfEvents(lout, str.substr(str.find_first_of(' ')+1));
90 lout << endl;
91
92 return true;
93 }
94 if (str=="states" || str=="st")
95 {
96 fStateMachine->PrintListOfStates(lout);
97 return true;
98 }
99 if (str=="allowed" || str=="ac")
100 {
101 lout << endl << kBold << "List of commands allowed in current state:" << endl;
102 fStateMachine->PrintListOfAllowedEvents(lout);
103 lout << endl;
104 return true;
105 }
106
107 if (str.substr(0, 3)==".s ")
108 {
109 istringstream in(str.substr(3));
110
111 int state=-100, ms=0;
112 in >> state >> ms;
113
114 if (state==-100)
115 {
116 lout << kRed << "Couldn't parse state id in '" << str.substr(3) << "'" << endl;
117 return true;
118 }
119
120 const Time timeout = ms<=0 ? Time(Time::none) : Time()+boost::posix_time::millisec(ms);
121
122 while (fStateMachine->GetCurrentState()!=state && timeout>Time() && !T::IsScriptStopped())
123 usleep(1);
124
125 if (fStateMachine->GetCurrentState()==state)
126 return true;
127
128 int label = -1;
129 in >> label;
130 if (in.fail() && !in.eof())
131 {
132 lout << kRed << "Invalid label in '" << str.substr(3) << "'" << endl;
133 T::StopScript();
134 return true;
135 }
136 T::SetLabel(label);
137
138 return true;
139 }
140
141 if (str[0]=='>')
142 {
143 fStateMachine->Comment(Tools::Trim(str.substr(1)));
144 return true;
145 }
146
147 if (T::Process(str))
148 return true;
149
150 return !fStateMachine->PostEvent(lout, str);
151 }
152
153public:
154
155 void SetReceiver(StateMachineImp &imp) { fStateMachine = &imp; }
156};
157
158// **************************************************************************
159/** @class LocalStream
160
161@brief Derives the LocalControl from ConsoleStream
162
163This is basically a LocalControl, which derives through the template
164argument from the ConsoleStream class.
165
166 */
167// **************************************************************************
168#include "Console.h"
169
170class LocalStream : public LocalControl<ConsoleStream>
171{
172public:
173 LocalStream(const char *name, bool null = false)
174 : LocalControl<ConsoleStream>(name) { SetNullOutput(null); }
175};
176
177// **************************************************************************
178/** @class LocalConsole
179
180@brief Derives the LocalControl from Control and adds prompt
181
182This is basically a LocalControl, which derives through the template
183argument from the Console class. It enhances the functionality of
184the local control with a proper updated prompt.
185
186 */
187// **************************************************************************
188#include "tools.h"
189
190class LocalConsole : public LocalControl<Console>
191{
192public:
193 LocalConsole(const char *name, bool continous=false)
194 : LocalControl<Console>(name)
195 {
196 SetContinous(continous);
197 }
198
199 string GetUpdatePrompt() const
200 {
201 return GetLinePrompt()+" "
202 "\001\033[34m\033[1m\002"+fName+"\001\033[0m\002:"
203 "\001\033[32m\033[1m\002"+fStateMachine->GetStateName()+"\001\033[0m\002> ";
204 }
205};
206
207// **************************************************************************
208/** @class LocalShell
209
210@brief Derives the LocalControl from Shell and adds a colored prompt
211
212This is basically a LocalControl, which derives through the template
213argument from the Shell class. It enhances the functionality of
214the local control with a proper updated prompt.
215
216 */
217// **************************************************************************
218#include "Shell.h"
219
220class LocalShell : public LocalControl<Shell>
221{
222public:
223 LocalShell(const char *name, bool = false)
224 : LocalControl<Shell>(name) { }
225
226 string GetUpdatePrompt() const
227 {
228 return GetLinePrompt()+' '+fName+':'+fStateMachine->GetStateName()+"> ";
229 }
230};
231
232#endif
Note: See TracBrowser for help on using the repository browser.