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, 19 years ago

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

File size: 7.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"
[5639]23#include "shell_command_class.h"
[5181]24#include "shell_completion.h"
[5180]25#include "event_handler.h"
[5179]26
27#include "debug.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*/
[7221]43ShellInput::ShellInput () : Text ("")
[3365]44{
[5179]45  this->pressedKey = SDLK_FIRST;
[5202]46  this->setClassID(CL_SHELL_INPUT, "ShellInput");
[4320]47
[7221]48  this->inputLine = "";
[5784]49  this->historyIT = this->history.begin();
[5245]50  this->setHistoryLength(50);
[5243]51  this->historyScrolling = false;
[5180]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++)
[5309]58  {
59    if (!evh->isSubscribed(ES_SHELL, i))
60      evh->subscribe(this, ES_SHELL, i);
61  }
[7341]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
[5184]68  this->completion = new ShellCompletion(this);
[3365]69}
[1853]70
[3245]71/**
[4838]72 * standard deconstructor
[3245]73*/
[5178]74ShellInput::~ShellInput ()
[3543]75{
76  // delete what has to be deleted here
[5181]77  delete this->completion;
[5182]78
[5784]79  while (!this->history.empty())
[5182]80  {
[5784]81    this->history.pop_front();
[5182]82  }
[3543]83}
[5179]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{
[7221]101  this->inputLine.clear();
102  this->setText(this->inputLine);
[5179]103}
104
105/**
[5244]106 * sets the entire text of the InputLine to text
107 * @param text the new Text to set as InputLine
108 */
[7221]109void ShellInput::setInputText(const std::string& text)
[5244]110{
[7221]111  this->inputLine = text;
112  this->setText(this->inputLine);
[5244]113}
114
115
116/**
[5179]117 * adds one character to the inputLine
118 * @param character the character to add to the inputLine
119 */
120void ShellInput::addCharacter(char character)
121{
[5244]122  if (this->historyScrolling)
123  {
[5784]124    this->history.pop_back();
[5244]125    this->historyScrolling = false;
126  }
127
[7221]128  this->inputLine += character;
129  this->setText(this->inputLine);
[5179]130}
131
132/**
133 * adds multiple Characters to thr inputLine
134 * @param characters a \\0 terminated char-array to add to the InputLine
135 */
[7221]136void ShellInput::addCharacters(const std::string& characters)
[5179]137{
[5244]138  if (this->historyScrolling)
139  {
[5784]140    this->history.pop_back();
[5244]141    this->historyScrolling = false;
142  }
143
[7221]144  this->inputLine += characters;
145  this->setText(this->inputLine);
[5179]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{
[5244]154  if (this->historyScrolling)
155  {
[5784]156    this->history.pop_back();
[5244]157    this->historyScrolling = false;
158  }
[7221]159  if (this->inputLine.size() < characterCount)
160    characterCount = this->inputLine.size();
[5244]161
[7221]162  this->inputLine.erase(this->inputLine.size() - characterCount, this->inputLine.size());
163  this->setText(this->inputLine);
[5179]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{
[7221]172  ShellBuffer::addBufferLineStatic("Execute Command: %s\n", this->inputLine.c_str());
[5179]173
[7221]174  if (this->inputLine.empty())
[5369]175    return false;
176
[7221]177  ShellCommand::execute(this->inputLine);
[5179]178
[5243]179  // removing the eventually added Entry (from scrolling) to the List
180  if (this->historyScrolling)
181  {
[5784]182    this->history.pop_back();
[5243]183    this->historyScrolling = false;
184  }
185
186  // adding the new Command to the History
[7221]187  this->history.push_back(this->inputLine);
[5784]188  if (this->history.size() > this->historyLength)
[5243]189  {
[5784]190    this->history.pop_front();
[5243]191  }
192
[5179]193  this->flush();
194
[5369]195  return true;
[5179]196}
197
[5180]198
199/**
[5243]200 * moves one entry up in the history.
201 */
202void ShellInput::historyMoveUp()
203{
204  if (!this->historyScrolling)
205  {
[7221]206    this->history.push_back(this->inputLine);
[5243]207    this->historyScrolling = true;
[5785]208    this->historyIT = --this->history.end();
[5243]209  }
210
[5785]211  if(this->historyIT != this->history.begin())
[5243]212  {
[7221]213    std::string prevElem = *(--this->historyIT);
214    /*if (prevElem == NULL) /// TODO STD
[5785]215      return;
[7221]216    else */
[5785]217    {
218      this->flush();
219      this->setInputText(prevElem);
220    }
[5243]221  }
222}
223
224/**
225 * moves one entry down in the history
226 */
227void ShellInput::historyMoveDown()
228{
229  if (!this->historyScrolling)
230    return;
[5785]231  if (this->historyIT != this->history.end())
[5243]232  {
[7221]233    std::string nextElem = *(++this->historyIT);
234    /*    if (nextElem == NULL) /// TODO FIX STD
[5785]235      return;
[7221]236    else */
[5785]237    {
238      this->flush();
239      this->setInputText(nextElem);
240    }
[5243]241  }
242}
243
244
245/**
[5180]246 * prints out some nice help about the Shell
247 */
[7221]248void ShellInput::help(const std::string& className, const std::string& functionName)
[5180]249{
[7221]250  printf("%s::%s\n", className.c_str(), functionName.c_str());
[5207]251
[7221]252  if (className.empty())
[5204]253  {
254    PRINT(0)("Help for the most important Shell-commands\n");
[5248]255    PRINT(0)("F1 - HELP; F2 - DEBUG; '`' - open/close shell\n");
[5204]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  }
[7221]261  else if (!className.empty() && functionName.empty())
[5204]262  {
263    ShellCommandClass::help(className);
264    //PRINTF(1)("%s::%s\n", className, functionName);
265  }
[5180]266}
267
[5197]268/**
269 * ticks the ShellInput
270 * @param dt the time passed since the last update
271 */
[5180]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;
[5786]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    }
[5180]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)
[5786]311    {
[5248]312      ;//this->debug();
[5786]313    }
[5243]314    else if (event.type == SDLK_UP)
[5786]315    {
[5243]316      this->historyMoveUp();
[5786]317      this->pressedKey = event.type;
318    }
[5243]319    else if (event.type == SDLK_DOWN)
[5786]320    {
[5243]321      this->historyMoveDown();
[5786]322      this->pressedKey = event.type;
323    }
[5180]324    else if (event.type == SDLK_TAB)
[5184]325      this->completion->autoComplete();
[5180]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)
[5786]333    {
[5180]334      this->executeCommand();
[5786]335      this->pressedKey = event.type;
336    }
[5244]337    // any other keyboard key
[5180]338    else if (likely(event.type < 127))
339    {
[5786]340      this->addCharacter(event.x);
341      this->pressedKey = event.x;
[5180]342    }
[5786]343    this->delayed = this->repeatDelay;
[5180]344  }
345  else // if(!event.bPressed)
346  {
[5787]347    if (this->pressedKey == event.x || this->pressedKey == event.type)
[5180]348    {
[5786]349      this->pressedKey = 0;
[5180]350      this->delayed = 0.0;
351    }
352  }
353}
Note: See TracBrowser for help on using the repository browser.