/* ----------------------------------------------------------------------------- This source file is part of OGRE (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2006 Torus Knot Software Ltd Also see acknowledgements in Readme.html This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt. You may alternatively use this source under the terms of a specific version of the OGRE Unrestricted License provided you have obtained such a license from Torus Knot Software Ltd. ----------------------------------------------------------------------------- */ #include "OgreStableHeaders.h" #include "OgreSceneManagerEnumerator.h" #include "OgreDynLibManager.h" #include "OgreDynLib.h" #include "OgreConfigFile.h" #include "OgreMaterial.h" #include "OgreException.h" #include "OgreRoot.h" #include "OgreLogManager.h" namespace Ogre { //----------------------------------------------------------------------- template<> SceneManagerEnumerator* Singleton::ms_Singleton = 0; SceneManagerEnumerator* SceneManagerEnumerator::getSingletonPtr(void) { return ms_Singleton; } SceneManagerEnumerator& SceneManagerEnumerator::getSingleton(void) { assert( ms_Singleton ); return ( *ms_Singleton ); } //----------------------------------------------------------------------- SceneManagerEnumerator::SceneManagerEnumerator() : mInstanceCreateCount(0), mCurrentRenderSystem(0) { addFactory(&mDefaultFactory); } //----------------------------------------------------------------------- SceneManagerEnumerator::~SceneManagerEnumerator() { // Destroy all remaining instances // Really should have shutdown and unregistered by now, but catch here in case for (Instances::iterator i = mInstances.begin(); i != mInstances.end(); ++i) { // destroy instances for(Factories::iterator f = mFactories.begin(); f != mFactories.end(); ++f) { if ((*f)->getMetaData().typeName == i->second->getTypeName()) { (*f)->destroyInstance(i->second); break; } } } mInstances.clear(); } //----------------------------------------------------------------------- void SceneManagerEnumerator::addFactory(SceneManagerFactory* fact) { mFactories.push_back(fact); // add to metadata mMetaDataList.push_back(&fact->getMetaData()); // Log LogManager::getSingleton().logMessage("SceneManagerFactory for type '" + fact->getMetaData().typeName + "' registered."); } //----------------------------------------------------------------------- void SceneManagerEnumerator::removeFactory(SceneManagerFactory* fact) { // destroy all instances for this factory for (Instances::iterator i = mInstances.begin(); i != mInstances.end(); ) { SceneManager* instance = i->second; if (instance->getTypeName() == fact->getMetaData().typeName) { fact->destroyInstance(instance); Instances::iterator deli = i++; mInstances.erase(deli); } else { ++i; } } // remove from metadata for (MetaDataList::iterator m = mMetaDataList.begin(); m != mMetaDataList.end(); ++m) { if(*m == &(fact->getMetaData())) { mMetaDataList.erase(m); break; } } mFactories.remove(fact); } //----------------------------------------------------------------------- const SceneManagerMetaData* SceneManagerEnumerator::getMetaData(const String& typeName) const { for (MetaDataList::const_iterator i = mMetaDataList.begin(); i != mMetaDataList.end(); ++i) { if (typeName == (*i)->typeName) { return *i; } } OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No metadata found for scene manager of type '" + typeName + "'", "SceneManagerEnumerator::createSceneManager"); } //----------------------------------------------------------------------- SceneManagerEnumerator::MetaDataIterator SceneManagerEnumerator::getMetaDataIterator(void) const { return MetaDataIterator(mMetaDataList.begin(), mMetaDataList.end()); } //----------------------------------------------------------------------- SceneManager* SceneManagerEnumerator::createSceneManager( const String& typeName, const String& instanceName) { if (mInstances.find(instanceName) != mInstances.end()) { OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "SceneManager instance called '" + instanceName + "' already exists", "SceneManagerEnumerator::createSceneManager"); } SceneManager* inst = 0; for(Factories::iterator i = mFactories.begin(); i != mFactories.end(); ++i) { if ((*i)->getMetaData().typeName == typeName) { if (instanceName.empty()) { // generate a name StringUtil::StrStreamType s; s << "SceneManagerInstance" << ++mInstanceCreateCount; inst = (*i)->createInstance(s.str()); } else { inst = (*i)->createInstance(instanceName); } break; } } if (!inst) { // Error! OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No factory found for scene manager of type '" + typeName + "'", "SceneManagerEnumerator::createSceneManager"); } /// assign rs if already configured if (mCurrentRenderSystem) inst->_setDestinationRenderSystem(mCurrentRenderSystem); mInstances[inst->getName()] = inst; return inst; } //----------------------------------------------------------------------- SceneManager* SceneManagerEnumerator::createSceneManager( SceneTypeMask typeMask, const String& instanceName) { if (mInstances.find(instanceName) != mInstances.end()) { OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "SceneManager instance called '" + instanceName + "' already exists", "SceneManagerEnumerator::createSceneManager"); } SceneManager* inst = 0; String name = instanceName; if (name.empty()) { // generate a name StringUtil::StrStreamType s; s << "SceneManagerInstance" << ++mInstanceCreateCount; name = s.str(); } // Iterate backwards to find the matching factory registered last for(Factories::reverse_iterator i = mFactories.rbegin(); i != mFactories.rend(); ++i) { if ((*i)->getMetaData().sceneTypeMask & typeMask) { inst = (*i)->createInstance(name); break; } } // use default factory if none if (!inst) inst = mDefaultFactory.createInstance(name); /// assign rs if already configured if (mCurrentRenderSystem) inst->_setDestinationRenderSystem(mCurrentRenderSystem); mInstances[inst->getName()] = inst; return inst; } //----------------------------------------------------------------------- void SceneManagerEnumerator::destroySceneManager(SceneManager* sm) { // Erase instance from map mInstances.erase(sm->getName()); // Find factory to destroy for(Factories::iterator i = mFactories.begin(); i != mFactories.end(); ++i) { if ((*i)->getMetaData().typeName == sm->getTypeName()) { (*i)->destroyInstance(sm); break; } } } //----------------------------------------------------------------------- SceneManager* SceneManagerEnumerator::getSceneManager(const String& instanceName) const { Instances::const_iterator i = mInstances.find(instanceName); if(i != mInstances.end()) { return i->second; } else { OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "SceneManager instance with name '" + instanceName + "' not found.", "SceneManagerEnumerator::getSceneManager"); } } //----------------------------------------------------------------------- SceneManagerEnumerator::SceneManagerIterator SceneManagerEnumerator::getSceneManagerIterator(void) { return SceneManagerIterator(mInstances.begin(), mInstances.end()); } //----------------------------------------------------------------------- void SceneManagerEnumerator::setRenderSystem(RenderSystem* rs) { mCurrentRenderSystem = rs; for (Instances::iterator i = mInstances.begin(); i != mInstances.end(); ++i) { i->second->_setDestinationRenderSystem(rs); } } //----------------------------------------------------------------------- void SceneManagerEnumerator::shutdownAll(void) { for (Instances::iterator i = mInstances.begin(); i != mInstances.end(); ++i) { // shutdown instances (clear scene) i->second->clearScene(); } } //----------------------------------------------------------------------- const String DefaultSceneManagerFactory::FACTORY_TYPE_NAME = "DefaultSceneManager"; //----------------------------------------------------------------------- void DefaultSceneManagerFactory::initMetaData(void) const { mMetaData.typeName = FACTORY_TYPE_NAME; mMetaData.description = "The default scene manager"; mMetaData.sceneTypeMask = ST_GENERIC; mMetaData.worldGeometrySupported = false; } //----------------------------------------------------------------------- SceneManager* DefaultSceneManagerFactory::createInstance( const String& instanceName) { return new DefaultSceneManager(instanceName); } //----------------------------------------------------------------------- void DefaultSceneManagerFactory::destroyInstance(SceneManager* instance) { delete instance; } //----------------------------------------------------------------------- //----------------------------------------------------------------------- DefaultSceneManager::DefaultSceneManager(const String& name) : SceneManager(name) { } //----------------------------------------------------------------------- DefaultSceneManager::~DefaultSceneManager() { } //----------------------------------------------------------------------- const String& DefaultSceneManager::getTypeName(void) const { return DefaultSceneManagerFactory::FACTORY_TYPE_NAME; } //----------------------------------------------------------------------- }