Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: better method to register Shell-Commands (now via the Factory-algorithm proposed)

BUT!! NOW ONLY SINGLETON IS SUPPORTED → fixing!!

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