Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: ClassList is now in std::list style
ShellCommand is now in std::list style

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