Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 5207 was 5207, checked in by bensch, 19 years ago

orxonox/trunk: default value can now be supplied as aditional arg of the SHELL_COMMAND-macro

File size: 6.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: ...
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_completion.h"
24#include "event_handler.h"
25
26#include "debug.h"
27#include "list.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 * standard constructor
40 * @todo this constructor is not jet implemented - do it
41*/
42ShellInput::ShellInput ()
43{
44  this->pressedKey = SDLK_FIRST;
45  this->setClassID(CL_SHELL_INPUT, "ShellInput");
46
47  this->inputLine = new char[1];
48  this->inputLine[0] = '\0';
49  this->inputHistory = new tList<char>;
50  this->delayed = 0;
51  this->setRepeatDelay(.3, .05);
52
53  // subscribe all keyboard commands to ES_SEHLL
54  EventHandler* evh = EventHandler::getInstance();
55  for (int i = 1; i < SDLK_LAST; i++)
56    evh->subscribe(this, ES_SHELL, i);
57
58  this->completion = new ShellCompletion(this);
59}
60
61/**
62 * standard deconstructor
63*/
64ShellInput::~ShellInput ()
65{
66  // delete what has to be deleted here
67  delete[] this->inputLine;
68  delete this->completion;
69
70  tIterator<char>* itH = this->inputHistory->getIterator();
71  char* histEl = itH->firstElement();
72  while (histEl != NULL)
73  {
74    delete[] histEl;
75    histEl = itH->nextElement();
76  }
77  delete itH;
78  delete this->inputHistory;
79}
80
81/**
82 * sets the Repeate-delay and rate
83 * @param repeatDelay the Delay it takes, to repeate a key
84 * @param repeatRate the rate to repeate a pressed key
85 */
86void ShellInput::setRepeatDelay(float repeatDelay, float repeatRate)
87{
88  this->repeatDelay = repeatDelay;
89  this->repeatRate = repeatRate;
90}
91
92/**
93 * deletes the InputLine
94 */
95void ShellInput::flush()
96{
97  if (likely(this->inputLine != NULL))
98  {
99    delete[] this->inputLine;
100  }
101  this->inputLine = new char[1];
102  *this->inputLine = '\0';
103  this->setText(this->inputLine, true);
104}
105
106/**
107 * adds one character to the inputLine
108 * @param character the character to add to the inputLine
109 */
110void ShellInput::addCharacter(char character)
111{
112  char* addCharLine = new char[strlen(this->inputLine)+2];
113
114  sprintf(addCharLine, "%s%c", this->inputLine, character);
115  delete[] this->inputLine;
116  this->inputLine = addCharLine;
117  this->setText(this->inputLine, true);
118}
119
120/**
121 * adds multiple Characters to thr inputLine
122 * @param characters a \\0 terminated char-array to add to the InputLine
123 */
124void ShellInput::addCharacters(const char* characters)
125{
126  char* addCharLine = new char[strlen(this->inputLine)+strlen(characters)+1];
127
128  sprintf(addCharLine, "%s%s", this->inputLine, characters);
129  delete[] this->inputLine;
130  this->inputLine = addCharLine;
131  this->setText(this->inputLine, true);
132}
133
134/**
135 * removes characterCount characters from the InputLine
136 * @param characterCount the count of Characters to remove from the input Line
137 */
138void ShellInput::removeCharacters(unsigned int characterCount)
139{
140  if (strlen(this->inputLine) == 0)
141    return;
142
143  if (characterCount > strlen(this->inputLine))
144    characterCount = strlen(this->inputLine);
145
146  char* removeCharLine = new char[strlen(this->inputLine)-characterCount+1];
147
148  strncpy(removeCharLine, this->inputLine, strlen(this->inputLine)-characterCount);
149  removeCharLine[strlen(this->inputLine)-characterCount] = '\0';
150  delete[] this->inputLine;
151  this->inputLine = removeCharLine;
152  this->setText(this->inputLine, true);
153}
154
155/**
156 * executes the command stored in the inputLine
157 * @return true if the command was commited successfully, false otherwise
158 */
159bool ShellInput::executeCommand()
160{
161  ShellBuffer::addBufferLineStatic("Execute Command: %s\n", this->inputLine);
162
163  char* newCommand = new char[strlen(this->inputLine)+1];
164  strcpy(newCommand, this->inputLine);
165  this->inputHistory->add(newCommand);
166
167  ShellCommandBase::execute(this->inputLine);
168
169  this->flush();
170
171  return false;
172}
173
174
175/**
176 * prints out some nice help about the Shell
177 */
178void ShellInput::help(const char* className, const char* functionName)
179{
180  printf("%s::%s\n", className, functionName);
181
182  if (strlen(className) == 0)
183  {
184    PRINT(0)("Help for the most important Shell-commands\n");
185    PRINT(0)("F1 - HELP; F2 - DEBUG; ` - open/close shell\n");
186    PRINT(0)("input order:\n");
187    PRINT(0)("ClassName [objectName] function [parameter1, [parameter2 ...]]  or\n");
188    PRINT(0)("Alias [parameter]\n");
189    PRINT(0)("- Also try 'help className'");
190  }
191  else if (strlen (className) > 0 && strlen (functionName) == 0)
192  {
193    ShellCommandClass::help(className);
194    //PRINTF(1)("%s::%s\n", className, functionName);
195  }
196}
197
198/**
199 * ticks the ShellInput
200 * @param dt the time passed since the last update
201 */
202void ShellInput::tick(float dt)
203{
204  if (this->delayed > 0.0)
205    this->delayed -= dt;
206  else if (this->pressedKey != SDLK_FIRST )
207  {
208    this->delayed = this->repeatRate;
209    if (this->pressedKey == SDLK_BACKSPACE)
210      this->removeCharacters(1);
211    else if (pressedKey < 127)
212      this->addCharacter(this->pressedKey);
213  }
214}
215
216/**
217 * listens for some event
218 * @param event the Event happened
219 */
220void ShellInput::process(const Event &event)
221{
222  if (event.bPressed)
223  {
224    PRINTF(5)("Shell received command %s\n", SDLKToKeyname(event.type));
225    if (event.type == SDLK_F1)
226      this->help();
227    else if (event.type == SDLK_F2)
228      this->debug();
229    else if (event.type == SDLK_TAB)
230      this->completion->autoComplete();
231    else if (event.type == SDLK_BACKSPACE)
232    {
233      this->delayed = this->repeatDelay;
234      this->pressedKey = SDLK_BACKSPACE;
235      this->removeCharacters(1);
236    }
237    else if (event.type == SDLK_RETURN)
238      this->executeCommand();
239    /*
240    else if (event.type == SDLK_UP)
241    {
242//      this->flushInputLine();
243    tIterator<char>* iterator = this->commandList->getIterator();
244    char* command = iterator->lastElement();
245    while (command)
246    {
247    if (!strcmp (command, inputLine))
248    {
249    inputLine = iterator->prevElement();
250    return;
251  }
252    command = iterator->prevElement();
253  }
254    inputLine = iterator->lastElement();
255  }
256    */
257    else if (likely(event.type < 127))
258    {
259      Uint8 *keystate = SDL_GetKeyState(NULL);
260      this->delayed = this->repeatDelay;
261      if (unlikely( keystate[SDLK_LSHIFT] || keystate[SDLK_RSHIFT] ))
262      {
263        this->pressedKey = event.type-32;
264        this->addCharacter(event.type-32);
265      }
266      else
267      {
268        this->pressedKey = event.type;
269        this->addCharacter(event.type);
270      }
271    }
272  }
273  else // if(!event.bPressed)
274  {
275    if (this->pressedKey == event.type || (this->pressedKey == event.type - 32))
276    {
277      this->pressedKey = SDLK_FIRST;
278      this->delayed = 0.0;
279    }
280  }
281}
Note: See TracBrowser for help on using the repository browser.