/*! * @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 #include #define NewObjectListDeclaration(ClassName) \ static NewObjectList objectList #define NewObjectListDefinitionID(ClassName, ID) \ NewObjectList ClassName::objectList(#ClassName, ID) #define NewObjectListDefinition(ClassName) \ NewObjectListDefinitionID(ClassName, -1) //! 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 ///// ///////////////////////// /** * @brief creates a new NewObjectList * @param name The name of the Class. * @param id The ID of the class if desired, or -1 if an id should be assigned automatically. */ template NewObjectList::NewObjectList(const std::string& name, int id) : NewObjectListBase(name, id) {} /** * @brief deletes the NewObjectList. */ template NewObjectList::~NewObjectList() { if (!_objects.empty()) { std::cout << "There are still Object in the ObjectList of " << this->name() << "(id:" << this->id() << ")\n"; this->debug(); } } 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)); } 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 */