Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/new_class_id/src/lib/lang/new_object_list.h @ 9701

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

orxonox/trunk: new safer concept for NewClassID

File size: 10.5 KB
Line 
1/*!
2 * @file new_object_list.h
3 * @brief Definition of a dynamically allocating ClassID
4 *
5 */
6
7#ifndef _NEW_OBJECT_LIST_H
8#define _NEW_OBJECT_LIST_H
9
10#include "new_class_id.h"
11#include <map>
12#include <list>
13#include <string>
14#include <iostream>
15
16
17
18/**
19 * @brief Use this macro to easily declare a Class to store its own ObjectListDeclaration
20 * @param ClassName the Name of the Class.
21 * @note: Using this inside of a Class means, that you loose the member: _objectList, while defining
22 * two new functions objectList() and classID().
23 */
24#define NewObjectListDeclaration(ClassName) \
25  public: \
26   static inline const NewObjectList<ClassName>& objectList() { return ClassName::_objectList; }; \
27   static inline const NewClassID& classID() { return ClassName::_objectList.identity(); }; \
28  private: \
29   static NewObjectList<ClassName> _objectList
30
31#define NewObjectListDefinitionID(ClassName, ID) \
32   NewObjectList<ClassName> ClassName::_objectList(#ClassName, ID)
33
34
35#define NewObjectListDefinition(ClassName) \
36    NewObjectListDefinitionID(ClassName, -1)
37
38class BaseObject;
39//! The superclass that all NewObjectLists follow.
40/**
41 * @see template<class T> NewObjectList<T>
42 */
43class NewObjectListBase
44{
45public:
46  //! A fast iterator Base-Class, for iterator-casting and storing.
47  /**
48   * @note This Iterator is explicitely used only for storage purposes
49   */
50  class IteratorBase { };
51
52public:
53  inline const NewClassID& identity() const { return _identity; }
54  inline int id() const { return _id; };
55  inline const std::string& name() const { return _name; };
56  bool operator==(int id) const { return _id == id; };
57  bool operator==(const NewClassID& id) const { return id == _id; };
58  bool operator==(const std::string& name) const { return _name == name; };
59
60  void acquireID(const int*& id, const std::string*& name) const { id = &_id; name = &_name; };
61
62  virtual void debug() const = 0;
63
64  static unsigned int                   classCount();
65  static const std::string&             IDToString(int classID);
66  static int                            StringToID(const std::string& className);
67
68  static const std::list<std::string>&  getClassNames();
69
70  virtual void unregisterObject(IteratorBase* _iterators) = 0;
71
72protected:
73  NewObjectListBase(const std::string& className, int id = -1);
74  virtual ~NewObjectListBase();
75
76private:
77  NewObjectListBase(const NewObjectListBase&);
78
79  static bool classIDExists(int id);
80  static bool classNameExists(const std::string& className);
81
82public:
83  class base_iterator
84  {
85  public:
86    /// @NOTE Do not use this class. For internal handling.
87    class __base_iterator_base
88    {
89    public:
90      virtual void operator++(int) = 0;
91      virtual void operator++() = 0;
92      virtual void operator--(int) = 0;
93      virtual void operator--() = 0;
94      virtual BaseObject* operator*() = 0;
95      virtual __base_iterator_base* operator=(const __base_iterator_base& iterator) = 0;
96      virtual bool operator==(const __base_iterator_base& iterator) const = 0;
97      virtual bool operator!=(const __base_iterator_base& iterator) const = 0;
98      virtual __base_iterator_base* clone() const;
99    };
100
101  public:
102    base_iterator(const __base_iterator_base& it) { _it = it.clone(); };
103    ~base_iterator() { delete _it; }
104    void operator++() { (*_it)++; };
105    void operator++(int) { ++(*_it); };
106    void operator--() { (*_it)--; };
107    void operator--(int) { --(*_it); };
108    BaseObject* operator*() { return *(*_it); };
109    base_iterator& operator=(const base_iterator& iterator);
110    bool operator==(const base_iterator& iter) const { return *this->_it == *iter._it; };
111    bool operator!=(const base_iterator& iter) const { return *this->_it != *iter._it; };
112
113  private:
114    __base_iterator_base*    _it;
115  };
116
117  virtual base_iterator base_begin() const = 0;
118  virtual base_iterator base_end() const = 0;
119
120  static const NewObjectListBase* const getObjectList(int classID);
121  static const NewObjectListBase* const getObjectList(const std::string& className);
122  static const NewObjectListBase* const getObjectList(const NewClassID& classID);
123
124  static BaseObject* getBaseObject(int classID, const std::string& objectName);
125  static BaseObject* getBaseObject(const std::string& className, const std::string& objectName);
126  static BaseObject* getBaseObject(const NewClassID& classID, const std::string& objectName);
127
128  virtual BaseObject* getBaseObject(const std::string& name) const = 0;
129
130protected:
131  typedef std::map<int, NewObjectListBase*>         classIDMap;   //!< The Generic Map.
132  typedef std::map<std::string, NewObjectListBase*> classNameMap; //!< The Generic Map.
133
134  int                           _id;
135  const std::string             _name;              //!< The Name of the Class.
136  NewClassID                    _identity;          //!< The Identity of the Class. (equal to _id and _name)
137
138private:
139  static classIDMap*            _classesByID;       //!< A Map of all the classes in existance.
140  static classNameMap*          _classesByName;     //!< A Map of all the classes in existance.
141  static std::list<std::string> _classNames;        //!< A list of all the registered ClassNames.
142};
143
144
145/////////////////////////
146//// TEMPLATISATION /////
147/////////////////////////
148//! Defines a ObjectsList handler for objects of type T.
149/**
150 * To define a Class with a ObjectList, you have to:
151 *  1. Include 'NewObjectListDeclaration(T);' in its Declaration (at the beginning)
152 *  2. Include 'NewObjectListDefinition(T);' in some Definition file (cc-file)
153 *  3. In the constructor add 'registerObject(this, objectList);'
154 *
155 * @note The Class must define the compare with const std::string& operator for this to work.
156 */
157template<class T>
158class NewObjectList : public NewObjectListBase
159{
160public:
161  typedef std::list<T*>                  list;
162  typedef typename list::iterator        iterator;
163  typedef typename list::const_iterator  const_iterator;
164
165  virtual base_iterator base_begin() const { return base_iterator(__base_iterator(this->_objects.begin())); };
166  virtual base_iterator base_end() const { return base_iterator(__base_iterator(this->_objects.end())); };
167
168
169class Iterator : public NewObjectListBase::IteratorBase
170  {
171  public:
172    Iterator(iterator it) { _it = it; }
173    inline iterator& it() { return _it; }
174    typename NewObjectList::iterator _it;
175  };
176
177public:
178  NewObjectList(const std::string& name, int id = -1);
179  ~NewObjectList();
180
181  virtual BaseObject*     getBaseObject(const std::string& name) const;
182  T*                      getObject(const std::string& name) const;
183  inline const list&      objects() const { return _objects; };
184
185  inline iterator begin() { return _objects.begin(); };
186  inline const_iterator begin() const { return _objects.begin(); };
187  inline iterator  end() { return _objects.end(); };
188  inline const_iterator  end() const { return _objects.end(); };
189
190  inline bool empty() const { return _objects.empty(); };
191  inline int size() const { return _objects.size(); };
192  inline T* front() const { return _objects.front(); };
193  inline T* back() const { return _objects.back(); };
194
195  NewObjectListBase::IteratorBase* registerObject(T* object);
196  void unregisterObject(IteratorBase* iterator);
197
198  virtual void debug() const;
199
200protected:
201class __base_iterator : public base_iterator::__base_iterator_base
202  {
203  public:
204    __base_iterator(const const_iterator& iter);
205    void operator++(int) { ++_iter; };
206    void operator++()  { _iter++; };
207    void operator--(int) { --_iter; };
208    void operator--()  { _iter--; };
209    BaseObject* operator*() { return *_iter; };
210    base_iterator::__base_iterator_base* operator=(const __base_iterator_base& iterator) { this->_iter = static_cast<const __base_iterator&>(iterator)._iter; return this; };
211    bool operator==(const __base_iterator_base& iterator) const { return _iter == static_cast<const __base_iterator&>(iterator)._iter; };
212    bool operator!=(const __base_iterator_base& iterator) const { return _iter != static_cast<const __base_iterator&>(iterator)._iter; };
213  private:
214    const_iterator _iter;
215  };
216
217private:
218  //! the copy constructor will be hidden.
219  NewObjectList(const NewObjectList& definer) {};
220
221private:
222  list                _objects;
223};
224
225
226
227
228
229/////////////////////////
230//// IMPLEMENTATION /////
231/////////////////////////
232/**
233 * @brief creates a new NewObjectList
234 * @param name The name of the Class.
235 * @param id The ID of the class if desired, or -1 if an id should be assigned automatically.
236 */
237template <class T>
238NewObjectList<T>::NewObjectList(const std::string& name, int id)
239    : NewObjectListBase(name, id)
240{}
241
242/**
243 * @brief deletes the NewObjectList.
244 */
245template <class T>
246NewObjectList<T>::~NewObjectList()
247{
248  if (!_objects.empty())
249  {
250    std::cout << "There are still Object in the ObjectList of " << this->name() << "(id:" << this->id() << ")\n";
251    this->debug();
252  }
253}
254
255/**
256 * @brief Retrieves a BaseObject matching the Name name in this List.
257 * @param name the Name of the Object.
258 * @returns a BaseObject pointing to the object if found, NULL otherwise.
259 */
260template <class T>
261BaseObject* NewObjectList<T>::getBaseObject(const std::string& name) const
262{
263  return this->getObject(name);
264}
265
266
267
268/**
269 * @brief Retrieves an Object of type T matching the Name name in this List.
270 * @param name the Name of the Object.
271 * @returns an Object of type T pointing to the object if found, NULL otherwise.
272 */
273template <class T>
274T* NewObjectList<T>::getObject(const std::string& name) const
275{
276  const_iterator it;
277  for (it = this->_objects.begin(); it != this->_objects.end(); ++it)
278    if ((*it)->getName() == name)
279      return (*it);
280  return NULL;
281}
282
283/**
284 * @brief registers an Object to the NewObjectList.
285 * @param T object the Object to register.
286 * @returns a pointer to the iterator inside of the list.
287 */
288template <class T>
289NewObjectListBase::IteratorBase* NewObjectList<T>::registerObject(T* object)
290{
291  this->_objects.push_front(object);
292  return new Iterator(this->_objects.begin());
293}
294
295/**
296 * @brief removes an Object from the ClassList.
297 * @param iterator the Position at which to remove the Object.
298 */
299template <class T>
300void NewObjectList<T>::unregisterObject(IteratorBase* iterator)
301{
302  this->_objects.erase(static_cast<Iterator*>(iterator)->it());
303  //_objects.erase(std::find(_objects.begin(), _objects.end(), object));
304}
305
306/**
307 * @brief print out some debug information
308 * @note this function will most probably vanish from here and be completely moved to the base class.
309 */
310template <class T>
311void NewObjectList<T>::debug() const
312{
313  const_iterator it;
314  for (it = this->_objects.begin(); it != this->_objects.end(); ++it)
315  {
316    std::cout << (*it)->getName() << std::endl;
317  }
318}
319
320#endif /* _NEW_OBJECT_LIST_H */
Note: See TracBrowser for help on using the repository browser.