Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/util/shell.cc @ 5126

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

orxonox/trunk: the shell is now able to handle newLines

File size: 20.6 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:
[5068]12   main-programmer: Benjamin Grauer
[1855]13   co-programmer: ...
[1853]14*/
15
[3955]16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
[1853]17
[5068]18#include "shell.h"
[1853]19
[5072]20#include "text_engine.h"
21#include "list.h"
[5093]22#include "graphics_engine.h"
23#include "event_handler.h"
[5072]24
[5100]25#include "load_param.h"
[5113]26#include "class_list.h"
27
28#include "key_names.h"
[5093]29#include "debug.h"
[5075]30#include <stdarg.h>
31#include <stdio.h>
32
[1856]33using namespace std;
[1853]34
[1856]35
[3245]36/**
[4838]37 * standard constructor
[5068]38 */
39Shell::Shell ()
[3365]40{
[5072]41  this->setClassID(CL_SHELL, "Shell");
42  this->setName("Shell");
43
[5113]44  this->shellHeight = 400;
45  this->bActive = false;
[5072]46  this->buffer = new tList<char>;
[5118]47  this->bufferIterator = this->buffer->getIterator();
[5072]48
[5113]49  this->textSize = 15;
50  this->lineSpacing = 5;
[5080]51
[5074]52  //this->bufferSize = 0;
[5080]53  this->bufferText = NULL;
[5072]54  this->setBufferSize(100);
[5113]55  this->bufferDisplaySize = 10;
56  this->setAbsCoor2D(3, -400);
[5095]57  this->delayed = 0;
[5097]58  this->setRepeatDelay(.3, .05);
[5095]59  this->pressedKey = SDLK_FIRST;
[5074]60
[5113]61  this->inputLineText = NULL;
[5093]62  this->inputLine = new char[1];
63  this->inputLine[0] = '\0';
64
[5113]65  this->rebuildText();
66  this->completionList = NULL;
[5093]67
[5113]68  // EVENT-Handler subscription of '`' to all States, and all other keyboard commands to ES_SEHLL
[5093]69  EventHandler* evh = EventHandler::getInstance();
[5096]70  evh->subscribe(this, ES_ALL, SDLK_BACKQUOTE);
[5119]71  for (int i = 1; i < SDLK_LAST; i++)
[5095]72    evh->subscribe(this, ES_SHELL, i);
[5068]73}
[4320]74
[5068]75Shell* Shell::singletonRef = NULL;
[1853]76
[3245]77/**
[4838]78 * standard deconstructor
[5068]79 */
80Shell::~Shell ()
[3543]81{
[5099]82  // delete the displayable Buffers
[5080]83  for (int i = 0; i < this->bufferDisplaySize; i++)
84    delete this->bufferText[i];
[5113]85  delete[] this->bufferText;
[5093]86
[5099]87  // delete the inputLine
[5080]88  delete this->inputLineText;
[5093]89  delete this->inputLine;
[5079]90
[5099]91  // delete all the Chars in the Buffers
[5118]92  char* charElem = this->bufferIterator->firstElement();
[5099]93  while (charElem != NULL)
94  {
95    delete charElem;
[5118]96    charElem = this->bufferIterator->nextElement();
[5099]97  }
[5118]98  delete this->bufferIterator;
[5099]99
[5113]100//  if (this->completionList != NULL)
101    //delete this->completionList;
102
[5068]103  Shell::singletonRef = NULL;
[3543]104}
[5068]105
[5113]106
[5119]107/**
108 * activates the shell
109 *
110 * This also feeds the Last few lines from the main buffers into the displayBuffer
111 */
[5113]112void Shell::activate()
113{
114  if (this->bActive == true)
115    PRINTF(3)("The shell is already active\n");
116  this->bActive = true;
117
118  EventHandler::getInstance()->setState(ES_SHELL);
119  this->setRelCoorSoft2D(0, 0, 1, 5);
[5118]120
121  this->bufferIterator->lastElement();
122  for (int i = 0; i < this->bufferDisplaySize; i++)
123    this->bufferText[i]->setText(this->bufferIterator->prevElement());
[5113]124}
125
[5119]126/**
127 * deactiveates the Shell.
128 */
[5113]129void Shell::deactivate()
130{
131  if (this->bActive == false)
132    PRINTF(3)("The shell is already inactive\n");
133  this->bActive = false;
134
135  EventHandler::getInstance()->setState(ES_GAME);
136  this->setRelCoorSoft2D(0, -400, 1, 5);
[5118]137
[5113]138}
139
[5119]140/**
141 * sets the size of the text and spacing
142 * @param textSize the size of the Text in Pixels
143 * @param lineSpacing the size of the Spacing between two lines in pixels
144 *
145 * this also rebuilds the entire Text, inputLine and displayBuffer,
146 * to be accurate again.
147 */
[5113]148void Shell::setTextSize(unsigned int textSize, unsigned int lineSpacing)
149{
150  this->textSize = textSize;
151  this->lineSpacing = lineSpacing;
152
153  this->rebuildText();
154}
155
156void Shell::rebuildText()
157{
158  if (this->inputLineText == NULL)
159    delete this->inputLineText;
[5122]160  this->inputLineText = TextEngine::getInstance()->createText("fonts/Aniron_Bold.ttf", this->textSize, TEXT_RENDER_DYNAMIC);
[5121]161  this->inputLineText->setColor(1, 0, 0);
[5113]162  this->inputLineText->setAlignment(TEXT_ALIGN_LEFT);
163  this->inputLineText->setText(NULL);
164  this->inputLineText->setParent2D(this);
[5124]165  this->inputLineText->setRelCoor2D(5, (this->textSize + this->lineSpacing)*this->bufferDisplaySize + this->textSize);
[5113]166
167  this->setBufferDisplaySize(this->bufferDisplaySize);
168}
169
[5074]170/**
171 * sets The count of Lines to display in the buffer.
172 * @param bufferDisplaySize the count of lines to display in the Shell-Buffer.
173 */
[5072]174void Shell::setBufferDisplaySize(unsigned int bufferDisplaySize)
175{
[5080]176  if (this->bufferText != NULL)
[5072]177  {
[5080]178    for (unsigned int i = 0; i < this->bufferDisplaySize; i++)
179      delete this->bufferText[i];
[5113]180    delete[] this->bufferText;
[5072]181  }
[5080]182
183  this->bufferText = new Text*[bufferDisplaySize];
184  for (unsigned int i = 0; i < bufferDisplaySize; i++)
[5072]185  {
[5122]186    this->bufferText[i] = TextEngine::getInstance()->createText("fonts/Aniron_Bold.ttf", this->textSize, TEXT_RENDER_DYNAMIC);
[5121]187    this->bufferText[i]->setColor(1, 0, 0);
[5080]188    this->bufferText[i]->setAlignment(TEXT_ALIGN_LEFT);
[5120]189    this->bufferText[i]->setRelCoor2D(calculateLinePosition(i));
[5080]190    this->bufferText[i]->setText(NULL);
[5089]191    this->bufferText[i]->setParent2D(this);
[5072]192  }
[5113]193  this->bufferDisplaySize = bufferDisplaySize;
[5111]194
[5113]195  this->shellHeight = (this->textSize + this->lineSpacing) * (bufferDisplaySize+1);
[5072]196}
[5068]197
198/**
199 * deletes all the Buffers
200 */
201void Shell::flushBuffers()
202{
[5072]203  // remove all chars from the BufferTexts.
[5080]204  if (this->bufferText)
[5125]205    for (int i = 0; i < this->bufferDisplaySize; i++)
[5080]206    {
[5125]207      this->bufferText[i]->setText(NULL, true);
[5080]208    }
[5068]209
[5072]210  // delete all the Chars in the Buffers
211  tIterator<char>* charIterator = this->buffer->getIterator();
[5115]212  char* charElem = charIterator->firstElement();
[5072]213  while (charElem != NULL)
214  {
215    delete charElem;
216
217    charElem = charIterator->nextElement();
218  }
219  delete charIterator;
[5125]220  delete this->buffer;
221  this->buffer = new tList<char>;
[5068]222}
223
224/**
225 * adds a new Line to the List of Buffers
226 * @param line the Line as in the first argument in printf
227 * @param args the arguments as a va_list
228 */
[5075]229bool Shell::addBufferLineStatic(const char* line, ...)
[5068]230{
[5075]231  va_list arguments;
232  va_start(arguments, line);
[5072]233
[5092]234#if DEBUG < 3
[5075]235  if (Shell::singletonRef == NULL)
[5089]236#endif
237
238  vprintf(line, arguments);
[5092]239#if DEBUG < 3
[5075]240  else
[5092]241#else
242  if (Shell::singletonRef != NULL)
[5089]243#endif
[5075]244    Shell::singletonRef->addBufferLine(line, arguments);
245  return true;
246}
[5072]247
[5080]248/**
249 * add a Line to the List of Buffers
250 * @param line
251 * @param arguments
252 *
253 * This function Adds one line to the buffer.
254 * and displays the line as the First Line of the display-buffer
255 */
[5075]256void Shell::addBufferLine(const char* line, va_list arguments)
257{
[5078]258   vsprintf(this->bufferArray, line, arguments);
[5072]259
[5126]260   unsigned int inputLength = strlen(this->bufferArray);
261   char* newLineBegin = this->bufferArray;
262   char* newLineEnd;
[5073]263
[5126]264   while (newLineBegin < this->bufferArray + inputLength)
[5080]265   {
[5126]266     newLineEnd = strchr(newLineBegin, '\n');
267     if (newLineEnd != NULL && *newLineEnd == '\n')
268       *newLineEnd = '\0';
269     else
270       break;
[5080]271
[5126]272     char* addLine = new char[strlen(newLineBegin)+1];
273     strcpy(addLine, newLineBegin);
274
275     this->buffer->add(addLine);
276
277     if (this->buffer->getSize() > this->bufferSize)
278     {
279       delete this->buffer->firstElement();
280       this->buffer->remove(this->buffer->firstElement());
281     }
282
283     if (this->bActive)
284     {
285       this->printToDisplayBuffer(addLine);
286     }
287     newLineBegin = newLineEnd+1;
[5118]288   }
289}
[5113]290
[5118]291/**
292 * prints out some text to the input-buffers
293 * @param text the text to output.
294 */
295void Shell::printToDisplayBuffer(const char* text)
296{
297  if(likely(bufferText != NULL))
298  {
299    Text* lastText = this->bufferText[this->bufferDisplaySize-1];
[5113]300
[5118]301    Text* swapText;
302    Text* moveText = this->bufferText[0];
[5120]303    this->bufferText[0]->setRelCoorSoft2D(this->calculateLinePosition(1),10);
[5118]304    for (unsigned int i = 1; i < this->bufferDisplaySize; i++)
305    {
306      if ( i < this->bufferDisplaySize-1)
[5120]307        this->bufferText[i]->setRelCoorSoft2D(this->calculateLinePosition(i+1),5);
[5118]308      swapText = this->bufferText[i];
309      this  ->bufferText[i] = moveText;
310      moveText = swapText;
311    }
[5120]312    lastText->setRelCoor2D(this->calculateLinePosition(0));
[5118]313    this->bufferText[0] = lastText;
314
[5122]315    this->bufferText[0]->setText(text, true);
[5118]316  }
[5068]317}
318
319/**
320 * moves the buffer around lineCount lines upwards (negative values move down)
321 * @param lineCount the Count of lines to move upwards
[5072]322 *
323 * @todo
[5068]324 */
325void Shell::moveBuffer(int lineCount)
326{
327}
328
329/**
330 * @param lineNumber the n-th line from the bottom
331 * @returns the Buffer at Line lineNumber
332 */
333const char* Shell::getBufferLine(unsigned int lineNumber)
334{
[5072]335  tIterator<char>* charIterator = this->buffer->getIterator();
[5115]336  char* charElem = charIterator->firstElement();
[5072]337
338  int i = 1;
339  while (charElem != NULL)
340  {
341    if (i++ < lineNumber)
342    {
343      delete charIterator;
344      return charElem;
345    }
346
347    charElem = charIterator->nextElement();
348  }
349  delete charIterator;
[5068]350}
351
352/**
353 * deletes the InputLine
354 */
355void Shell::flushInputLine()
356{
[5072]357  if (likely(this->inputLine != NULL))
358  {
[5125]359    delete[] this->inputLine;
[5072]360  }
361  this->inputLine = new char[1];
362  *this->inputLine = '\0';
[5125]363  this->inputLineText->setText(this->inputLine, true);
[5068]364}
365
366/**
367 * adds one character to the inputLine
368 * @param character the character to add to the inputLine
369 */
370void Shell::addCharacter(char character)
371{
[5072]372  char* addCharLine = new char[strlen(inputLine)+2];
373
374  sprintf(addCharLine, "%s%c", this->inputLine, character);
375  delete this->inputLine;
376  this->inputLine = addCharLine;
[5123]377  this->inputLineText->setText(inputLine, true);
[5068]378}
379
380/**
381 * adds multiple Characters to thr inputLine
382 * @param characters a '\0' terminated char-array to add to the InputLine
383 */
384void Shell::addCharacters(const char* characters)
385{
[5072]386  char* addCharLine = new char[strlen(inputLine)+strlen(characters)+1];
387
388  sprintf(addCharLine, "%s%s", this->inputLine, characters);
389  delete this->inputLine;
390  this->inputLine = addCharLine;
[5093]391  this->inputLineText->setText(inputLine);
[5068]392}
393
394/**
395 * removes characterCount characters from the InputLine
396 * @param characterCount the count of Characters to remove from the input Line
397 */
398void Shell::removeCharacters(unsigned int characterCount)
399{
[5093]400  if (strlen(this->inputLine) == 0)
401    return;
402
[5072]403  if (characterCount > strlen(this->inputLine))
404    characterCount = strlen(this->inputLine);
405
406  char* removeCharLine = new char[strlen(inputLine)-characterCount+1];
407
408  strncpy(removeCharLine, this->inputLine, strlen(inputLine)-characterCount);
[5093]409  removeCharLine[strlen(inputLine)-characterCount] = '\0';
[5072]410  delete this->inputLine;
411  this->inputLine = removeCharLine;
[5093]412  this->inputLineText->setText(inputLine);
[5068]413}
414
[5096]415/**
416 * executes the command stored in the inputLine
417 * @return true if the command was commited successfully, false otherwise
418 */
419bool Shell::executeCommand()
420{
421  this->addBufferLineStatic("Execute Command: %s\n", this->inputLine);
[5125]422
423  if (!strcmp(this->inputLine, "clear"))
424  {
425    this->flushBuffers();
[5126]426    this->addBufferLine("orxonox - shell\n ==================== \n", NULL);
[5125]427  }
428
429  this->flushInputLine();
430
[5096]431  return false;
432}
433
[5097]434/**
435 * sets the Repeate-delay and rate
436 * @param repeatDelay the Delay it takes, to repeate a key
437 * @param repeatRate the rate to repeate a pressed key
438 */
439void Shell::setRepeatDelay(float repeatDelay, float repeatRate)
440{
441  this->repeatDelay = repeatDelay;
442  this->repeatRate = repeatRate;
443
444}
445
[5069]446/**
447 * listens for some event
448 * @param event the Event happened
449 */
450void Shell::process(const Event &event)
451{
[5093]452  if (event.bPressed)
453  {
454    PRINTF(4)("Shell received command %s\n", SDLKToKeyname(event.type));
455    if (event.type == SDLK_BACKQUOTE)
456    {
457      if (EventHandler::getInstance()->getState() == ES_GAME)
[5113]458        this->activate();
[5093]459      else
[5113]460        this->deactivate();
[5093]461    }
[5119]462    else if (event.type == SDLK_F1)
463      this->help();
464    else if (event.type == SDLK_F2)
465      this->debug();
[5093]466    else if (event.type == SDLK_TAB)
467      this->autoComplete();
468    else if (event.type == SDLK_BACKSPACE)
[5095]469    {
470      this->delayed = this->repeatDelay;
471      this->pressedKey = SDLK_BACKSPACE;
[5093]472      this->removeCharacters(1);
[5095]473    }
[5096]474    else if (event.type == SDLK_RETURN)
475      this->executeCommand();
[5097]476    else if (likely(event.type < 127))
[5095]477    {
478      this->delayed = this->repeatDelay;
479      this->pressedKey = event.type;
[5093]480      this->addCharacter(event.type);
[5095]481    }
[5093]482  }
[5095]483  else // if(!event.bPressed)
484  {
485    if (this->pressedKey == event.type)
[5113]486    {
[5095]487      this->pressedKey = SDLK_FIRST;
[5113]488      this->delayed = 0.0;
489    }
[5095]490  }
[5069]491}
492
[5068]493/**
494 * ticks the Shell for dt Seconds
495 * @param dt the elapsed time since the last tick();
496 */
[5095]497void Shell::tick(float dt)
498{
499  if (this->delayed > 0.0)
500    this->delayed -= dt;
501  else if (this->pressedKey != SDLK_FIRST )
502  {
[5097]503    this->delayed = this->repeatRate;
[5095]504    if (this->pressedKey == SDLK_BACKSPACE)
505      this->removeCharacters(1);
506    else if (pressedKey < 127)
507      this->addCharacter(this->pressedKey);
508  }
509}
[5068]510
511/**
512 * displays the Shell
513 */
514void Shell::draw() const
515{
[5099]516  glPushMatrix();
517  // transform for alignment.
518  // setting the Blending effects
519
520  glColor4f(0.0f, 0.0f, 0.8f, .4);
521  glEnable(GL_BLEND);
522  glDisable(GL_TEXTURE_2D);
523  glBlendFunc(GL_SRC_ALPHA, GL_ONE);
524
525//  glBindTexture(GL_TEXTURE_2D, this->texture);
526  glBegin(GL_QUADS);
527
528//  glTexCoord2f(this->texCoord.minU, this->texCoord.minV);
529  glVertex2f(this->getAbsCoor2D().x,   this->getAbsCoor2D().);
530
531//  glTexCoord2f(this->texCoord.maxU, this->texCoord.minV);
[5113]532  glVertex2f(GraphicsEngine::getInstance()->getResolutionX() - this->getAbsCoor2D().x, this->getAbsCoor2D().);
[5099]533
534//  glTexCoord2f(this->texCoord.maxU, this->texCoord.maxV);
[5113]535  glVertex2f(GraphicsEngine::getInstance()->getResolutionX() - this->getAbsCoor2D().x, this->getAbsCoor2D().y + this->shellHeight);
[5099]536
537//  glTexCoord2f(this->texCoord.minU, this->texCoord.maxV);
[5113]538  glVertex2f(this->getAbsCoor2D().x, this->getAbsCoor2D().y + this->shellHeight);
[5099]539
540  glEnd();
[5068]541}
542
543
544/**
545 * autocompletes the Shell's inputLine
546 * @returns true, if a result was found, false otherwise
[5100]547 *
548 * @todo implement it!!
[5068]549 */
550bool Shell::autoComplete()
551{
[5100]552  //PRINTF(3)("AutoCompletion not implemented yet\n");
553
554  char* completionLine = new char[strlen(inputLine)+1];
555  strcpy(completionLine, this->inputLine);
556
[5113]557  char* commandBegin = strrchr(completionLine, ' ');
[5100]558  if (commandBegin == NULL)
559    commandBegin = completionLine;
560  else
561  {
562    if(commandBegin >= completionLine + strlen(completionLine))
563      commandBegin = completionLine + strlen(completionLine);
564    else
565      commandBegin++;
566  }
567
[5113]568  char* objectStart;
569  if (objectStart = strstr(commandBegin, "::"))
570  {
571    char* classIdentity = new char[objectStart - commandBegin +1];
572    strncpy(classIdentity, commandBegin, objectStart - commandBegin);
573    classIdentity[objectStart - commandBegin] = '\0';
574    this->objectComplete(objectStart+2, ClassList::StringToID(classIdentity));
575    delete[] classIdentity;
576  }
577  else
578    this->classComplete(commandBegin);
[5102]579
[5113]580  delete[] completionLine;
581}
[5102]582
[5113]583/**
584 * autocompletes a className
585 * @param classBegin the Beginning of a String to autoComplete
586 * @return true on success, false otherwise
587 */
588bool Shell::classComplete(const char* classBegin)
589{
590  if (unlikely(classBegin == NULL))
591    return false;
592  const tList<const char>* clList = ClassList::getClassList();
593  if (clList != NULL)
594  {
595    const tList<const char>* classList = this->createCompleteList(clList, classBegin);
596    if (classList != NULL)
597      this->generalComplete(classList, classBegin, "%s::", "::");
598    else
599      return false;
600  }
601  else
602    return false;
603  return true;
[5105]604}
605
606/**
[5113]607 * autocompletes an ObjectName
608 * @param objectBegin the beginning string of a Object
609 * @param classID the ID of the Class to search for.
610 * @return true on success, false otherwise
611 */
612bool Shell::objectComplete(const char* objectBegin, long classID)
613{
614  printf("%s\n", objectBegin);
615
616  if (unlikely(objectBegin == NULL))
617    return false;
618  tList<BaseObject>* boList = ClassList::getList(classID);
619  if (boList != NULL)
620  {
621    printf("\n", boList->firstElement()->getName());
622    const tList<const char>* objectList = this->createCompleteList(boList, objectBegin);
623    if (objectList != NULL)
624      this->generalComplete(objectList, objectBegin, "%s");
625    else
626      return false;
627  }
628  else
629    return false;
630  return true;
631}
632
633bool Shell::functionComplete(const char* functionBegin)
634{
635}
636
637/**
638 * completes the inputline on grounds of an inputList
639 * @param stringList the List to parse through
640 * @param begin the String to search in the inputList, and to extend with it.
641 * @param displayAs how to display the found value to the user, printf-style, !!with only one %s!! ex.: "::%s::"
642 * @param addBack what should be added at the end of the completion
643 * @param addFront what should be added to the front of one finished completion
644 * @return true if ok, false otherwise
645 */
646bool Shell::generalComplete(const tList<const char>* stringList, const char* begin, const char* displayAs, const char* addBack, const char* addFront)
647{
648  if (stringList->getSize() == 0)
649    return false;
650
651  const char* addString = stringList->firstElement();
652  unsigned int addLength = 0;
653  unsigned int inputLenght = strlen(begin);
654
655  if (addString != NULL)
656    addLength = strlen(addString);
657  tIterator<const char>* charIterator = stringList->getIterator();
[5115]658  const char* charElem = charIterator->firstElement();
[5113]659  while (charElem != NULL)
660  {
661    PRINTF(0)(displayAs, charElem);
662    for (unsigned int i = inputLenght; i < addLength; i++)
663      if (addString[i] != charElem[i])
664    {
665      addLength = i;
666      break;
667    }
668    charElem = charIterator->nextElement();
669  }
670  delete charIterator;
671
672  if (addLength >= inputLenght)
673  {
674    char* adder = new char[addLength+1];
675    strncpy(adder, addString, addLength);
676    adder[addLength] = '\0';
677    this->removeCharacters(inputLenght);
678    this->addCharacters(adder);
679    if (addBack != NULL && stringList->getSize() == 1)
680      this->addCharacters("::");
681    delete[] adder;
682  }
683  return true;
684}
685
686/**
687 * searches for classes, which beginn with classNameBegin
688 * @param inputList the List to parse through
689 * @param classNameBegin the beginning string
690 * @return a NEW char-array with ClassNames. The LIST should be deleted afterwards,
691 * !! The strings MUST NOT be deleted !!
692 */
693const tList<const char>* Shell::createCompleteList(const tList<const char>* inputList, const char* classNameBegin)
694{
695  if (inputList == NULL || classNameBegin == NULL)
696    return NULL;
697  unsigned int searchLength = strlen(classNameBegin);
698  if (this->completionList != NULL)
699    delete this->completionList;
700  this->completionList = new tList<const char>;
701
702//  tList<const char>* classList = ClassList::getClassList();
703
704  tIterator<const char>* iterator = inputList->getIterator();
[5115]705  const char* enumString = iterator->firstElement();
[5113]706  while (enumString != NULL)
707  {
708    if (strlen(enumString)>searchLength+1 &&
709        !strncasecmp(enumString, classNameBegin, searchLength))
710    {
711      this->completionList->add(enumString);
712    }
713    enumString = iterator->nextElement();
714  }
715  delete iterator;
716
717  return this->completionList;
718}
719
720/**
721 * searches for classes, which beginn with classNameBegin
722 * @param inputList the List to parse through
723 * @param classNameBegin the beginning string
724 * @return a NEW char-array with ClassNames. The LIST should be deleted afterwards,
725 * !! The strings MUST NOT be deleted !!
726 */
727const tList<const char>* Shell::createCompleteList(const tList<BaseObject>* inputList, const char* classNameBegin)
728{
729  if (inputList == NULL || classNameBegin == NULL)
730    return NULL;
731  unsigned int searchLength = strlen(classNameBegin);
732  if (this->completionList != NULL)
733    delete this->completionList;
734  this->completionList = new tList<const char>;
735
736  tIterator<BaseObject>* iterator = inputList->getIterator();
[5115]737  BaseObject* enumBO = iterator->firstElement();
[5113]738  while (enumBO != NULL)
739  {
740    if (enumBO->getName() != NULL &&
741        strlen(enumBO->getName())>searchLength+1 &&
742        !strncasecmp(enumBO->getName(), classNameBegin, searchLength))
743    {
744      this->completionList->add(enumBO->getName());
745    }
746    enumBO = iterator->nextElement();
747  }
748  delete iterator;
749
750  return this->completionList;
751}
752
[5119]753void Shell::help() const
754{
755  PRINT(0)("Help for the most important Shell-commands\n");
756  PRINT(0)("F1 - HELP; F2 - DEBUG; ` - open/close shell\n");
757  PRINT(0)("input order:\n");
758  PRINT(0)("ClassName::objectName function [parameter1, [parameter2 ...]]  or\n");
759  PRINT(0)("Command [parameter]\n");
760}
761
[5120]762
763///////////////////////
764// HELPER FUNCTIONS  //
765///////////////////////
766Vector Shell::calculateLinePosition(unsigned int lineNumber)
767{
[5124]768  return Vector(5, (this->textSize + this->lineSpacing)*(this->bufferDisplaySize - lineNumber -1) + this->textSize, 0);
[5120]769}
770
771
772
[5113]773/**
[5068]774 * displays some nice output from the Shell
775 */
776void Shell::debug() const
777{
[5119]778  PRINT(3)("Debugging output to console (not this shell)\n");
779
[5096]780  if (this->pressedKey != SDLK_FIRST)
781    printf("%s::%f %f\n", SDLKToKeyname(this->pressedKey), this->delayed, this->repeatDelay);
[5119]782
783
784  char* tmpChar = this->bufferIterator->firstElement();
785  while(tmpChar != NULL)
786  {
787    printf(tmpChar);
788    tmpChar = this->bufferIterator->nextElement();
789  }
[5068]790}
Note: See TracBrowser for help on using the repository browser.