/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 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: Christian Meyer co-programmer: Benjamin Grauer */ /*! * @file factory.h * @brief A loadable object handler */ #ifndef _FACTORY_H #define _FACTORY_H class BaseObject; #include "parser/tinyxml/tinyxml.h" #include "base_object.h" #include "debug.h" /** * Creates a factory to a Loadable Class. * this should be used at the beginning of all the Classes that should be loadable (in the cc-file) */ #define CREATE_FACTORY(CLASS_NAME, CLASS_ID) \ tFactory* global_##CLASS_NAME##_Factory = new tFactory(#CLASS_NAME, CLASS_ID) //! The Factory is a loadable object handler class Factory : public BaseObject { public: Factory (const char* factoryName = NULL, ClassID classID = CL_NULL); virtual ~Factory (); void fabricate(const char* className, const char* entityName); virtual BaseObject* fabricate(ClassID classID) = NULL; virtual BaseObject* fabricate(const TiXmlElement* root) = NULL; virtual BaseObject* fabricateDirect() = NULL; static void registerFactory( Factory* factory); /** @returns the first factory */ static Factory* getFirst() { return Factory::first; }; protected: /** sets the Next factory in the list @param nextFactory the next factory */ inline void setNext( Factory* nextFactory) { this->next = nextFactory; }; /** @returns the next factory */ Factory* getNext() const { return this->next; }; protected: ClassID classID; //!< The CLass-Identifyer of the Factory. private: Factory* next; //!< pointer to the next factory. static Factory* first; //!< A pointer to the first factory. }; /** * a factory that is able to load any kind of Object * (this is a Functor) */ template class tFactory : public Factory { public: tFactory(const char* factoryName, ClassID classID); virtual ~tFactory(); private: virtual BaseObject* fabricate(ClassID classID); virtual BaseObject* fabricate(const TiXmlElement* root); virtual BaseObject* fabricateDirect(); }; /** * construnts a factory with * @param factoryName the name of the factory */ template tFactory::tFactory(const char* factoryName, ClassID classID) : Factory(factoryName, classID) { PRINTF(4)("Class: %s loadable\n", this->getName()); } /** * destructs the type-Factory */ template tFactory::~tFactory() {} /** * fabricates an Object of type T, with the constructor T::T(const TiXmlElemnt*) * @param root the TiXmlElement T should load parameters from. * @return the newly fabricated T, NULL otherwise. */ template BaseObject* tFactory::fabricate(const TiXmlElement* root) { if (root == NULL) return NULL; if(!strcmp(root->Value(), this->getName())) return new T ( root); else if( getNext() != NULL) return getNext()->fabricate( root); else return NULL; } /** * fabricates an Object of type T, with the constructor T::T(const TiXmlElemnt*) * @param classID the ClassID of T that should be created. * @return the newly fabricated T if fabricated NULL otherwise. */ template BaseObject* tFactory::fabricate(ClassID classID) { if(classID == this->classID) return this->fabricateDirect(); else if( getNext() != NULL) return getNext()->fabricate( classID); else return NULL; } /** * directly fabricate an Entity of this factory. */ template BaseObject* tFactory::fabricateDirect() { return new T((const TiXmlElement*)NULL); } #endif /* _FACTORY_H */