Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/lang/class_list.cc @ 5329

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

orxonox/trunk: executing static commands work

File size: 9.7 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 "class_list.h"
19#include "base_object.h"
20
21#include "list.h"
22#include "compiler.h"
23#include "debug.h"
24#include <string.h>
25#include <math.h>
26#include "shell_command.h"
27
28using namespace std;
29
30SHELL_COMMAND_STATIC(debug, ClassList, ClassList::debug);
31
32/**
33 *  Creates a new ClassList
34*/
35ClassList::ClassList(const long& classID, const char* className)
36{
37  this->next = NULL;
38  this->className = className;
39  this->classID = classID;
40  this->objectList = new tList<BaseObject>;
41
42  ++ClassList::classCount;
43}
44
45/**
46 *  standard deconstructor
47*/
48ClassList::~ClassList ()
49{
50  delete this->objectList;
51  if(ClassList::classList != NULL)
52  {
53    delete ClassList::classList;
54    ClassList::classList = NULL;
55  }
56  --ClassList::classCount;
57}
58
59//! the first class that is registered
60ClassList*  ClassList::first = NULL;
61
62//! the Count of classes
63unsigned int ClassList::classCount = 0;
64
65//! a List of all strings of all classes, that have registered so far.
66tList<const char>* ClassList::classList = NULL;
67
68/**
69 * Adds a new Object to the ClassList (and if necessary a new Class)
70 * @param objectPointer Pointer to the Object at hand
71 * @param classID ID of the Given ObjectType \see ClassID
72 * @param className name of the Class to add
73 */
74void ClassList::addToClassList(BaseObject* objectPointer, const long& classID, const char* className)
75{
76  ClassList* regClass;
77  PRINTF(5)("subscribe a %s\n", className );
78
79  if(ClassList::first == NULL)
80    ClassList::first = regClass = new ClassList(classID, className);
81  else
82  {
83    ClassList* tmp = ClassList::first;
84    while (likely(tmp != NULL))
85    {
86      if (tmp->classID == classID)
87      {
88        regClass = tmp;
89        break;
90      }
91
92      if (unlikely(tmp->next == NULL))
93      {
94        tmp->next = regClass = new ClassList(classID, className);
95        break;
96      }
97      tmp = tmp->next;
98    }
99  }
100  regClass->objectList->add(objectPointer);
101}
102
103/**
104 * removes an Object from a the ClassList
105 * @param objectPointer the Object to delete from the List
106 */
107void ClassList::removeFromClassList(BaseObject* objectPointer)
108{
109  ClassList* tmp = ClassList::first;
110  while (likely(tmp != NULL))
111  {
112    if (objectPointer->isA(tmp->classID))
113    {
114      tmp->objectList->remove(objectPointer);
115    }
116    tmp = tmp->next;
117  }
118}
119
120/**
121 * grabs the names of all Classes, and injects it into a List of const chars
122 * @return the generated List
123 *
124 * This function first looks, if the List has been changed (by the ListSize)
125 * befor it changes anything.
126 */
127const tList<const char>* ClassList::getClassList()
128{
129  if (unlikely(ClassList::classList != NULL && ClassList::classList->getSize() != ClassList::classCount))
130  {
131    delete ClassList::classList;
132    ClassList::classList = NULL;
133  }
134  if (unlikely(ClassList::classList == NULL))
135    ClassList::classList = new tList<const char>;
136
137  if(likely(ClassList::first != NULL))
138  {
139    ClassList* tmpCL = ClassList::first;
140    while (likely(tmpCL != NULL))
141    {
142      ClassList::classList->add(tmpCL->className);
143      tmpCL = tmpCL->next;
144    }
145  }
146  return ClassList::classList;
147}
148
149/**
150 * searches for classID and returns the list of Entities
151 * @param classID the ID of the class to get the list from
152 * @return the List accessed by classID, or NULL if not found
153 */
154tList<BaseObject>* ClassList::getList(long classID)
155{
156  if(unlikely(ClassList::first == NULL))
157    return NULL;
158  else
159  {
160    ClassList* tmpCL = ClassList::first;
161    while (likely(tmpCL != NULL))
162    {
163      if (unlikely(tmpCL->classID == classID))
164        return tmpCL->objectList;
165      tmpCL = tmpCL->next;
166    }
167  }
168  return NULL;
169}
170
171/**
172 * searches for className and returns the list of Entities
173 * @param className the name of the class to get the list from
174 * @return the List accessed by classID, or NULL if not found
175 */tList<BaseObject>* ClassList::getList(const char* className)
176{
177  if(unlikely(ClassList::first == NULL))
178    return NULL;
179  else
180  {
181    ClassList* tmpCL = ClassList::first;
182    while (likely(tmpCL != NULL))
183    {
184      if (unlikely(!strcmp(tmpCL->className, className)))
185        return tmpCL->objectList;
186      tmpCL = tmpCL->next;
187    }
188  }
189  return NULL;
190}
191
192/**
193 * checks if the BaseObject* object exists.
194 * @param name the name of the BaseObject to look for
195 * @param classID if not CL_NULL it will only search through a specific type of Objects. Otherwise it will be searched everywhere.
196 * @return true, if the Object Exists in the specified ClassID, false otherwise
197 * @todo: speed this up!!
198 */
199BaseObject* ClassList::getObject(const char* name, long classID)
200{
201  if(unlikely(ClassList::first == NULL) || name == NULL)
202    return NULL;
203  else
204  {
205    ClassList* tmp = ClassList::first;
206    while (likely(tmp != NULL))
207    {
208      if (tmp->classID == classID || classID == CL_NULL)
209      {
210        tIterator<BaseObject>* iterator = tmp->objectList->getIterator();
211        BaseObject* enumBO = iterator->firstElement();
212        const char* tmpName;
213        while (enumBO != NULL)
214        {
215          tmpName = enumBO->getName();
216          if (tmpName && !strcmp(tmpName, name))
217          {
218            delete iterator;
219            return enumBO;
220          }
221          enumBO = iterator->nextElement();
222        }
223        delete iterator;
224        break;
225      }
226      tmp = tmp->next;
227    }
228  }
229  return NULL;
230}
231
232
233/**
234 * checks if the BaseObject* object exists.
235 * @param object the Pointer to a BaseObject to check if it exists
236 * @param classID if not CL_NULL it will only search through a specific type of Objects. Otherwise it will be searched everywhere.
237 * @return true, if the Object Exists in the specified ClassID, false otherwise
238 * @todo: speed this up!!
239 */
240bool ClassList::exists(const BaseObject* object, long classID)
241{
242  if(unlikely(ClassList::first == NULL))
243    return false;
244  else
245  {
246    ClassList* tmp = ClassList::first;
247    while (likely(tmp != NULL))
248    {
249      if (tmp->classID == classID || classID == CL_NULL)
250      {
251        tIterator<BaseObject>* iterator = tmp->objectList->getIterator();
252        BaseObject* enumBO = iterator->firstElement();
253        while (enumBO != NULL)
254        {
255          if (enumBO == object)
256          {
257            delete iterator;
258            return true;
259          }
260          enumBO = iterator->nextElement();
261        }
262        delete iterator;
263        break;
264      }
265      tmp = tmp->next;
266    }
267  }
268  return false;
269}
270
271/**
272 * prints out a string of all the types this Object matches
273 * @param object a Pointer to the object to analyze
274 */
275void ClassList::whatIs(const BaseObject* object)
276{
277  ClassList* tmp = ClassList::first;
278  while (likely(tmp != NULL))
279  {
280    if (object->isA(tmp->classID))
281    {
282      PRINT(0)("=%s=-", tmp->className);
283    }
284    tmp = tmp->next;
285  }
286}
287
288/**
289 * converts a ClassID into a string
290 * @param classID the ClassID to search for
291 * @return a String containing the name of the Class, NULL if the Class was not found
292 */
293const char* ClassList::IDToString(long classID)
294{
295  if(likely(ClassList::first != NULL))
296  {
297    ClassList* tmpCL = ClassList::first;
298    while (likely(tmpCL != NULL))
299    {
300      if (tmpCL->classID == classID)
301        return tmpCL->className;
302      tmpCL = tmpCL->next;
303    }
304  }
305  return NULL;
306}
307
308/**
309 * converts a String into a ClassID
310 * @param className the name of the class to search for
311 * @return the ClassID. CL_NULL, if the class was not found.
312 */
313long ClassList::StringToID(const char* className)
314{
315  if(likely(ClassList::first != NULL))
316  {
317    ClassList* tmpCL = ClassList::first;
318    while (likely(tmpCL != NULL))
319    {
320      if (!strcasecmp(tmpCL->className, className))
321        return tmpCL->classID;
322      tmpCL = tmpCL->next;
323    }
324  }
325  return CL_NULL;
326}
327
328
329
330/**
331 * Print out some very nice debug information
332 * @param debugLevel the level of verbosity
333 * @param classID the class that should be displayed (if CL_NULL (default) all classes will be displayed)
334 */
335void ClassList::debug(unsigned int debugLevel, long classID)
336{
337  if (debugLevel > 3)
338    debugLevel = 3;
339  PRINT(0)("==========================\n");
340  PRINT(0)("=  CLASS_LIST (level %d)  =\n", debugLevel);
341  PRINT(0)("==========================\n");
342  PRINT(0)("| knows %d Classes\n|\n", ClassList::classCount);
343  ClassList* tmp = ClassList::first;
344  char niceString[100];
345  unsigned int lenCount = 0;
346
347  while (likely(tmp != NULL))
348  {
349    if ((debugLevel >= 1 || tmp->objectList->getSize() > 0 ) &&
350         (classID == CL_NULL || unlikely (classID == tmp->classID)))
351    {
352      lenCount = 1;
353      while (pow(10,lenCount) <= tmp->objectList->getSize())
354        ++lenCount;
355      for (int i=0; i < 30-strlen(tmp->className) - lenCount; i++)
356        (niceString[i]) = ' ';
357      niceString[30-strlen(tmp->className) - lenCount] = '\0';
358
359      PRINT(0)("| CLASS %s:%s %d\n", tmp->className, niceString, tmp->objectList->getSize());
360
361      if (debugLevel >=2 && tmp->objectList->getSize() > 0)
362      {
363        PRINT(0)("|  Listing Instances:\n");
364        tIterator<BaseObject>* iterator = tmp->objectList->getIterator();
365        BaseObject* enumBO = iterator->firstElement();
366        while (enumBO)
367        {
368          PRINT(0)("|   (class %s): NAME(%s)->%p ", enumBO->getClassName(), enumBO->getName(), enumBO);
369          if (debugLevel == 3)
370            ClassList::whatIs(enumBO);
371          PRINT(0)("\n");
372          enumBO = iterator->nextElement();
373        }
374        delete iterator;
375      }
376    }
377    tmp = tmp->next;
378  }
379  PRINT(0)("=======================CL=\n");
380}
Note: See TracBrowser for help on using the repository browser.