Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: all types work as expected

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