/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2006 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Grauer co-programmer: ... */ //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ #include "object_list.h" #include /** * @brief Constructor, that creates an ObjectList while checking (development mode) for uniqueness of all Keys (names and ID's) * @param className The Name of the Class to create an ObjectList for. * @param id The ID if you like, or -1 otherwise. * @return a new NewObejctList */ ObjectListBase::ObjectListBase(const std::string& className, int id) : _name(className) { if (ObjectListBase::_classesByID == NULL) { ObjectListBase::_classesByID = new IDMap; assert (ObjectListBase::_classesByName == NULL); ObjectListBase::_classesByName = new NameMap; } assert(!ObjectListBase::classNameExists(className) && "Classes should only be included once, and no two classes should have the same name (key value)"); if (id == -1) { id = ObjectListBase::_classesByID->size(); // searching for a free ID while (ObjectListBase::classIDExists(id)) ++id; } assert(!ObjectListBase::classIDExists(id) && "Classes should only be included once, and no two classes should have the same ID (key value)"); this->_id = id; /// Some Output, that will fall out later // std::cout << "register new ObjectList " << className << " ID: " << this->_id << std::endl; this->_identity = ClassID(this); (*ObjectListBase::_classesByID)[this->_identity.id()] = this; (*ObjectListBase::_classesByName)[this->_identity.name()] = this; } /** * Destructor. * * This destructor deletes the ObjectList, and cleans up the ObjectList sorted Maps. */ ObjectListBase::~ObjectListBase() { assert (ObjectListBase::_classesByName != NULL && ObjectListBase::_classesByID != NULL); /* std::cout << "Erasing: " << this->_name << " "<< this->_id << std::endl; std::cout << "SIZE OF _classByID: " << ObjectListBase::_classesByID->size() << std::endl; std::cout << "SIZE OF _classByName: " << ObjectListBase::_classesByName->size() << std::endl; */ ObjectListBase::_classesByID->erase(this->_identity.id()); ObjectListBase::_classesByName->erase(this->_identity.name()); if (ObjectListBase::_classesByID->empty()) { delete ObjectListBase::_classesByID; ObjectListBase::_classesByID = NULL; assert(ObjectListBase::_classesByName != NULL); delete ObjectListBase::_classesByName; ObjectListBase::_classesByName = NULL; } } ObjectListBase::IDMap* ObjectListBase::_classesByID = NULL; ObjectListBase::NameMap* ObjectListBase::_classesByName = NULL; std::list ObjectListBase::_classNames; /** * @returns the Registered Class Count. */ unsigned int ObjectListBase::classCount() { assert (ObjectListBase::_classesByID != NULL); return ObjectListBase::_classesByID->size(); }; /** * @brief Checks if a Class with name already exists. * @param id The id of the Class to check. * @return true if such a class already exists. */ bool ObjectListBase::classIDExists(int id) { return (ObjectListBase::_classesByID->find(id) != ObjectListBase::_classesByID->end()); } /** * @brief Checks if a Class with name already exists. * @param name The Name of the Class to check. * @return true if such a class already exists. */ bool ObjectListBase::classNameExists(const std::string& name) { return (ObjectListBase::_classesByName->find(name) != ObjectListBase::_classesByName->end()); } /** * @brief searches for a ClassID in the list of all ObjectLists, and returns its Identity * @param id: The Id to search for * @returns the ClassID if found and NullClass' identity if not. */ const ClassID& ObjectListBase::retrieveIdentity(int id) { const ObjectListBase* const base = ObjectListBase::getObjectList(id); if (base != NULL) return base->_identity; else return NullClass::staticClassID(); } /** * @brief searches for a ClassID in the list of all ObjectLists, and returns its Identity * @param name: The Name to search for * @returns the ClassID if found and NullClass' identity if not. */ const ClassID& ObjectListBase::retrieveIdentity(const std::string& name) { const ObjectListBase* const base = ObjectListBase::getObjectList(name); if (base != NULL) return base->_identity; else return NullClass::staticClassID(); } /** * @brief Searches for a ObjectList with the ID classID * @param classID the ID to search for. * @return The ObjectList if found, NULL otherwise. */ const ObjectListBase* const ObjectListBase::getObjectList(int classID) { assert (ObjectListBase::_classesByID != NULL); ObjectListBase::IDMap::iterator it = ObjectListBase::_classesByID->find(classID); if (it != ObjectListBase::_classesByID->end()) return (*it).second; else return NULL; } /** * @brief Searches for a ObjectList with the Name className * @param className the Name to search for. * @return The ObjectList if found, NULL otherwise. */ const ObjectListBase* const ObjectListBase::getObjectList(const std::string& className) { assert (ObjectListBase::_classesByName != NULL); ObjectListBase::NameMap::iterator it = ObjectListBase::_classesByName->find(className); if (it != ObjectListBase::_classesByName->end()) return (*it).second; else return NULL; } /** * @brief Searches for a ObjectList with the ClassID classID * @param classID the ID to search for. * @return The ObjectList if found, NULL otherwise. */ const ObjectListBase* const ObjectListBase::getObjectList(const ClassID& classID) { return ObjectListBase::getObjectList(classID.id()); } /** * @brief Retrieves the first BaseObject matching the name objectName from the List matching classID. * @param classID the ID of the List. * @param objectName the Name of the Object to search for */ BaseObject* ObjectListBase::getBaseObject(int classID, const std::string& objectName) { const ObjectListBase* const base = ObjectListBase::getObjectList(classID); if (base != NULL) return base->getBaseObject(objectName); else return NULL; } /** * @brief Retrieves the first BaseObject matching the name objectName from the List matching className. * @param className the Name of the List. * @param objectName the Name of the Object to search for */ BaseObject* ObjectListBase::getBaseObject(const std::string& className, const std::string& objectName) { const ObjectListBase* const base = ObjectListBase::getObjectList(className); if (base != NULL) return base->getBaseObject(objectName); else return NULL; } /** * @brief Retrieves the first BaseObject matching the name objectName from the List matching classID. * @param classID The ClassID of the List. * @param objectName the Name of the Object to search for */ BaseObject* ObjectListBase::getBaseObject(const ClassID& classID, const std::string& objectName) { const ObjectListBase* const base = ObjectListBase::getObjectList(classID); if (base != NULL) return base->getBaseObject(objectName); else return NULL; } /** * @returns An alphabetically sorted List of all stored ClassNames. */ const std::list& ObjectListBase::getClassNames() { if (ObjectListBase::classCount() != ObjectListBase::_classNames.size()) { ObjectListBase::_classNames.clear(); for (NameMap::const_iterator it = ObjectListBase::_classesByName->begin(); it != ObjectListBase::_classesByName->end(); ++it) ObjectListBase::_classNames.push_back((*it).second->name()); } return ObjectListBase::_classNames; } #include "base_object.h" /** * @brief Prints out some debugging information about a given List. * @param level: * 1: List ObjectListsand how many object. * 2: 1+List ObjectLists entries, and information about Objects. */ void ObjectListBase::debug(unsigned int level) const { base_list list; this->getBaseObjectList(&list); if (level > 1 || !list.empty()) printf(" ObjectList of class %s(id:%d) contains %d objects\n", this->name().c_str(), this->id(), list.size()); if (level >= 2) { printf(" - listing Instances: \n"); for (base_iterator it = list.begin(); it != list.end(); ++it) { printf(" + %s::%s (%p)\n", (*it)->getClassCName(), (*it)->getCName(), (*it)); } } } /** * @brief prints out debug output about all Lists * @param level: * 0: list number of ClassList and general info. * 1: 0+List ObjectLists and how many object. * 2: 1+List ObjectLists entries, and information about Objects. */ void ObjectListBase::debugAll(unsigned int level) { printf("Listing all %d ObjectLists \n", ObjectListBase::_classesByID->size()); for (NameMap::const_iterator it = ObjectListBase::_classesByName->begin(); it != ObjectListBase::_classesByName->end(); ++it) (*it).second->debug(level); } /** * @brief Converts an ID into a ClassName String. * @param classID The ID to convert. * @return The ClassName or an empty string if the ID was not found. */ const std::string& ObjectListBase::IDToString(int classID) { const ObjectListBase* const base = ObjectListBase::getObjectList(classID); if (base != NULL) return base->name(); else { static std::string empty; return empty; } } /** * @brief Converts a String into an ID * @param className the Name of the Class to search for * @return The Classes ID if found, -1 otherwise. */ int ObjectListBase::StringToID(const std::string& className) { const ObjectListBase* const base = ObjectListBase::getObjectList(className); if (base != NULL) return base->id(); else return -1; }