Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: better and faster BaseObject/ClassList

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