Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7162 was 7162, checked in by bensch, 18 years ago

using vector instead of list in classList

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