Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: top-down shell, as proposed by patrick. This makes sense, becuase the general people knows only shells comming top down

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