Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 5309 was 5309, checked in by bensch, 20 years ago

orxonox/trunk: Ckeck if an Event is already subscribed via isSubscribed, and using it in the ShellInput

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