#ifndef _ClassHierarchy_H__ #define _ClassHierarchy_H__ #include #include // DONE AND TESTED: // - build class hierarchy // - isA, isChildOf, ... // - insert into class-lists // - ClassIdentifier // IN WORK: // - BaseIdentifier // - Factory // TO DO: // - iterate through lists // - searchtree for classname-strings namespace orxonox { // ##### ClassHierarchy ##### template class ClassIdentifier; class ClassHierarchy { template friend class ClassIdentifier; public: static ClassHierarchy* getSingleton(); bool isCreatingHierarchy() { return (this->hierarchyCreatingCounter_ > 0); } private: ClassHierarchy(); ~ClassHierarchy(); void startCreatingHierarchy() { this->hierarchyCreatingCounter_++; std::cout << "*** Increased Hierarchy-Creating-Counter to " << this->hierarchyCreatingCounter_ << "\n"; } void stopCreatingHierarchy() { this->hierarchyCreatingCounter_--; std::cout << "*** Decreased Hierarchy-Creating-Counter to " << this->hierarchyCreatingCounter_ << "\n"; } static ClassHierarchy* pointer_; int hierarchyCreatingCounter_; }; // ##### Identifier ##### class IdentifierList; class ObjectList; class OrxonoxClass; class Identifier { template friend class ClassIdentifier; template friend class BaseIdentifier; public: void addObject(OrxonoxClass* object); void removeObject(OrxonoxClass* object); bool isA(Identifier* identifier); bool isDirectlyA(Identifier* identifier); bool isChildOf(Identifier* identifier); bool isDirectChildOf(Identifier* identifier); bool isParentOf(Identifier* identifier); bool isDirectParentOf(Identifier* identifier); std::string getName() { return this->name_; } IdentifierList* getDirectParents() { return this->directParents_; } IdentifierList* getAllParents() { return this->allParents_; } IdentifierList* getDirectChildren() { return this->directChildren_; } IdentifierList* getAllChildren() { return this->allChildren_; } private: Identifier(); Identifier(const Identifier& identifier) {} virtual ~Identifier(); void initialize(IdentifierList* parents); IdentifierList* directParents_; IdentifierList* allParents_; IdentifierList* directChildren_; IdentifierList* allChildren_; ObjectList* objects_; std::string name_; bool bCreatedOneObject_; }; // ##### ClassIdentifier ##### template class ClassIdentifier : public Identifier { public: static ClassIdentifier* registerClass(IdentifierList* parents, std::string name, bool bRootClass); static ClassIdentifier* getIdentifier(); static T* create(); private: ClassIdentifier(); ClassIdentifier(const ClassIdentifier& identifier) {} ~ClassIdentifier(); static ClassIdentifier* pointer_; }; template ClassIdentifier* ClassIdentifier::pointer_ = NULL; template ClassIdentifier::ClassIdentifier() { } template ClassIdentifier::~ClassIdentifier() { this->pointer_ = NULL; } template ClassIdentifier* ClassIdentifier::registerClass(IdentifierList* parents, std::string name, bool bRootClass) { std::cout << "*** Register Class in " << name << "-Singleton.\n"; if (!pointer_) { std::cout << "*** Register Class in " << name << "-Singleton -> Create Singleton.\n"; if (parents || bRootClass) { pointer_ = new ClassIdentifier(); pointer_->name_ = name; pointer_->initialize(parents); } else { pointer_ = getIdentifier(); } } return pointer_; } template ClassIdentifier* ClassIdentifier::getIdentifier() { // std::cout << "*** Get Identifier.\n"; if (!pointer_) { std::cout << "*** Get Identifier -> Create Class\n"; ClassHierarchy::getSingleton()->startCreatingHierarchy(); T* temp = new T(); ClassHierarchy::getSingleton()->stopCreatingHierarchy(); delete temp; } return pointer_; } template T* ClassIdentifier::create() { return new T(); } // ##### BaseIdentifier ##### template class BaseIdentifier// : public Identifier { public: BaseIdentifier(); template BaseIdentifier& operator= (ClassIdentifier* identifier) { std::cout << "####### Class(" << identifier->getName() << ")->isA( Class(" << ClassIdentifier::getIdentifier()->getName() << ") ) = " << identifier->isA( ClassIdentifier::getIdentifier() ) << "\n"; if (!identifier->isA(ClassIdentifier::getIdentifier())) { std::cout << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier::getIdentifier()->getName() << "!\n"; std::cout << "Error: BaseIdentifier<" << ClassIdentifier::getIdentifier()->getName() << "> = Class(" << identifier->getName() << ") is forbidden.\n"; std::cout << "Aborting...\n"; abort(); } this->identifier_ = identifier; return *this; } operator Identifier() { return this->identifier_; } private: Identifier* identifier_; }; template BaseIdentifier::BaseIdentifier() { this->identifier_ = ClassIdentifier::getIdentifier(); } // ##### Identifier List ##### class IdentifierListElement; class IdentifierList { public: IdentifierList(); ~IdentifierList(); void add(Identifier* identifier); void remove(Identifier* identifier); bool isInList(Identifier* identifier); std::string toString(); IdentifierListElement* first_; }; class IdentifierListElement { public: IdentifierListElement(Identifier* identifier); ~IdentifierListElement(); Identifier* identifier_; IdentifierListElement* next_; bool bDirect_; }; // ##### Object List ##### class ObjectListElement; class ObjectList { public: ObjectList(); ~ObjectList(); void add(OrxonoxClass* object); void remove(OrxonoxClass* object); ObjectListElement* first_; }; class ObjectListElement { public: ObjectListElement(OrxonoxClass* object); ~ObjectListElement(); OrxonoxClass* object_; ObjectListElement* next_; }; // ##### Macros ##### #define registerRootObject(ClassName) \ std::cout << "*** Register Root-Object: " << #ClassName << "\n"; \ if (ClassHierarchy::getSingleton()->isCreatingHierarchy() && !this->getParents()) \ this->setParents(new IdentifierList()); \ if (this->getIdentifier()) \ this->getIdentifier()->removeObject(this); \ this->setIdentifier(ClassIdentifier::registerClass(this->getParents(), #ClassName, true)); \ if (ClassHierarchy::getSingleton()->isCreatingHierarchy() && this->getParents()) \ this->getParents()->add(this->getIdentifier()); \ this->getIdentifier()->addObject(this) #define registerObject(ClassName) \ std::cout << "*** Register Object: " << #ClassName << "\n"; \ this->getIdentifier()->removeObject(this); \ this->setIdentifier(ClassIdentifier::registerClass(this->getParents(), #ClassName, false)); \ if (ClassHierarchy::getSingleton()->isCreatingHierarchy() && this->getParents()) \ this->getParents()->add(this->getIdentifier()); \ this->getIdentifier()->addObject(this) #define unregisterObject() \ this->getIdentifier()->removeObject(this) #define Class(ClassName) \ ClassIdentifier::getIdentifier() #define Factory(ClassName) \ ClassIdentifier::create() } #endif