Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: no more segfault in the Shell

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