Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/shell/shell_input.cc @ 7341

Last change on this file since 7341 was 7341, checked in by bensch, 18 years ago

orxonox/trunk: shell in c++-style now

File size: 7.9 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14*/
15
16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
17
18#include "shell_input.h"
19
20
21
22#include "shell_command.h"
23#include "shell_command_class.h"
24#include "shell_completion.h"
25#include "event_handler.h"
26
27#include "debug.h"
28#include "compiler.h"
29#include "stdlibincl.h"
30#include "key_names.h"
31
32
33using namespace std;
34
35SHELL_COMMAND(help, ShellInput, help)
36    ->describe("retrieve some help about the input mode")
37    ->setAlias("help");
38
39/**
40 * constructor
41 * this also generates a ShellCompletion automatically.
42*/
43ShellInput::ShellInput () : Text ("")
44{
45  this->pressedKey = SDLK_FIRST;
46  this->setClassID(CL_SHELL_INPUT, "ShellInput");
47
48  this->inputLine = "";
49  this->historyIT = this->history.begin();
50  this->setHistoryLength(50);
51  this->historyScrolling = false;
52  this->delayed = 0;
53  this->setRepeatDelay(.3, .05);
54
55  // subscribe all keyboard commands to ES_SEHLL
56  EventHandler* evh = EventHandler::getInstance();
57  for (int i = 1; i < SDLK_LAST; i++)
58  {
59    if (!evh->isSubscribed(ES_SHELL, i))
60      evh->subscribe(this, ES_SHELL, i);
61  }
62  // unsubscribe unused TODO improve.
63  evh->unsubscribe(ES_SHELL, SDLK_BACKQUOTE);
64  evh->unsubscribe(ES_SHELL, SDLK_F12);
65  evh->unsubscribe(ES_SHELL, SDLK_PAGEUP);
66  evh->unsubscribe(ES_SHELL, SDLK_PAGEDOWN);
67
68  this->completion = new ShellCompletion(this);
69}
70
71/**
72 * standard deconstructor
73*/
74ShellInput::~ShellInput ()
75{
76  // delete what has to be deleted here
77  delete this->completion;
78
79  while (!this->history.empty())
80  {
81    this->history.pop_front();
82  }
83}
84
85/**
86 * sets the Repeate-delay and rate
87 * @param repeatDelay the Delay it takes, to repeate a key
88 * @param repeatRate the rate to repeate a pressed key
89 */
90void ShellInput::setRepeatDelay(float repeatDelay, float repeatRate)
91{
92  this->repeatDelay = repeatDelay;
93  this->repeatRate = repeatRate;
94}
95
96/**
97 * deletes the InputLine
98 */
99void ShellInput::flush()
100{
101  this->inputLine.clear();
102  this->setText(this->inputLine);
103}
104
105/**
106 * sets the entire text of the InputLine to text
107 * @param text the new Text to set as InputLine
108 */
109void ShellInput::setInputText(const std::string& text)
110{
111  this->inputLine = text;
112  this->setText(this->inputLine);
113}
114
115
116/**
117 * adds one character to the inputLine
118 * @param character the character to add to the inputLine
119 */
120void ShellInput::addCharacter(char character)
121{
122  if (this->historyScrolling)
123  {
124    this->history.pop_back();
125    this->historyScrolling = false;
126  }
127
128  this->inputLine += character;
129  this->setText(this->inputLine);
130}
131
132/**
133 * adds multiple Characters to thr inputLine
134 * @param characters a \\0 terminated char-array to add to the InputLine
135 */
136void ShellInput::addCharacters(const std::string& characters)
137{
138  if (this->historyScrolling)
139  {
140    this->history.pop_back();
141    this->historyScrolling = false;
142  }
143
144  this->inputLine += characters;
145  this->setText(this->inputLine);
146}
147
148/**
149 * removes characterCount characters from the InputLine
150 * @param characterCount the count of Characters to remove from the input Line
151 */
152void ShellInput::removeCharacters(unsigned int characterCount)
153{
154  if (this->historyScrolling)
155  {
156    this->history.pop_back();
157    this->historyScrolling = false;
158  }
159  if (this->inputLine.size() < characterCount)
160    characterCount = this->inputLine.size();
161
162  this->inputLine.erase(this->inputLine.size() - characterCount, this->inputLine.size());
163  this->setText(this->inputLine);
164}
165
166/**
167 * executes the command stored in the inputLine
168 * @return true if the command was commited successfully, false otherwise
169 */
170bool ShellInput::executeCommand()
171{
172  ShellBuffer::addBufferLineStatic("Execute Command: %s\n", this->inputLine.c_str());
173
174  if (this->inputLine.empty())
175    return false;
176
177  ShellCommand::execute(this->inputLine);
178
179  // removing the eventually added Entry (from scrolling) to the List
180  if (this->historyScrolling)
181  {
182    this->history.pop_back();
183    this->historyScrolling = false;
184  }
185
186  // adding the new Command to the History
187  this->history.push_back(this->inputLine);
188  if (this->history.size() > this->historyLength)
189  {
190    this->history.pop_front();
191  }
192
193  this->flush();
194
195  return true;
196}
197
198
199/**
200 * moves one entry up in the history.
201 */
202void ShellInput::historyMoveUp()
203{
204  if (!this->historyScrolling)
205  {
206    this->history.push_back(this->inputLine);
207    this->historyScrolling = true;
208    this->historyIT = --this->history.end();
209  }
210
211  if(this->historyIT != this->history.begin())
212  {
213    std::string prevElem = *(--this->historyIT);
214    /*if (prevElem == NULL) /// TODO STD
215      return;
216    else */
217    {
218      this->flush();
219      this->setInputText(prevElem);
220    }
221  }
222}
223
224/**
225 * moves one entry down in the history
226 */
227void ShellInput::historyMoveDown()
228{
229  if (!this->historyScrolling)
230    return;
231  if (this->historyIT != this->history.end())
232  {
233    std::string nextElem = *(++this->historyIT);
234    /*    if (nextElem == NULL) /// TODO FIX STD
235      return;
236    else */
237    {
238      this->flush();
239      this->setInputText(nextElem);
240    }
241  }
242}
243
244
245/**
246 * prints out some nice help about the Shell
247 */
248void ShellInput::help(const std::string& className, const std::string& functionName)
249{
250  printf("%s::%s\n", className.c_str(), functionName.c_str());
251
252  if (className.empty())
253  {
254    PRINT(0)("Help for the most important Shell-commands\n");
255    PRINT(0)("F1 - HELP; F2 - DEBUG; '`' - open/close shell\n");
256    PRINT(0)("input order:\n");
257    PRINT(0)("ClassName [objectName] function [parameter1, [parameter2 ...]]  or\n");
258    PRINT(0)("Alias [parameter]\n");
259    PRINT(0)("- Also try 'help className'");
260  }
261  else if (!className.empty() && functionName.empty())
262  {
263    ShellCommandClass::help(className);
264    //PRINTF(1)("%s::%s\n", className, functionName);
265  }
266}
267
268/**
269 * ticks the ShellInput
270 * @param dt the time passed since the last update
271 */
272void ShellInput::tick(float dt)
273{
274  if (this->delayed > 0.0)
275    this->delayed -= dt;
276  else if (this->pressedKey != SDLK_FIRST )
277  {
278    this->delayed = this->repeatRate;
279    switch (this->pressedKey )
280    {
281      case SDLK_BACKSPACE:
282        this->removeCharacters(1);
283        break;
284      case SDLK_UP:
285        this->historyMoveUp();
286        break;
287      case SDLK_DOWN:
288        this->historyMoveDown();
289        break;
290      default:
291      {
292        if (likely(pressedKey < 127))
293          this->addCharacter(this->pressedKey);
294      }
295    }
296  }
297}
298
299/**
300 * listens for some event
301 * @param event the Event happened
302 */
303void ShellInput::process(const Event &event)
304{
305  if (event.bPressed)
306  {
307    PRINTF(5)("Shell received command %s\n", SDLKToKeyname(event.type));
308    if (event.type == SDLK_F1)
309      this->help();
310    else if (event.type == SDLK_F2)
311    {
312      ;//this->debug();
313    }
314    else if (event.type == SDLK_UP)
315    {
316      this->historyMoveUp();
317      this->pressedKey = event.type;
318    }
319    else if (event.type == SDLK_DOWN)
320    {
321      this->historyMoveDown();
322      this->pressedKey = event.type;
323    }
324    else if (event.type == SDLK_TAB)
325      this->completion->autoComplete();
326    else if (event.type == SDLK_BACKSPACE)
327    {
328      this->delayed = this->repeatDelay;
329      this->pressedKey = SDLK_BACKSPACE;
330      this->removeCharacters(1);
331    }
332    else if (event.type == SDLK_RETURN)
333    {
334      this->executeCommand();
335      this->pressedKey = event.type;
336    }
337    // any other keyboard key
338    else if (likely(event.type < 127))
339    {
340      this->addCharacter(event.x);
341      this->pressedKey = event.x;
342    }
343    this->delayed = this->repeatDelay;
344  }
345  else // if(!event.bPressed)
346  {
347    if (this->pressedKey == event.x || this->pressedKey == event.type)
348    {
349      this->pressedKey = 0;
350      this->delayed = 0.0;
351    }
352  }
353}
Note: See TracBrowser for help on using the repository browser.