Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: commands now get unregistered when leaving orxonox

File size: 8.5 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
30ShellCommandBase::ShellCommandBase(const char* commandName, const char* className, unsigned int paramCount, ...)
31{
32  this->setClassID(CL_SHELL_COMMAND, "ShellCommand");
33  this->setName(commandName);
34  this->description = NULL;
35
36//  this->classID = classID;
37  this->className = className; //ClassList::IDToString(classID);
38
39  // handling parameters, and storing them:
40  if (paramCount > FUNCTOR_MAX_ARGUMENTS)
41    paramCount = FUNCTOR_MAX_ARGUMENTS;
42  this->paramCount = paramCount;
43  this->parameters = new unsigned int[paramCount];
44
45  va_list parameterList;
46  va_start(parameterList, paramCount);
47
48  for (unsigned int i = 0; i < paramCount; i++)
49  {
50    this->parameters[i] = va_arg(parameterList, int);
51
52    switch (this->parameters[i])
53    {
54      case ParameterBool:
55        this->defaultBools[i] = va_arg(parameterList, int);
56        break;
57      case ParameterChar:
58        this->defaultStrings[i] = new char[2];
59        sprintf(this->defaultStrings[0], "%c",  va_arg(parameterList, int));
60        break;
61      case ParameterString:
62        this->defaultStrings[i] = va_arg(parameterList, char*);
63        break;
64      case ParameterInt:
65        this->defaultInts[i] = va_arg(parameterList, int);
66        break;
67      case ParameterUInt:
68        this->defaultInts[i] = va_arg(parameterList, unsigned int);
69        break;
70      case ParameterFloat:
71        this->defaultFloats[i] = va_arg(parameterList, double);
72        break;
73      case ParameterLong:
74        this->defaultInts[i] = va_arg(parameterList, long);
75        break;
76      default:
77        break;
78    }
79  }
80
81  // adding this ShellCommand to the list of known Commands
82  ShellCommandBase::commandList->add(this);
83}
84
85ShellCommandBase::~ShellCommandBase()
86{
87  delete[] this->parameters;
88}
89
90void ShellCommandBase::unregisterAllCommands()
91{
92  tIterator<ShellCommandBase>* iterator = ShellCommandBase::commandList->getIterator();
93  ShellCommandBase* elem = iterator->firstElement();
94  while(elem != NULL)
95  {
96    delete elem;
97
98    elem = iterator->nextElement();
99  }
100  delete iterator;
101
102  delete ShellCommandBase::commandList;
103  ShellCommandBase::commandList = NULL;
104}
105
106
107void unregisterCommand(const char* commandName, const char* className)
108{
109  PRINTF(1)("IMPLEMENT THIS\n");
110}
111
112tList<ShellCommandBase>* ShellCommandBase::commandList = NULL;
113
114
115
116bool ShellCommandBase::isRegistered(const char* commandName, const char* className, unsigned int paramCount, ...)
117{
118  va_list parameterList;
119  va_start(parameterList, paramCount);
120
121  if (ShellCommandBase::commandList == NULL)
122  {
123    ShellCommandBase::commandList = new tList<ShellCommandBase>;
124    ShellCommand<ShellCommandBase>::registerCommand("debug", "ShellCommand", &ShellCommandBase::debugDyn);
125    return false;
126  }
127
128  tIterator<ShellCommandBase>* iterator = ShellCommandBase::commandList->getIterator();
129  ShellCommandBase* elem = iterator->firstElement();
130  while(elem != NULL)
131  {
132    if (!strcmp(className, elem->className) && !strcmp(commandName, elem->getName()))
133    {
134      PRINTF(2)("Command already registered\n");
135      delete iterator;
136      return true;
137    }
138    elem = iterator->nextElement();
139  }
140  delete iterator;
141  return false;
142}
143
144
145/**
146 * executes commands
147 * @param executionString the string containing the following input
148 * ClassName [ObjectName] functionName [parameter1[,parameter2[,...]]]
149 * @return true on success, false otherwise.
150 */
151bool ShellCommandBase::execute(const char* executionString)
152{
153  if (ShellCommandBase::commandList == NULL)
154    return false;
155
156  tIterator<ShellCommandBase>* iterator = ShellCommandBase::commandList->getIterator();
157  ShellCommandBase* elem = iterator->firstElement();
158  while(elem != NULL)
159  {
160    printf("%s::%s\n", elem->className, elem->getName());
161    if (!strncasecmp (executionString, elem->className, strlen(elem->className)) &&
162         (*(executionString+strlen(elem->className)) == ' ' ||
163          *(executionString+strlen(elem->className)) == ':' ))
164    {
165      const char* commandBegin = executionString + strlen(elem->className);
166
167      PRINTF(4)("Class %s matches\n", elem->className);
168      BaseObject* objectPointer = NULL;
169      if (ClassList::StringToID(elem->className) & CL_MASK_SINGLETON == CL_MASK_SINGLETON)
170      {
171        while(*commandBegin == ' ')
172          commandBegin++;
173        if (strncmp (commandBegin, elem->getName(), strlen(elem->getName())) ||
174            *(commandBegin + strlen(elem->getName())) != ' ' &&
175            *(commandBegin + strlen(elem->getName())) != '\0')
176        {
177          elem = iterator->nextElement();
178          continue;
179        }
180        PRINTF(4)("Command %s matches\n", elem->getName());
181        // getting singleton-reference
182        tList<BaseObject>* list =  ClassList::getList(elem->className);
183        if (list != NULL)
184          objectPointer = list->firstElement();
185      }
186      else
187      {
188        // checking for the Object
189        while(*commandBegin == ' ')
190          commandBegin++;
191        tList<BaseObject>* list = ClassList::getList(elem->className);
192        if (list == NULL)
193          break;
194        tIterator<BaseObject>* iterBO = list->getIterator();
195        BaseObject* enumBO = iterBO->firstElement();
196        while(enumBO != NULL)
197        {
198          if(!strncmp(commandBegin, enumBO->getName(), strlen(enumBO->getName())))
199          {
200            PRINTF(4)("Object %s matches\n", enumBO->getName());
201            objectPointer = enumBO;
202            break;
203          }
204          enumBO = iterBO->nextElement();
205        }
206        delete iterBO;
207
208        // break on no object Found. We cannot operate on Classes, but on Objects
209        if (objectPointer == NULL)
210          break;
211        commandBegin = commandBegin + strlen(objectPointer->getName());
212        while(*commandBegin == ' ')
213          commandBegin++;
214        // checking for the requested function.
215        if (strncmp (commandBegin, elem->getName(), strlen(elem->getName())))
216        {
217          elem = iterator->nextElement();
218          continue;
219        }
220        PRINTF(4)("Function '%s' found\n", commandBegin);
221      }
222      const char* paramBegin = strchr(commandBegin, ' ');
223      if (paramBegin == NULL)
224        paramBegin = commandBegin + strlen(elem->getName());
225      while (*paramBegin == ' ')
226        paramBegin++;
227
228      PRINTF(3)("Parameters to Pass: %s\n", paramBegin);
229      if (objectPointer != NULL && paramBegin != NULL)
230      {
231        elem->executeCommand(objectPointer, paramBegin);
232        delete iterator;
233        return true;
234      }
235    }
236    elem = iterator->nextElement();
237  }
238  delete iterator;
239  return true;
240}
241
242
243ShellCommandBase* ShellCommandBase::describe(const char* description)
244{
245  if (this == NULL)
246    return NULL;
247 else
248 {
249   this->description = description;
250   return this;
251 }
252}
253
254void ShellCommandBase::debugDyn()
255{
256  this->debug();
257}
258
259void ShellCommandBase::debug()
260{
261  if (ShellCommandBase::commandList == NULL)
262  {
263    PRINT(0)("No Command registered so far\n");
264    return;
265  }
266
267  tIterator<ShellCommandBase>* iterator = ShellCommandBase::commandList->getIterator();
268  ShellCommandBase* elem = iterator->firstElement();
269  while(elem != NULL)
270  {
271    PRINT(0)("Class %s registered command %s with %d parameters: ", elem->className, elem->getName(), elem->paramCount);
272    for (unsigned int i = 0; i< elem->paramCount; i++)
273      printf("%s ", ShellCommandBase::paramToString(elem->parameters[i]));
274    if (elem->description != NULL)
275      printf("- %s", elem->description);
276    printf("\n");
277
278    elem = iterator->nextElement();
279  }
280  delete iterator;
281}
282
283
284
285const char* ShellCommandBase::paramToString(long parameter)
286{
287  switch (parameter)
288  {
289    case ParameterBool:
290      return "BOOL";
291      break;
292    case ParameterChar:
293      return "CHAR";
294      break;
295    case ParameterString:
296      return "STRING";
297      break;
298    case ParameterInt:
299      return "INT";
300      break;
301    case ParameterUInt:
302      return "UINT";
303      break;
304    case ParameterFloat:
305      return "FLOAT";
306      break;
307    case ParameterLong:
308      return "LONG";
309      break;
310    default:
311      return "NULL";
312      break;
313  }
314}
Note: See TracBrowser for help on using the repository browser.