source: trunk/FACT++/src/Console.cc@ 19878

Last change on this file since 19878 was 18052, checked in by tbretz, 10 years ago
My gcc version needs unistd for usleep
File size: 7.1 KB
Line 
1// **************************************************************************
2/** @class Console
3
4@brief This is an extension to the Readline class provding buffered output
5
6This in an extension to the Readline class. It's purpose is to keep a
7buffered output stream and flush the stream either between readline entries
8(non continous mode) or continously, keeping the readline prompt as
9intact as possible.
10
11 */
12// **************************************************************************
13#include "Console.h"
14
15#include <unistd.h>
16
17#include <sstream>
18#include <iostream>
19
20#include "tools.h"
21
22#include "ReadlineColor.h"
23
24using namespace std;
25
26// --------------------------------------------------------------------------
27//
28//! Instantiate a console stream. It will create a WindowLog object
29//! and immediatel switch off its output to the console. The default more
30//! is non-continous.
31//!
32//! @param name
33//! The name of the program passed to the Readline constructor
34//!
35Console::Console(const char *name) : Readline(name), fContinous(false)
36{
37 fLogO.SetNullOutput();
38 fLogI.SetNullOutput();
39 fLogO.SetBacklog(true);
40 fLogI.SetBacklog(true);
41}
42
43// --------------------------------------------------------------------------
44//
45//! Flush the contents of the buffer before it is destroyed.
46//
47Console::~Console()
48{
49 // flush buffer to display before it is destroyed in its destructor
50 fLogO.Display();
51 fLogI.Display();
52}
53
54void Console::PrintReadlineError(const std::string &str)
55{
56 fLogI << kRed << str << endl;
57}
58
59// --------------------------------------------------------------------------
60//
61//! Wrapper to call the correspnding function from ReadlineColor
62//
63bool Console::PrintGeneralHelp()
64{
65 return ReadlineColor::PrintGeneralHelp(fLogI, GetName());
66}
67
68// --------------------------------------------------------------------------
69//
70//! Wrapper to call the correspnding function from ReadlineColor
71//
72bool Console::PrintCommands()
73{
74 return ReadlineColor::PrintCommands(fLogI);
75}
76
77// --------------------------------------------------------------------------
78//
79//! Wrapper to call the correspnding function from ReadlineColor
80//
81bool Console::PrintKeyBindings()
82{
83 return ReadlineColor::PrintKeyBindings(fLogI);
84}
85
86void Console::Lock()
87{
88 // FIXME: Check missing
89 fLogO.Display(true);
90 fLogO.SetBacklog(false);
91 fLogO.SetNullOutput(false);
92}
93
94void Console::Unlock()
95{
96 // FIXME: Check missing
97 fLogO.SetNullOutput(true);
98 fLogO.SetBacklog(true);
99}
100
101// --------------------------------------------------------------------------
102//
103//! Processes the command provided by the Shell-class.
104//!
105//! @returns
106//! whether a command was successfully processed or could not be found
107//
108bool Console::Process(const string &str)
109{
110 if (ReadlineColor::Process(fLogI, str))
111 return true;
112
113 if (str.substr(0, 3)==".w ")
114 {
115 Lock();
116 usleep(stoul(str.substr(3))*1000);
117 Unlock();
118 return true;
119 }
120
121 if (Readline::Process(str))
122 return true;
123
124 return false;
125}
126
127// --------------------------------------------------------------------------
128//
129//! Before readline starts flush the buffer to display all stuff which was
130//! buffered since the last readline call returned.
131//
132void Console::Startup()
133{
134 // Call readline's startup (just in case, it is empty)
135 Readline::Startup();
136
137 // First flush the buffer of the stream which is synchronous
138 // with the prompt
139 fLogI.Display(true);
140
141 // Now flush the stream which is asychronous
142 fLogO.Display(true);
143
144 // The order has the advantage that output initiated by the prompt
145 // is not interrupter by the synchronous stream
146}
147
148// --------------------------------------------------------------------------
149//
150//! Flush the buffer if we are in continous mode, and call Readline's
151//! EventHook to update the prompt.
152//
153void Console::EventHook(bool)
154{
155 // If the output is continous and we are going to output something
156 // first jump back to the beginning of the line (well, that
157 // doesn't work well if the input line is already two lines)
158 // and then flush the buffer.
159 const bool newline = fContinous && fLogO.GetSizeBacklog()>0;
160 if (newline)
161 {
162 // Clear the line we are going to overwrite
163 std::cout << "\r\033[0K";
164 fLogO.Display(true);
165 }
166
167 // Call Readline's EventHook to update the prompt
168 // and signal readline so that a new prompt is displayed
169 Readline::EventHook(newline);
170}
171
172string Console::GetLinePrompt() const
173{
174 const string siz = fLogO.GetSizeStr();
175
176 ostringstream str;
177 str << '[' << GetLine();
178 return fContinous ? str.str()+']' : str.str()+':'+siz+']';
179}
180
181// --------------------------------------------------------------------------
182//
183//! Before Readline::Run() is called the buffer is flushed as well as
184//! after the Run() loop has exited.
185//! command processing. This keeps things as seperated as possible,
186//! although there is no gurantee.
187//
188void Console::Run(const char *)
189{
190 // Flush the buffer before we print the boot message
191 fLogO.Display(true);
192
193 ReadlineColor::PrintBootMsg(fLogI, GetName());
194
195 // Flush the buffer before we start out readline loop
196 fLogI.Display(true);
197 fLogO.Display(true);
198
199 // Now run readlines main loop
200 Readline::Run();
201
202 // flush buffer to display
203 fLogI.Display(true);
204 fLogO.Display(true);
205}
206
207// **************************************************************************
208/** @class ConsoleStream
209
210@brief This is an extension to the Readline class provding a colored output
211
212This in an extension to the Readline class. It's purpose is just to have a
213colored output stream available. It's main idea is that it is used in
214environments without user interaction as a replacement the Console class.
215This is interesting to be able to do everything identical as if Console
216would be used, but Run() does not prompt but just wait until Stop()
217was called. The advantage is that some functions of Readline can be used
218like Execute and the history (just for Execute() commands of course)
219
220 */
221// **************************************************************************
222
223ConsoleStream::~ConsoleStream()
224{
225 fLogO.Display();
226}
227
228// --------------------------------------------------------------------------
229//
230//! Instantiate a console stream. It will create a single WindowLog object
231//! which is returned as input and output stream.
232//!
233//! @param name
234//! The name of the program passed to the Readline constructor
235//!
236ConsoleStream::ConsoleStream(const char *name) : Readline(name)
237{
238 fLogO.SetBacklog(false);
239 fLogO.SetNullOutput(false);
240 ReadlineColor::PrintBootMsg(fLogO, GetName(), false);
241}
242
243void ConsoleStream::PrintReadlineError(const std::string &str)
244{
245 fLogO << kRed << str << endl;
246}
247
248// --------------------------------------------------------------------------
249//
250//! Just usleep until Stop() was called.
251//
252void ConsoleStream::Run(const char *)
253{
254 while (!IsStopped())
255 {
256 const string buf = GetExternalInput();
257 SetExternalInput("");
258 if (!buf.empty())
259 ProcessLine(buf);
260
261 usleep(100000);
262 }
263}
Note: See TracBrowser for help on using the repository browser.