aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Console/LocalConsole.cs
diff options
context:
space:
mode:
authorMelanie Thielker2009-05-04 12:15:55 +0000
committerMelanie Thielker2009-05-04 12:15:55 +0000
commit1b877234dada9f14cebc486cc426db892beae152 (patch)
tree762ee7172c66a78b643f4cef0eed946314816403 /OpenSim/Framework/Console/LocalConsole.cs
parentThanks BlueWall for Mantis #3578 - adding Hypergrid connection to JSON Stats (diff)
downloadopensim-SC-1b877234dada9f14cebc486cc426db892beae152.zip
opensim-SC-1b877234dada9f14cebc486cc426db892beae152.tar.gz
opensim-SC-1b877234dada9f14cebc486cc426db892beae152.tar.bz2
opensim-SC-1b877234dada9f14cebc486cc426db892beae152.tar.xz
Refactor. Make ConsoleBase a true base class. Create CommandConsole as a simple
console capable of processing commands. Create LocalConsole as a console that uses cursor control and context help. Precursor to a distributed console system for the new grid services. No functional change intended :)
Diffstat (limited to 'OpenSim/Framework/Console/LocalConsole.cs')
-rw-r--r--OpenSim/Framework/Console/LocalConsole.cs470
1 files changed, 470 insertions, 0 deletions
diff --git a/OpenSim/Framework/Console/LocalConsole.cs b/OpenSim/Framework/Console/LocalConsole.cs
new file mode 100644
index 0000000..9dde969
--- /dev/null
+++ b/OpenSim/Framework/Console/LocalConsole.cs
@@ -0,0 +1,470 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Diagnostics;
31using System.Reflection;
32using System.Text;
33using System.Threading;
34using log4net;
35
36namespace OpenSim.Framework.Console
37{
38 // A console that uses cursor control and color
39 //
40 public class LocalConsole : CommandConsole
41 {
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43
44 private readonly object m_syncRoot = new object();
45
46 private int y = -1;
47 private int cp = 0;
48 private int h = 1;
49 private string prompt = "# ";
50 private StringBuilder cmdline = new StringBuilder();
51 private bool echo = true;
52 private List<string> history = new List<string>();
53
54 public LocalConsole(string defaultPrompt) : base(defaultPrompt)
55 {
56 }
57
58 private void AddToHistory(string text)
59 {
60 while (history.Count >= 100)
61 history.RemoveAt(0);
62
63 history.Add(text);
64 }
65
66 /// <summary>
67 /// derive an ansi color from a string, ignoring the darker colors.
68 /// This is used to help automatically bin component tags with colors
69 /// in various print functions.
70 /// </summary>
71 /// <param name="input">arbitrary string for input</param>
72 /// <returns>an ansii color</returns>
73 protected override ConsoleColor DeriveColor(string input)
74 {
75 int colIdx = (input.ToUpper().GetHashCode() % 6) + 9;
76 return (ConsoleColor) colIdx;
77 }
78
79 private int SetCursorTop(int top)
80 {
81 if (top >= 0 && top < System.Console.BufferHeight)
82 {
83 System.Console.CursorTop = top;
84 return top;
85 }
86 else
87 {
88 return System.Console.CursorTop;
89 }
90 }
91
92 private int SetCursorLeft(int left)
93 {
94 if (left >= 0 && left < System.Console.BufferWidth)
95 {
96 System.Console.CursorLeft = left;
97 return left;
98 }
99 else
100 {
101 return System.Console.CursorLeft;
102 }
103 }
104
105 protected override void WriteNewLine(ConsoleColor senderColor, string sender, ConsoleColor color, string format, params object[] args)
106 {
107 lock (cmdline)
108 {
109 if (y != -1)
110 {
111 y=SetCursorTop(y);
112 System.Console.CursorLeft = 0;
113
114 int count = cmdline.Length;
115
116 System.Console.Write(" ");
117 while (count-- > 0)
118 System.Console.Write(" ");
119
120 y=SetCursorTop(y);
121 System.Console.CursorLeft = 0;
122 }
123 WritePrefixLine(senderColor, sender);
124 WriteConsoleLine(color, format, args);
125 if (y != -1)
126 y = System.Console.CursorTop;
127 }
128 }
129
130 protected override void WriteNewLine(ConsoleColor color, string format, params object[] args)
131 {
132 lock (cmdline)
133 {
134 if (y != -1)
135 {
136 y=SetCursorTop(y);
137 System.Console.CursorLeft = 0;
138
139 int count = cmdline.Length;
140
141 System.Console.Write(" ");
142 while (count-- > 0)
143 System.Console.Write(" ");
144
145 y=SetCursorTop(y);
146 System.Console.CursorLeft = 0;
147 }
148 WriteConsoleLine(color, format, args);
149 if (y != -1)
150 y = System.Console.CursorTop;
151 }
152 }
153
154 protected override void WriteConsoleLine(ConsoleColor color, string format, params object[] args)
155 {
156 try
157 {
158 lock (m_syncRoot)
159 {
160 try
161 {
162 if (color != ConsoleColor.White)
163 System.Console.ForegroundColor = color;
164
165 System.Console.WriteLine(format, args);
166 System.Console.ResetColor();
167 }
168 catch (ArgumentNullException)
169 {
170 // Some older systems dont support coloured text.
171 System.Console.WriteLine(format, args);
172 }
173 catch (FormatException)
174 {
175 System.Console.WriteLine(args);
176 }
177 }
178 }
179 catch (ObjectDisposedException)
180 {
181 }
182 }
183
184 protected override void WritePrefixLine(ConsoleColor color, string sender)
185 {
186 try
187 {
188 lock (m_syncRoot)
189 {
190 sender = sender.ToUpper();
191
192 System.Console.WriteLine("[" + sender + "] ");
193
194 System.Console.Write("[");
195
196 try
197 {
198 System.Console.ForegroundColor = color;
199 System.Console.Write(sender);
200 System.Console.ResetColor();
201 }
202 catch (ArgumentNullException)
203 {
204 // Some older systems dont support coloured text.
205 System.Console.WriteLine(sender);
206 }
207
208 System.Console.Write("] \t");
209 }
210 }
211 catch (ObjectDisposedException)
212 {
213 }
214 }
215
216 private void Show()
217 {
218 lock (cmdline)
219 {
220 if (y == -1 || System.Console.BufferWidth == 0)
221 return;
222
223 int xc = prompt.Length + cp;
224 int new_x = xc % System.Console.BufferWidth;
225 int new_y = y + xc / System.Console.BufferWidth;
226 int end_y = y + (cmdline.Length + prompt.Length) / System.Console.BufferWidth;
227 if (end_y / System.Console.BufferWidth >= h)
228 h++;
229 if (end_y >= System.Console.BufferHeight) // wrap
230 {
231 y--;
232 new_y--;
233 System.Console.CursorLeft = 0;
234 System.Console.CursorTop = System.Console.BufferHeight-1;
235 System.Console.WriteLine(" ");
236 }
237
238 y=SetCursorTop(y);
239 System.Console.CursorLeft = 0;
240
241 if (echo)
242 System.Console.Write("{0}{1}", prompt, cmdline);
243 else
244 System.Console.Write("{0}", prompt);
245
246 SetCursorLeft(new_x);
247 SetCursorTop(new_y);
248 }
249 }
250
251 public override void LockOutput()
252 {
253 Monitor.Enter(cmdline);
254 try
255 {
256 if (y != -1)
257 {
258 y = SetCursorTop(y);
259 System.Console.CursorLeft = 0;
260
261 int count = cmdline.Length + prompt.Length;
262
263 while (count-- > 0)
264 System.Console.Write(" ");
265
266 y = SetCursorTop(y);
267 System.Console.CursorLeft = 0;
268
269 }
270 }
271 catch (Exception)
272 {
273 }
274 }
275
276 public override void UnlockOutput()
277 {
278 if (y != -1)
279 {
280 y = System.Console.CursorTop;
281 Show();
282 }
283 Monitor.Exit(cmdline);
284 }
285
286 public override void Output(string text)
287 {
288 lock (cmdline)
289 {
290 if (y == -1)
291 {
292 System.Console.WriteLine(text);
293
294 return;
295 }
296
297 y = SetCursorTop(y);
298 System.Console.CursorLeft = 0;
299
300 int count = cmdline.Length + prompt.Length;
301
302 while (count-- > 0)
303 System.Console.Write(" ");
304
305 y = SetCursorTop(y);
306 System.Console.CursorLeft = 0;
307
308 System.Console.WriteLine(text);
309
310 y = System.Console.CursorTop;
311
312 Show();
313 }
314 }
315
316 private bool ContextHelp()
317 {
318 string[] words = Parser.Parse(cmdline.ToString());
319
320 bool trailingSpace = cmdline.ToString().EndsWith(" ");
321
322 // Allow ? through while typing a URI
323 //
324 if (words.Length > 0 && words[words.Length-1].StartsWith("http") && !trailingSpace)
325 return false;
326
327 string[] opts = Commands.FindNextOption(words, trailingSpace);
328
329 if (opts[0].StartsWith("Command help:"))
330 Output(opts[0]);
331 else
332 Output(String.Format("Options: {0}", String.Join(" ", opts)));
333
334 return true;
335 }
336
337 public override string ReadLine(string p, bool isCommand, bool e)
338 {
339 h = 1;
340 cp = 0;
341 prompt = p;
342 echo = e;
343 int historyLine = history.Count;
344
345 System.Console.CursorLeft = 0; // Needed for mono
346 System.Console.Write(" "); // Needed for mono
347
348 lock (cmdline)
349 {
350 y = System.Console.CursorTop;
351 cmdline.Remove(0, cmdline.Length);
352 }
353
354 while (true)
355 {
356 Show();
357
358 ConsoleKeyInfo key = System.Console.ReadKey(true);
359 char c = key.KeyChar;
360
361 if (!Char.IsControl(c))
362 {
363 if (cp >= 318)
364 continue;
365
366 if (c == '?' && isCommand)
367 {
368 if (ContextHelp())
369 continue;
370 }
371
372 cmdline.Insert(cp, c);
373 cp++;
374 }
375 else
376 {
377 switch (key.Key)
378 {
379 case ConsoleKey.Backspace:
380 if (cp == 0)
381 break;
382 cmdline.Remove(cp-1, 1);
383 cp--;
384
385 System.Console.CursorLeft = 0;
386 y = SetCursorTop(y);
387
388 System.Console.Write("{0}{1} ", prompt, cmdline);
389
390 break;
391 case ConsoleKey.End:
392 cp = cmdline.Length;
393 break;
394 case ConsoleKey.Home:
395 cp = 0;
396 break;
397 case ConsoleKey.UpArrow:
398 if (historyLine < 1)
399 break;
400 historyLine--;
401 LockOutput();
402 cmdline.Remove(0, cmdline.Length);
403 cmdline.Append(history[historyLine]);
404 cp = cmdline.Length;
405 UnlockOutput();
406 break;
407 case ConsoleKey.DownArrow:
408 if (historyLine >= history.Count)
409 break;
410 historyLine++;
411 LockOutput();
412 if (historyLine == history.Count)
413 {
414 cmdline.Remove(0, cmdline.Length);
415 }
416 else
417 {
418 cmdline.Remove(0, cmdline.Length);
419 cmdline.Append(history[historyLine]);
420 }
421 cp = cmdline.Length;
422 UnlockOutput();
423 break;
424 case ConsoleKey.LeftArrow:
425 if (cp > 0)
426 cp--;
427 break;
428 case ConsoleKey.RightArrow:
429 if (cp < cmdline.Length)
430 cp++;
431 break;
432 case ConsoleKey.Enter:
433 System.Console.CursorLeft = 0;
434 y = SetCursorTop(y);
435
436 System.Console.WriteLine("{0}{1}", prompt, cmdline);
437
438 lock (cmdline)
439 {
440 y = -1;
441 }
442
443 if (isCommand)
444 {
445 string[] cmd = Commands.Resolve(Parser.Parse(cmdline.ToString()));
446
447 if (cmd.Length != 0)
448 {
449 int i;
450
451 for (i=0 ; i < cmd.Length ; i++)
452 {
453 if (cmd[i].Contains(" "))
454 cmd[i] = "\"" + cmd[i] + "\"";
455 }
456 AddToHistory(String.Join(" ", cmd));
457 return String.Empty;
458 }
459 }
460
461 AddToHistory(cmdline.ToString());
462 return cmdline.ToString();
463 default:
464 break;
465 }
466 }
467 }
468 }
469 }
470}