/*! * @file fast_factory.h * The ObjectManager (FastFactory) is designed, to automatically generate and remove * (without to much overhead) many instances of different classes. * * It is especially usefull for objects, that come only for a short time into existence, * and get killed after a small amount of time (like shots). * * The Creation of an Object is usually done in the Weapon Class, where one subscribes * a Projectile with: * this->bulletFactory = tFastFactory::getFastFactory(CL_TEST_BULLET, "TestBullet"); * (this might change over time). * Then you can at loading time initialize an amount of the class with something like: * this->bulletFactory->prepare(100); // creates 100 entities of TestBullet (dead ones) * afterwards one can just retrieve an Object form the Class with * this->bulletFactory->resurrect(); // this returns a BaseObject an Object of the class. * * The big difference to the FastFactory-class is, that this one is used more for the purpose * of fast game-interaction than for loading. althought one can also load FastFactorized classes * it is not the main topic. */ #ifndef _FAST_FACTORY_H #define _FAST_FACTORY_H #include "base_object.h" /** * Creates a FastFactory to a Createable FastFactory. */ #define CREATE_FAST_FACTORY(CLASS_NAME, CLASS_ID) \ tFastFactory* global_##CLASS_NAME##_FastFactory = tFastFactory::getFastFactory(CLASS_ID, #CLASS_NAME) //! A struct, that holds Lists of Objects of a certain type. typedef struct FastObjectMember { BaseObject* objectPointer; //!< Pointer to the Object Stored in this Class (if it is the DeadList, else it is bork) FastObjectMember* next; //!< the next stored FastObjectMember. (or NULL if this is the last one stored in either the deadList or the unusedContainers) }; //! The FastFactory is a fast loadable object creator, and Dynamic List of dead object handler. /** * The ObjectManager (FastFactory) is designed, to automatically generate and remove * (without to much overhead) many instances of different classes. * * FastFactory is needed to glue all the tFastFactories together. * It is also the general class that implements the necessary functions * to generate, resurrect kill and stuff... */ class FastFactory : public BaseObject { public: virtual ~FastFactory (); static void deleteAll(); // functions to push and pop elements of this class BaseObject* resurrect(); static BaseObject* resurrect(ClassID classID); void kill(BaseObject* object); static void kill(BaseObject* object, bool searchForFastFactory); void prepare(unsigned int count); static void flushAll(bool hardFLUSH = false); void flush(bool hardFLUSH = false); /** @returns the first FastFactory */ inline static FastFactory* getFirst() { return FastFactory::first; }; static FastFactory* searchFastFactory(ClassID classID); static FastFactory* searchFastFactory(const char* fastFactoryName); ClassID getStoredID() const { return this->storedClassID; }; protected: FastFactory (ClassID classID, const char* fastFactoryName = NULL); /** sets the Next factory in the list @param nextFactory the next factory */ inline void setNext( FastFactory* nextFastFactory) { this->next = nextFastFactory; }; /** @returns the next FastFactory */ FastFactory* getNext() const { return this->next; }; /** generates a new Object of the Class T */ virtual void fabricate() = 0; private: static void registerFastFactory(FastFactory* fastFactory); protected: ClassID storedClassID; //!< The classID of the specified class. unsigned int storedDeadObjects; //!< How many dead objects are stored in this class FastObjectMember* deadList; //!< A List of all stored dead Objects of this class. FastObjectMember* unusedContainers; //!< This is a List of unused containers, that will be reused by kill. private: static FastFactory* first; //!< A pointer to the first FastFactory. FastFactory* next; //!< pointer to the next FastFactory. }; /** * a FastFactory that is able to load any kind of Object from a ClassID * (this is a Functor) */ template class tFastFactory : public FastFactory { public: static tFastFactory* getFastFactory(ClassID classID, const char* fastFactoryName = NULL); private: tFastFactory(ClassID classID, const char* fastFactoryName); virtual void fabricate(); }; /** * construnts a FastFactory with * @param fastFactoryName the name of the FastFactory * @param fastFactory the ID of the class * @todo (can this be written in another form??) */ template tFastFactory::tFastFactory(ClassID classID, const char* fastFactoryName) : FastFactory(classID, fastFactoryName) {} /** * creates (if not existent) a Factory of Class T, and assigns some values to it * @param classID the ClassID to assign to this class * @param fastFactoryName the name to assign * @returns The FastFactory if existent a new Factory if not. */ template tFastFactory* tFastFactory::getFastFactory(ClassID classID, const char* fastFactoryName) { tFastFactory* tmpFac = NULL; if (FastFactory::getFirst() != NULL) tmpFac = static_cast*>(FastFactory::getFirst()->searchFastFactory(classID)); if (tmpFac != NULL) return tmpFac; else return new tFastFactory(classID, fastFactoryName); } /** * fabricates an Object of Class T, that corresponds to classID. */ template void tFastFactory::fabricate() { FastObjectMember* tmpFirstDead = new FastObjectMember; tmpFirstDead->objectPointer = new T(); tmpFirstDead->next = this->deadList; ++this->storedDeadObjects; this->deadList = tmpFirstDead; } #endif /* _FAST_FACTORY_H */