Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/util/object_manager.h @ 4933

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

orxonox/trunk: more elaborate FastFactory, that should work…
now i have to test it… this will generate segfaults for sure :/

File size: 6.5 KB
Line 
1/*!
2    \file object_manager.h
3  *  this manager will ceep track of the objects  in the world
4
5    This is specially designed to:
6    - Give an interface to the world data
7    - separate the world data from the world build,update,draw process
8    - recycle deleted objects: specific for Projectils since there is a lot of world entity creation/deletion (and this needs a lot of time)
9    - control the garbage collector
10
11    TO ADD SUPPORT FOR A CLASS do the following steps:
12    1. include the hader file : #include "class_id.h"
13    2. add the class to the type enum classID {}; in class_id.h
14    3. define a function void mCache( ClassName ) in class ObjectManager
15
16*/
17
18
19#ifndef _OBJECT_MANAGER_H
20#define _OBJECT_MANAGER_H
21
22#include "base_object.h"
23#include "class_id.h"
24
25template<class T> class tList;
26class GarbageCollector;
27
28
29/**
30 * Creates a FastFactory to a Loadable FastFactory.
31 */
32//#define CREATE_FAST_FACTORY(CLASS_NAME, CLASS_ID) \
33    //tFastFactory<CLASS_NAME>* global_##CLASS_NAME##_FastFactory = new tFastFactory<CLASS_NAME>(#CLASS_NAME, CLASS_ID)
34
35//! A struct, that holds Lists of Objects of a certain type.
36template <class T> struct FastObjectMember
37{
38  T*                      objectPointer;
39
40  FastObjectMember<T>*    next;
41};
42
43//! The FastFactory is a fast loadable object creator, and Dynamic List of dead object handler.
44/**
45 * FastFactory is needed to glue all the tFastFactory<T>'s together.
46 * Furthermore one can retrieve the corresponding tFastFactory over
47 * tFastFactory<T>* = FastFacroty::getFastFactory(ID);
48 */
49class FastFactory : public BaseObject {
50
51  public:
52    virtual ~FastFactory ();
53
54    // functions to push and pop elements of this class
55    BaseObject* resurect(ClassID classID);
56    void kill(ClassID classID, BaseObject* object);
57
58    // retrival functions for fast Ineraction
59    //FastFactory* getFastFactory(ClassID classID);
60
61    /** @returns the first FastFactory */
62    static FastFactory* getFirst() { return FastFactory::first; };
63
64  protected:
65    /** sets the Next factory in the list @param nextFactory the next factory */
66    inline void setNext( FastFactory* nextFastFactory) { this->next = nextFastFactory; };
67    /** @returns the next FastFactory */
68    FastFactory* getNext() const { return this->next; };
69
70    virtual BaseObject* fabricate(ClassID classID) = NULL;
71
72  private:
73    FastFactory (ClassID classID, const char* fastFactoryName = NULL);
74    static void registerFastFactory(FastFactory* fastFactory);
75    static FastFactory* searchFastFactory(ClassID classID, const char* fastFactoryName = NULL);
76
77  protected:
78    ClassID               storedClassID;        //!< The classID of the specified class.
79    unsigned int          storedDeadObjects;    //!< How many dead objects are stored in this class
80
81  private:
82    static FastFactory*   first;                //!< A pointer to the first FastFactory.
83
84    FastFactory*          next;                 //!< pointer to the next FastFactory.
85};
86
87/**
88 *  a FastFactory that is able to load any kind of Object from a ClassID
89 * (this is a Functor)
90 */
91template<class T> class tFastFactory : public FastFactory
92{
93  public:
94    static FastFactory* getFastFactory(ClassID classID, const char* fastFactoryName = NULL);
95
96    void prepare(unsigned int count);
97
98    T* resurect();
99    void kill(T* object);
100
101  private:
102    tFastFactory(ClassID classID, const char* fastFactoryName);
103
104    T* fabricate();
105
106  private:
107    FastObjectMember<T>*     deadList;             //!< A List of all stored dead Objects of this class.
108    FastObjectMember<T>*     unusedContainers;     //!< This is a List of unused containers, that will be reused by kill.
109
110};
111
112/**
113 * construnts a FastFactory with
114 * @param fastFactoryName the name of the FastFactory
115 * @param fastFactory the ID of the class
116 */
117template<class T>
118    tFastFactory<T>::tFastFactory(ClassID classID, const char* fastFactoryName)
119  : FastFactory(classID, fastFactoryName)
120{
121  PRINTF(5)("Class: %s loadable as a FastFactory\n", this->getName());
122
123  this->deadList = NULL;
124  this->unusedContainers = NULL;
125}
126
127template<class T>
128    FastFactory* tFastFactory<T>::getFastFactory(ClassID classID, const char* fastFactoryName)
129{
130  tFastFactory<T>* tmpFac = NULL;
131  if (FastFactory::getFirst() != NULL)
132    tmpFac = FastFactory::getFirst()->searchFastFactory(classID, fastFactoryName);
133
134  if (tmpFac != NULL)
135    return tmpFac;
136  else
137    return new tFastFactory<T>;
138}
139
140
141template<class T>
142    T* tFastFactory<T>::fabricate()
143{
144  FastObjectMember<T>* tmpFirstDead = this->deadList;
145  tmpFirstDead->objectPointer = new T();
146  tmpFirstDead->next = this->deadList;
147  ++this->storedDeadObjects;
148
149  this->deadList = tmpFirstDead;
150  return this->deadList;
151}
152
153template<class T>
154    void tFastFactory<T>::prepare(unsigned int count)
155{
156  if (this->storedDeadObjects + this->storedLivingObjects >= count)
157  {
158    PRINTF(3)("not creating new Objects for class %s, because the requested count already exists\n", this->getClassName());
159  }
160  for (int i = this->storedDeadObjects + this->storedLivingObjects; i < count; i++)
161  {
162    this->fabricate();
163  }
164}
165
166template<class T>
167    T* tFastFactory<T>::resurect()
168{
169  if (unlikely(this->deadList == NULL))
170  {
171    PRINTF(2)("The deadList of Class %s is empty, this may be either because it has not been filled yet, or the cache is to small.\n" \
172        "Fabricating a new %s", this->getName(), this->getName());
173    return this->fabricate();
174  }
175  else
176  {
177    FastObjectMember<T>* tmpC = deadList;
178    this->deadList = this->deadList->next;
179
180    tmpC->next = this->unusedContainers;
181    this->unusedContainers->tmpC;
182
183    return tmpC;
184  }
185}
186
187template<class T>
188    void tFastFactory<T>::kill(T* object)
189{
190  FastObjectMember<T>* tmpC;
191  if (unlikely(this->unusedContainers == NULL))
192  {
193    tmpC = new FastObjectMember<T>;
194  }
195  else
196  {
197    tmpC = this->unusedContainers;
198    this->unusedContainers = this->unusedContainers->next;
199  }
200
201  tmpC->next = this->deadList;
202  tmpC->objectPointer = object;
203}
204
205////////////////////
206// OBJECT MANAGER //
207////////////////////
208
209//! the object manager itself
210class ObjectManager : public BaseObject {
211
212 public:
213  virtual ~ObjectManager();
214  /** @returns a Pointer to the only object of this Class */
215  inline static ObjectManager* getInstance() { if (!singletonRef) singletonRef = new ObjectManager();  return singletonRef; };
216
217  void registerClass(ClassID classID);
218
219  BaseObject* resurect();
220  void kill(BaseObject* object);
221
222
223  void debug() const;
224
225 private:
226  ObjectManager();
227
228 private:
229  static ObjectManager*      singletonRef;          //!< The singleton reference to the only reference of this class
230
231};
232
233
234
235#endif /* _OBJECT_MANAGER_H */
Note: See TracBrowser for help on using the repository browser.