Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: more functionality: getObject, getObjectList, and many new doxy-tags

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