1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4     (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2014 Torus Knot Software Ltd
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
28 #include "OgreStableHeaders.h"
29 #include "OgreSceneManagerEnumerator.h"
30 
31 
32 namespace Ogre {
33 
34     //-----------------------------------------------------------------------
35     template<> SceneManagerEnumerator* Singleton<SceneManagerEnumerator>::msSingleton = 0;
getSingletonPtr(void)36     SceneManagerEnumerator* SceneManagerEnumerator::getSingletonPtr(void)
37     {
38         return msSingleton;
39     }
getSingleton(void)40     SceneManagerEnumerator& SceneManagerEnumerator::getSingleton(void)
41     {
42         assert( msSingleton );  return ( *msSingleton );
43     }
44 
45     //-----------------------------------------------------------------------
SceneManagerEnumerator()46     SceneManagerEnumerator::SceneManagerEnumerator()
47         : mInstanceCreateCount(0), mCurrentRenderSystem(0)
48     {
49         addFactory(&mDefaultFactory);
50 
51     }
52     //-----------------------------------------------------------------------
~SceneManagerEnumerator()53     SceneManagerEnumerator::~SceneManagerEnumerator()
54     {
55         // Destroy all remaining instances
56         // Really should have shutdown and unregistered by now, but catch here in case
57         Instances instancesCopy = mInstances;
58         for (Instances::iterator i = instancesCopy.begin(); i != instancesCopy.end(); ++i)
59         {
60             // destroy instances
61             for(Factories::iterator f = mFactories.begin(); f != mFactories.end(); ++f)
62             {
63                 if ((*f)->getMetaData().typeName == i->second->getTypeName())
64                 {
65                     (*f)->destroyInstance(i->second);
66                     mInstances.erase(i->first);
67                     break;
68                 }
69             }
70 
71         }
72         mInstances.clear();
73 
74     }
75     //-----------------------------------------------------------------------
addFactory(SceneManagerFactory * fact)76     void SceneManagerEnumerator::addFactory(SceneManagerFactory* fact)
77     {
78         mFactories.push_back(fact);
79         // add to metadata
80         mMetaDataList.push_back(&fact->getMetaData());
81         // Log
82         LogManager::getSingleton().logMessage("SceneManagerFactory for type '" +
83             fact->getMetaData().typeName + "' registered.");
84     }
85     //-----------------------------------------------------------------------
removeFactory(SceneManagerFactory * fact)86     void SceneManagerEnumerator::removeFactory(SceneManagerFactory* fact)
87     {
88         if(!fact)
89             OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot remove a null SceneManagerFactory.", "SceneManagerEnumerator::removeFactory");
90 
91         // destroy all instances for this factory
92         for (Instances::iterator i = mInstances.begin(); i != mInstances.end(); )
93         {
94             SceneManager* instance = i->second;
95             if (instance->getTypeName() == fact->getMetaData().typeName)
96             {
97                 fact->destroyInstance(instance);
98                 Instances::iterator deli = i++;
99                 mInstances.erase(deli);
100             }
101             else
102             {
103                 ++i;
104             }
105         }
106         // remove from metadata
107         for (MetaDataList::iterator m = mMetaDataList.begin(); m != mMetaDataList.end(); ++m)
108         {
109             if(*m == &(fact->getMetaData()))
110             {
111                 mMetaDataList.erase(m);
112                 break;
113             }
114         }
115         mFactories.remove(fact);
116     }
117     //-----------------------------------------------------------------------
getMetaData(const String & typeName) const118     const SceneManagerMetaData* SceneManagerEnumerator::getMetaData(const String& typeName) const
119     {
120         for (MetaDataList::const_iterator i = mMetaDataList.begin();
121             i != mMetaDataList.end(); ++i)
122         {
123             if (typeName == (*i)->typeName)
124             {
125                 return *i;
126             }
127         }
128 
129         OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
130             "No metadata found for scene manager of type '" + typeName + "'",
131             "SceneManagerEnumerator::createSceneManager");
132 
133     }
134     //-----------------------------------------------------------------------
135     SceneManagerEnumerator::MetaDataIterator
getMetaDataIterator(void) const136     SceneManagerEnumerator::getMetaDataIterator(void) const
137     {
138         return MetaDataIterator(mMetaDataList.begin(), mMetaDataList.end());
139 
140     }
141     //-----------------------------------------------------------------------
createSceneManager(const String & typeName,const String & instanceName)142     SceneManager* SceneManagerEnumerator::createSceneManager(
143         const String& typeName, const String& instanceName)
144     {
145         if (mInstances.find(instanceName) != mInstances.end())
146         {
147             OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM,
148                 "SceneManager instance called '" + instanceName + "' already exists",
149                 "SceneManagerEnumerator::createSceneManager");
150         }
151 
152         SceneManager* inst = 0;
153         for(Factories::iterator i = mFactories.begin(); i != mFactories.end(); ++i)
154         {
155             if ((*i)->getMetaData().typeName == typeName)
156             {
157                 if (instanceName.empty())
158                 {
159                     // generate a name
160                     StringStream s;
161                     s << "SceneManagerInstance" << ++mInstanceCreateCount;
162                     inst = (*i)->createInstance(s.str());
163                 }
164                 else
165                 {
166                     inst = (*i)->createInstance(instanceName);
167                 }
168                 break;
169             }
170         }
171 
172         if (!inst)
173         {
174             // Error!
175             OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
176                 "No factory found for scene manager of type '" + typeName + "'",
177                 "SceneManagerEnumerator::createSceneManager");
178         }
179 
180         /// assign rs if already configured
181         if (mCurrentRenderSystem)
182             inst->_setDestinationRenderSystem(mCurrentRenderSystem);
183 
184         mInstances[inst->getName()] = inst;
185 
186         return inst;
187 
188 
189     }
190     //-----------------------------------------------------------------------
destroySceneManager(SceneManager * sm)191     void SceneManagerEnumerator::destroySceneManager(SceneManager* sm)
192     {
193         if(!sm)
194             OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot destroy a null SceneManager.", "SceneManagerEnumerator::destroySceneManager");
195 
196         // Erase instance from map
197         mInstances.erase(sm->getName());
198 
199         // Find factory to destroy
200         for(Factories::iterator i = mFactories.begin(); i != mFactories.end(); ++i)
201         {
202             if ((*i)->getMetaData().typeName == sm->getTypeName())
203             {
204                 (*i)->destroyInstance(sm);
205                 break;
206             }
207         }
208 
209     }
210     //-----------------------------------------------------------------------
getSceneManager(const String & instanceName) const211     SceneManager* SceneManagerEnumerator::getSceneManager(const String& instanceName) const
212     {
213         Instances::const_iterator i = mInstances.find(instanceName);
214         if(i != mInstances.end())
215         {
216             return i->second;
217         }
218         else
219         {
220             OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
221                 "SceneManager instance with name '" + instanceName + "' not found.",
222                 "SceneManagerEnumerator::getSceneManager");
223         }
224 
225     }
226     //---------------------------------------------------------------------
hasSceneManager(const String & instanceName) const227     bool SceneManagerEnumerator::hasSceneManager(const String& instanceName) const
228     {
229         return mInstances.find(instanceName) != mInstances.end();
230     }
231     //-----------------------------------------------------------------------
232     SceneManagerEnumerator::SceneManagerIterator
getSceneManagerIterator(void)233     SceneManagerEnumerator::getSceneManagerIterator(void)
234     {
235         return SceneManagerIterator(mInstances.begin(), mInstances.end());
236 
237     }
238     //-----------------------------------------------------------------------
getSceneManagers(void) const239     const SceneManagerEnumerator::Instances& SceneManagerEnumerator::getSceneManagers(void) const
240     {
241         return mInstances;
242     }
243     //-----------------------------------------------------------------------
setRenderSystem(RenderSystem * rs)244     void SceneManagerEnumerator::setRenderSystem(RenderSystem* rs)
245     {
246         mCurrentRenderSystem = rs;
247 
248         for (Instances::iterator i = mInstances.begin(); i != mInstances.end(); ++i)
249         {
250             i->second->_setDestinationRenderSystem(rs);
251         }
252 
253     }
254     //-----------------------------------------------------------------------
shutdownAll(void)255     void SceneManagerEnumerator::shutdownAll(void)
256     {
257         for (Instances::iterator i = mInstances.begin(); i != mInstances.end(); ++i)
258         {
259             // shutdown instances (clear scene)
260             i->second->clearScene();
261         }
262 
263     }
264     //-----------------------------------------------------------------------
265     const String DefaultSceneManagerFactory::FACTORY_TYPE_NAME = "DefaultSceneManager";
266     //-----------------------------------------------------------------------
initMetaData(void) const267     void DefaultSceneManagerFactory::initMetaData(void) const
268     {
269         mMetaData.typeName = FACTORY_TYPE_NAME;
270         mMetaData.worldGeometrySupported = false;
271     }
272     //-----------------------------------------------------------------------
createInstance(const String & instanceName)273     SceneManager* DefaultSceneManagerFactory::createInstance(
274         const String& instanceName)
275     {
276         return OGRE_NEW DefaultSceneManager(instanceName);
277     }
278     //-----------------------------------------------------------------------
destroyInstance(SceneManager * instance)279     void DefaultSceneManagerFactory::destroyInstance(SceneManager* instance)
280     {
281         OGRE_DELETE instance;
282     }
283     //-----------------------------------------------------------------------
284     //-----------------------------------------------------------------------
DefaultSceneManager(const String & name)285     DefaultSceneManager::DefaultSceneManager(const String& name)
286         : SceneManager(name)
287     {
288     }
289     //-----------------------------------------------------------------------
~DefaultSceneManager()290     DefaultSceneManager::~DefaultSceneManager()
291     {
292     }
293     //-----------------------------------------------------------------------
getTypeName(void) const294     const String& DefaultSceneManager::getTypeName(void) const
295     {
296         return DefaultSceneManagerFactory::FACTORY_TYPE_NAME;
297     }
298     //-----------------------------------------------------------------------
299 
300 
301 }
302