Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: registration of ShellCommands now via the ShellCommandClass… still a lot of work has to be done.

File size: 12.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_command.h"
19
20#include "list.h"
21#include "debug.h"
22#include "class_list.h"
23
24#include "key_names.h"
25#include <stdarg.h>
26#include <stdio.h>
27
28using namespace std;
29
30/**
31 * creates a new ShellCommandClass
32 * @param className the Name of the command-class to create
33 */
34ShellCommandClass::ShellCommandClass(const char* className)
35{
36  this->className = className;
37  this->classID = CL_NULL;
38  this->commandList = new tList<ShellCommandBase>;
39
40  ShellCommandClass::commandClassList->add(this);
41}
42
43/**
44 * destructs the shellCommandClass again
45 */
46ShellCommandClass::~ShellCommandClass()
47{
48  tIterator<ShellCommandBase>* iterator = this->commandList->getIterator();
49  ShellCommandBase* elem = iterator->firstElement();
50  while(elem != NULL)
51  {
52    delete elem;
53    elem = iterator->nextElement();
54  }
55  delete iterator;
56  delete this->commandList;
57}
58
59const ShellCommandClass* ShellCommandClass::isRegistered(const char* className)
60{
61  if (ShellCommandClass::commandClassList == NULL)
62    initCommandClassList();
63
64  tIterator<ShellCommandClass>* iterator = ShellCommandClass::commandClassList->getIterator();
65  ShellCommandClass* elem = iterator->firstElement();
66  while(elem != NULL)
67  {
68    if (!strcmp(className, elem->className))
69    {
70      delete iterator;
71      return elem;
72    }
73    elem = iterator->nextElement();
74  }
75  delete iterator;
76  return NULL;
77}
78
79ShellCommandClass* ShellCommandClass::getCommandClass(const char* className)
80{
81  if (ShellCommandClass::commandClassList == NULL)
82    initCommandClassList();
83
84  tIterator<ShellCommandClass>* iterator = ShellCommandClass::commandClassList->getIterator();
85  ShellCommandClass* elem = iterator->firstElement();
86  while(elem != NULL)
87  {
88    if (!strcmp(className, elem->className))
89    {
90      delete iterator;
91      return elem;
92    }
93    elem = iterator->nextElement();
94  }
95  delete iterator;
96  return new ShellCommandClass(className);
97}
98
99
100void ShellCommandClass::initCommandClassList()
101{
102  if (ShellCommandClass::commandClassList == NULL)
103  {
104    ShellCommandClass::commandClassList = new tList<ShellCommandClass>;
105    ShellCommand<ShellCommandBase>::registerCommand("debug", "ShellCommand", &ShellCommandBase::debugDyn);
106  }
107}
108
109tList<ShellCommandClass>* ShellCommandClass::commandClassList = NULL;
110
111/**
112 * constructs and registers a new Command
113 * @param commandName the name of the Command
114 * @param className the name of the class to apply this command to
115 * @param paramCount the count of parameters this command takes
116 * @return self
117 */
118ShellCommandBase::ShellCommandBase(const char* commandName, const char* className, unsigned int paramCount, ...)
119{
120  this->setClassID(CL_SHELL_COMMAND, "ShellCommand");
121  this->setName(commandName);
122  this->description = NULL;
123
124//  this->classID = classID;
125  ShellCommandClass::getCommandClass(className)->commandList->add(this); //ClassList::IDToString(classID);
126
127  // handling parameters, and storing them:
128  if (paramCount > FUNCTOR_MAX_ARGUMENTS)
129    paramCount = FUNCTOR_MAX_ARGUMENTS;
130  this->paramCount = paramCount;
131  this->parameters = new unsigned int[paramCount];
132
133  va_list parameterList;
134  va_start(parameterList, paramCount);
135
136  for (unsigned int i = 0; i < paramCount; i++)
137  {
138    this->parameters[i] = va_arg(parameterList, int);
139
140    switch (this->parameters[i])
141    {
142      case ParameterBool:
143        this->defaultBools[i] = va_arg(parameterList, int);
144        break;
145      case ParameterChar:
146        this->defaultStrings[i] = new char[2];
147        sprintf(this->defaultStrings[0], "%c",  va_arg(parameterList, int));
148        break;
149      case ParameterString:
150        this->defaultStrings[i] = va_arg(parameterList, char*);
151        break;
152      case ParameterInt:
153        this->defaultInts[i] = va_arg(parameterList, int);
154        break;
155      case ParameterUInt:
156        this->defaultInts[i] = va_arg(parameterList, unsigned int);
157        break;
158      case ParameterFloat:
159        this->defaultFloats[i] = va_arg(parameterList, double);
160        break;
161      case ParameterLong:
162        this->defaultInts[i] = va_arg(parameterList, long);
163        break;
164      default:
165        break;
166    }
167  }
168}
169
170/**
171 * deconstructs a ShellCommand
172 * @return
173 */
174ShellCommandBase::~ShellCommandBase()
175{
176  delete[] this->parameters;
177}
178
179/**
180 * unregisters all Commands that exist
181 */
182void ShellCommandBase::unregisterAllCommands()
183{
184//   tIterator<ShellCommandBase>* iterator = ShellCommandBase::commandList->getIterator();
185//   ShellCommandBase* elem = iterator->firstElement();
186//   while(elem != NULL)
187//   {
188//     delete elem;
189//
190//     elem = iterator->nextElement();
191//   }
192//   delete iterator;
193//
194//   delete ShellCommandBase::commandList;
195//   ShellCommandBase::commandList = NULL;
196}
197
198/**
199 * unregister an existing commandName
200 * @param className the name of the Class the command belongs to.
201 * @param commandName the name of the command itself
202 *
203 * @todo implement
204 */
205void ShellCommandBase::unregisterCommand(const char* commandName, const char* className)
206{
207  PRINTF(1)("IMPLEMENT THIS\n");
208}
209
210
211
212/**
213 * checks if a command has already been registered.
214 * @param commandName the name of the Command
215 * @param className the name of the Class the command should apply to.
216 * @param paramCount how many arguments the Command takes
217 * @returns true, if the command is registered/false otherwise
218 *
219 * This is used internally, to see, if we have multiple command subscriptions.
220 * This is checked in the registerCommand-function.
221 */
222bool ShellCommandBase::isRegistered(const char* commandName, const char* className, unsigned int paramCount, ...)
223{
224  if (ShellCommandClass::commandClassList == NULL)
225  {
226    ShellCommandClass::initCommandClassList();
227    return false;
228  }
229
230  const ShellCommandClass* checkClass = ShellCommandClass::isRegistered(className);
231  if (checkClass != NULL)
232  {
233    tIterator<ShellCommandBase>* iterator = checkClass->commandList->getIterator();
234    ShellCommandBase* elem = iterator->firstElement();
235    while(elem != NULL)
236   {
237     if (!strcmp(commandName, elem->getName()))
238     {
239       PRINTF(2)("Command already registered\n");
240       delete iterator;
241       return true;
242      }
243     elem = iterator->nextElement();
244   }
245   delete iterator;
246   return false;
247  }
248  else
249    return false;
250}
251
252
253/**
254 * executes commands
255 * @param executionString the string containing the following input
256 * ClassName [ObjectName] functionName [parameter1[,parameter2[,...]]]
257 * @return true on success, false otherwise.
258 */
259bool ShellCommandBase::execute(const char* executionString)
260{
261//   if (ShellCommandBase::commandList == NULL)
262//     return false;
263//
264//   tIterator<ShellCommandBase>* iterator = ShellCommandBase::commandList->getIterator();
265//   ShellCommandBase* elem = iterator->firstElement();
266//   while(elem != NULL)
267//   {
268//     printf("%s::%s\n", elem->className, elem->getName());
269//     if (!strncasecmp (executionString, elem->className, strlen(elem->className)) &&
270//          (*(executionString+strlen(elem->className)) == ' ' ||
271//           *(executionString+strlen(elem->className)) == ':' ))
272//     {
273//       const char* commandBegin = executionString + strlen(elem->className);
274//
275//       PRINTF(4)("Class %s matches\n", elem->className);
276//       BaseObject* objectPointer = NULL;
277//       if (ClassList::StringToID(elem->className) & CL_MASK_SINGLETON == CL_MASK_SINGLETON)
278//       {
279//         while(*commandBegin == ' ')
280//           commandBegin++;
281//         if (strncmp (commandBegin, elem->getName(), strlen(elem->getName())) ||
282//             *(commandBegin + strlen(elem->getName())) != ' ' &&
283//             *(commandBegin + strlen(elem->getName())) != '\0')
284//         {
285//           elem = iterator->nextElement();
286//           continue;
287//         }
288//         PRINTF(4)("Command %s matches\n", elem->getName());
289//         // getting singleton-reference
290//         tList<BaseObject>* list =  ClassList::getList(elem->className);
291//         if (list != NULL)
292//           objectPointer = list->firstElement();
293//       }
294//       else
295//       {
296//         // checking for the Object
297//         while(*commandBegin == ' ')
298//           commandBegin++;
299//         tList<BaseObject>* list = ClassList::getList(elem->className);
300//         if (list == NULL)
301//           break;
302//         tIterator<BaseObject>* iterBO = list->getIterator();
303//         BaseObject* enumBO = iterBO->firstElement();
304//         while(enumBO != NULL)
305//         {
306//           if(!strncmp(commandBegin, enumBO->getName(), strlen(enumBO->getName())))
307//           {
308//             PRINTF(4)("Object %s matches\n", enumBO->getName());
309//             objectPointer = enumBO;
310//             break;
311//           }
312//           enumBO = iterBO->nextElement();
313//         }
314//         delete iterBO;
315//
316//         // break on no object Found. We cannot operate on Classes, but on Objects
317//         if (objectPointer == NULL)
318//           break;
319//         commandBegin = commandBegin + strlen(objectPointer->getName());
320//         while(*commandBegin == ' ')
321//           commandBegin++;
322//         // checking for the requested function.
323//         if (strncmp (commandBegin, elem->getName(), strlen(elem->getName())))
324//         {
325//           elem = iterator->nextElement();
326//           continue;
327//         }
328//         PRINTF(4)("Function '%s' found\n", commandBegin);
329//       }
330//       const char* paramBegin = strchr(commandBegin, ' ');
331//       if (paramBegin == NULL)
332//         paramBegin = commandBegin + strlen(elem->getName());
333//       while (*paramBegin == ' ')
334//         paramBegin++;
335//
336//       PRINTF(3)("Parameters to Pass: %s\n", paramBegin);
337//       if (objectPointer != NULL && paramBegin != NULL)
338//       {
339//         elem->executeCommand(objectPointer, paramBegin);
340//         delete iterator;
341//         return true;
342//       }
343//     }
344//     elem = iterator->nextElement();
345//   }
346//   delete iterator;
347//   return true;
348}
349
350/**
351 * lets a command be described
352 * @param description the description of the Given command
353 */
354ShellCommandBase* ShellCommandBase::describe(const char* description)
355{
356  if (this == NULL)
357    return NULL;
358 else
359 {
360   this->description = description;
361   return this;
362 }
363}
364
365/**
366 * see ShellCommandBase::debug()
367 */
368void ShellCommandBase::debugDyn()
369{
370  this->debug();
371}
372
373/**
374 * prints out nice information about the Shells Commands
375 */
376void ShellCommandBase::debug()
377{
378  if (ShellCommandClass::commandClassList == NULL)
379  {
380    PRINT(0)("No Command registered so far\n");
381    return;
382  }
383
384  tIterator<ShellCommandClass>* iteratorCL = ShellCommandClass::commandClassList->getIterator();
385  ShellCommandClass* elemCL = iteratorCL->firstElement();
386  while(elemCL != NULL)
387  {
388    tIterator<ShellCommandBase>* iterator = elemCL->commandList->getIterator();
389    const ShellCommandBase* elem = iterator->firstElement();
390    {
391      PRINT(0)("Class:'%s' registered: \n", elemCL->className);
392      PRINT(0)("  command:'%s':params:%d: ", elem->getName(), elem->paramCount);
393      for (unsigned int i = 0; i< elem->paramCount; i++)
394       printf("%s ", ShellCommandBase::paramToString(elem->parameters[i]));
395      if (elem->description != NULL)
396       printf("- %s", elem->description);
397      printf("\n");
398
399      elem = iterator->nextElement();
400    }
401    delete iterator;
402    elemCL = iteratorCL->nextElement();
403  }
404  delete iteratorCL;
405}
406
407/**
408 * converts a Parameter to a String
409 * @param parameter the Parameter we have.
410 * @returns the Name of the Parameter at Hand
411 */
412const char* ShellCommandBase::paramToString(long parameter)
413{
414  switch (parameter)
415  {
416    case ParameterBool:
417      return "BOOL";
418      break;
419    case ParameterChar:
420      return "CHAR";
421      break;
422    case ParameterString:
423      return "STRING";
424      break;
425    case ParameterInt:
426      return "INT";
427      break;
428    case ParameterUInt:
429      return "UINT";
430      break;
431    case ParameterFloat:
432      return "FLOAT";
433      break;
434    case ParameterLong:
435      return "LONG";
436      break;
437    default:
438      return "NULL";
439      break;
440  }
441}
Note: See TracBrowser for help on using the repository browser.