/* 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: Benjamin Grauer */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOAD #include "fast_factory.h" #include "compiler.h" #include "debug.h" #include /** * Initializes a FastFactory * @param classID the ClassID this Class belongs to (the top-most) * @param fastFactoryName the Name of the ObjectClass-handled here * @return a new FastFactory */ FastFactory::FastFactory (ClassID classID, const std::string& fastFactoryName) { this->setClassID(CL_FAST_FACTORY, "FastFactory"); this->setName(fastFactoryName); this->storedClassID = classID; this->next = NULL; this->deadList = NULL; this->unusedContainers = NULL; this->storedDeadObjects = 0; FastFactory::registerFastFactory(this); } /** a reference to the First FastFactory */ FastFactory* FastFactory::first = NULL; /** * destructor * deletes all the Instances of the FastFactory. */ FastFactory::~FastFactory () { if (this == first) this->first = NULL; this->flush(); if (this->next) delete this->next; } /** * deletes all FastFactories */ void FastFactory::deleteAll() { if (FastFactory::first) delete FastFactory::first; } /** * registers a Factory to the List of known factories. * @param fastFactory The factory to add * * needed, to step through all the FastFactories. */ void FastFactory::registerFastFactory(FastFactory* fastFactory) { PRINTF(4)("Registered FastFactory for '%s'\n", fastFactory->getName()); if( FastFactory::first == NULL) FastFactory::first = fastFactory; else { FastFactory* tmpFac = FastFactory::first; while( tmpFac->next != NULL) tmpFac = tmpFac->next; tmpFac->setNext(fastFactory); } } /** * searches for a FastFactory * @param classID the ClassID of the FastFactory to search for * @returns true if found, false otherwise. */ FastFactory* FastFactory::searchFastFactory(ClassID classID) { if (FastFactory::first == NULL) return NULL; else { FastFactory* tmpFac = FastFactory::first; while (tmpFac != NULL) { if (tmpFac->storedClassID == classID) return tmpFac; tmpFac = tmpFac->next; } } return NULL; } /** * searches for a FastFactory * @param classID the ClassID of the FastFactory to search for * @returns true if found, false otherwise. */ FastFactory* FastFactory::searchFastFactory(const std::string& fastFactoryName) { if (FastFactory::first == NULL) return NULL; else { FastFactory* tmpFac = FastFactory::first; while (tmpFac != NULL) { if (fastFactoryName == tmpFac->getName()) return tmpFac; tmpFac = tmpFac->next; } } return NULL; } /** * Removes all the stored Containers, and sets the Lists back to emptienes. * @param hardFLUSH if true the containing Objects will also be deleted !! THIS IS DANGEROUS !! */ void FastFactory::flushAll(bool hardFLUSH) { FastFactory* tmpFac = FastFactory::first; while (tmpFac != NULL) { PRINTF(4)("DELETEING ALL OF %s\n",tmpFac->getName()); tmpFac->flush(hardFLUSH); tmpFac = tmpFac->next; } } /** * ereases all the remaining containers, without deleting the stored Objects inside of them. * @param hardFLUSH if the the containing Objects will also be deleted !! THIS IS DANGEROUS !! */ void FastFactory::flush(bool hardFLUSH) { FastObjectMember* tmpMember = this->deadList, *delMember = NULL; while (tmpMember != NULL) { delMember = tmpMember; tmpMember = tmpMember->next; if (hardFLUSH) { delete delMember->objectPointer; } delete delMember; } this->deadList = NULL; tmpMember = this->unusedContainers; while (tmpMember != NULL) { delMember = tmpMember; tmpMember = tmpMember->next; delete delMember; } this->unusedContainers = NULL; } /** * generates count new Object of the Corresponding class. (precaching) * @param count How many instances of the class should be generated. */ void FastFactory::prepare(unsigned int count) { /* if (this->storedDeadObjects + this->storedLivingObjects >= count) { PRINTF(3)("not creating new Objects for class %s, because the requested count already exists\n", this->getClassName()); }*/ for (unsigned int i = this->storedDeadObjects; i < count; i++) { this->fabricate(); } } /** * gives back live to one Object. * @return the Object to resurrect. */ BaseObject* FastFactory::resurrect() { PRINTF(4)("Resurecting Object of type %s\n", this->getName()); if (unlikely(this->deadList == NULL)) { PRINTF(3)("The deadList of Class %s is empty, this may be either because it has not been filled yet, or the cache is to small.\n" \ " Developer: try increasing the count with FastFactory::prepare(contHigher than actual)\n" \ " Fabricating a new %s\n", this->getName(), this->getName()); this->fabricate(); return this->resurrect(); } else { FastObjectMember* tmpC = this->deadList; this->deadList = this->deadList->next; tmpC->next = this->unusedContainers; this->unusedContainers = tmpC; return tmpC->objectPointer; } } /** * gives back live to one Object. * @param classID the class From which to resurrect an Object. * @return the Object to resurrect, NULL if classID is not found. */ BaseObject* FastFactory::resurrect(ClassID classID) { FastFactory* tmpFac = FastFactory::getFirst(); while (tmpFac != NULL) { if (classID == tmpFac->storedClassID) return tmpFac->resurrect(); tmpFac = tmpFac->next; } return NULL; } /** * kills Object object, meaning, that it will be stored in the deadList of the FastFactory, and waiting for resurrection * @param object the Object to kill. * * synony that would be really grate would be abolish, but this is more like exterminate than pause-mode. */ void FastFactory::kill(BaseObject* object) { FastObjectMember* tmpC; if (unlikely(this->unusedContainers == NULL)) { tmpC = new FastObjectMember; } else { tmpC = this->unusedContainers; this->unusedContainers = this->unusedContainers->next; } tmpC->next = this->deadList; tmpC->objectPointer = object; this->deadList = tmpC; } void FastFactory::kill(BaseObject* object, bool searchForFastFactory) { if (likely(searchForFastFactory == true)) { FastFactory* tmpFac = FastFactory::first; while (tmpFac != NULL) { if (object->isA(tmpFac->storedClassID)) { tmpFac->kill(object); return; } tmpFac = tmpFac->next; } } }