Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: color adaption in the shell
isA also with String (slow)

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