Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/network/src/lib/lang/class_list.cc @ 5619

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

orxonox/trunk: ShellCommand availiable again, in orxonox-mode, but unavailiable in subproject Network

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