/*! * @file new_object_list.h * @brief Definition of a dynamically allocating ClassID * */ #ifndef _NEW_OBJECT_LIST_H #define _NEW_OBJECT_LIST_H #include "type_info.h" #include #include #include #define NewObjectListDeclaration(ClassName) \ static NewObjectList objectList #define NewObjectListDefinition(ClassName) \ NewObjectList ClassName::objectList(#ClassName) #define NewObjectListDefinitionID(ClassName, ID) \ NewObjectList ClassName::objectList(#ClassName, ID) //! The superclass that all NewObjectLists follow. /** * @see template NewObjectList */ class NewObjectListBase { public: //! An iterator Base-Class, for iterator-casting and storing. class IteratorBase { }; public: inline int id() const { return _id; }; inline const std::string& name() const { return _name; }; bool operator==(int id) const { return _id == id; }; bool operator==(const std::string& name) const { return _name == name; }; virtual void debug() const = 0; static unsigned int classCount(); static const std::string& IDToString(int classID); static int StringToID(const std::string& className); static const std::list& getClassNames(); virtual void unregisterObject(IteratorBase* _iterators) = 0; protected: NewObjectListBase(const std::string& className, int id = -1); virtual ~NewObjectListBase(); private: NewObjectListBase(const NewObjectListBase&); static bool classIDExists(int id); static bool classNameExists(const std::string& className); protected: typedef std::map classIDMap; //!< The Generic Map. typedef std::map classNameMap;//!< The Generic Map. int _id; //!< The ID of the class. std::string _name; //!< The Name of the Class. private: static classIDMap* _classesByID; //!< A Map of all the classes in existance. static classNameMap* _classesByName; //!< A Map of all the classes in existance. static std::list _classNames; //!< A list of all the registered ClassNames. }; ///////////////////////// //// TEMPLATISATION ///// ///////////////////////// //! Defines a ObjectsList handler for objects of type T. /** * To define a Class with a ObjectList, you have to: * 1. Include 'NewObjectListDeclaration(T);' in its Declaration (at the beginning) * 2. Include 'NewObjectListDefinition(T);' in some Definition file (cc-file) * 3. In the constructor add 'registerObject(this, objectList);' * * @note The Class must define the compare with const std::string& operator for this to work. */ template class NewObjectList : public NewObjectListBase { public: typedef std::list list; typedef typename list::iterator iterator; typedef typename list::const_iterator const_iterator; class Iterator : public NewObjectListBase::IteratorBase { public: Iterator(iterator it) { _it = it; } inline iterator& it() { return _it; } typename NewObjectList::iterator _it; }; public: NewObjectList(const std::string& name, int id = -1); ~NewObjectList(); T* getObject(const std::string& name) const; inline const list& objects() const { return _objects; }; NewObjectListBase::IteratorBase* registerObject(T* object); void unregisterObject(IteratorBase* iterator); virtual void debug() const; private: //! the copy constructor will be hidden. NewObjectList(const NewObjectList& definer) {}; private: list _objects; }; ///////////////////////// //// IMPLEMENTATION ///// ///////////////////////// template NewObjectList::NewObjectList(const std::string& name, int id) : NewObjectListBase(name, id) {} template NewObjectList::~NewObjectList() { // assert(_objects.empty()); } template T* NewObjectList::getObject(const std::string& name) const { iterator it = std::find(this->_objects.begin(), this->_objects.end(), name); if (it != this->_objects.end()) return *it; else return NULL; } template NewObjectListBase::IteratorBase* NewObjectList::registerObject(T* object) { this->_objects.push_front(object); return new Iterator(this->_objects.begin()); } template void NewObjectList::unregisterObject(IteratorBase* iterator) { this->_objects.erase(static_cast(iterator)->it()); //_objects.erase(std::find(_objects.begin(), _objects.end(), object)); } #include template void NewObjectList::debug() const { const_iterator it; for (it = this->_objects.begin(); it != this->_objects.end(); ++it) { std::cout << (*it)->getName() << std::endl; } } #endif /* _NEW_OBJECT_LIST_H */