Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: added new Class ShellBuffer, that only handles the main shell's buffer

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