Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: some cleanup before the new tag

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