Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre/OgreMain/src/OgreResourceGroupManager.cpp @ 45

Last change on this file since 45 was 5, checked in by anonymous, 17 years ago

=hoffentlich gehts jetzt

File size: 47.5 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#include "OgreStableHeaders.h"
30#include "OgreResourceGroupManager.h"
31#include "OgreException.h"
32#include "OgreArchive.h"
33#include "OgreArchiveManager.h"
34#include "OgreLogManager.h"
35#include "OgreScriptLoader.h"
36#include "OgreSceneManager.h"
37
38namespace Ogre {
39
40    //-----------------------------------------------------------------------
41    template<> ResourceGroupManager* Singleton<ResourceGroupManager>::ms_Singleton = 0;
42    ResourceGroupManager* ResourceGroupManager::getSingletonPtr(void)
43    {
44        return ms_Singleton;
45    }
46    ResourceGroupManager& ResourceGroupManager::getSingleton(void)
47    { 
48        assert( ms_Singleton );  return ( *ms_Singleton ); 
49    }
50        String ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME = "General";
51        String ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME = "Internal";
52        String ResourceGroupManager::BOOTSTRAP_RESOURCE_GROUP_NAME = "Bootstrap";
53        String ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME = "Autodetect";
54        // A reference count of 3 means that only RGM and RM have references
55        // RGM has one (this one) and RM has 2 (by name and by handle)
56        size_t ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS = 3;
57    //-----------------------------------------------------------------------
58    //-----------------------------------------------------------------------
59    ResourceGroupManager::ResourceGroupManager()
60        : mCurrentGroup(0)
61    {
62        // Create the 'General' group
63        createResourceGroup(DEFAULT_RESOURCE_GROUP_NAME);
64        // Create the 'Internal' group
65        createResourceGroup(INTERNAL_RESOURCE_GROUP_NAME);
66                // Create the 'Autodetect' group (only used for temp storage)
67                createResourceGroup(AUTODETECT_RESOURCE_GROUP_NAME);
68        // default world group to the default group
69        mWorldGroupName = DEFAULT_RESOURCE_GROUP_NAME;
70    }
71    //-----------------------------------------------------------------------
72    ResourceGroupManager::~ResourceGroupManager()
73    {
74        // delete all resource groups
75        ResourceGroupMap::iterator i, iend;
76        iend = mResourceGroupMap.end();
77        for (i = mResourceGroupMap.begin(); i != iend; ++i)
78        {
79                        deleteGroup(i->second);
80        }
81        mResourceGroupMap.clear();
82    }
83    //-----------------------------------------------------------------------
84    void ResourceGroupManager::createResourceGroup(const String& name)
85    {
86                OGRE_LOCK_AUTO_MUTEX
87
88                LogManager::getSingleton().logMessage("Creating resource group " + name);
89        if (getResourceGroup(name))
90        {
91            OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, 
92                "Resource group with name '" + name + "' already exists!", 
93                "ResourceGroupManager::createResourceGroup");
94        }
95        ResourceGroup* grp = new ResourceGroup();
96                grp->initialised = false;
97        grp->name = name;
98        grp->worldGeometrySceneManager = 0;
99        mResourceGroupMap.insert(
100            ResourceGroupMap::value_type(name, grp));
101    }
102        //-----------------------------------------------------------------------
103        void ResourceGroupManager::initialiseResourceGroup(const String& name)
104        {
105                OGRE_LOCK_AUTO_MUTEX
106                LogManager::getSingleton().logMessage("Initialising resource group " + name);
107                ResourceGroup* grp = getResourceGroup(name);
108                if (!grp)
109                {
110                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
111                                "Cannot find a group named " + name, 
112                                "ResourceGroupManager::parseResourceGroupScripts");
113                }
114                OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
115
116                if (!grp->initialised)
117                {
118                        // Set current group
119                        parseResourceGroupScripts(grp);
120                        mCurrentGroup = grp;
121                        createDeclaredResources(grp);
122                        grp->initialised = true;
123
124                        // Reset current group
125                        mCurrentGroup = 0;
126                }
127        }
128        //-----------------------------------------------------------------------
129        void ResourceGroupManager::initialiseAllResourceGroups(void)
130        {
131                OGRE_LOCK_AUTO_MUTEX
132
133                // Intialise all declared resource groups
134                ResourceGroupMap::iterator i, iend;
135                iend = mResourceGroupMap.end();
136                for (i = mResourceGroupMap.begin(); i != iend; ++i)
137                {
138                        ResourceGroup* grp = i->second;
139                        OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
140                        if (!grp->initialised)
141                        {
142                                // Set current group
143                                mCurrentGroup = grp;
144                                parseResourceGroupScripts(grp);
145                                createDeclaredResources(grp);
146                                grp->initialised = true;
147                                // Reset current group
148                                mCurrentGroup = 0;
149                        }
150                }
151        }
152    //-----------------------------------------------------------------------
153    void ResourceGroupManager::loadResourceGroup(const String& name, 
154                bool loadMainResources, bool loadWorldGeom)
155    {
156                // Can only bulk-load one group at a time (reasonable limitation I think)
157                OGRE_LOCK_AUTO_MUTEX
158
159                StringUtil::StrStreamType str;
160                str << "Loading resource group '" << name << "' - Resources: "
161                        << loadMainResources << " World Geometry: " << loadWorldGeom;
162                LogManager::getSingleton().logMessage(str.str());
163                // load all created resources
164                ResourceGroup* grp = getResourceGroup(name);
165                if (!grp)
166                {
167                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
168                                "Cannot find a group named " + name, 
169                                "ResourceGroupManager::loadResourceGroup");
170                }
171
172                OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
173                // Set current group
174                mCurrentGroup = grp;
175
176                // Count up resources for starting event
177                ResourceGroup::LoadResourceOrderMap::iterator oi;
178                size_t resourceCount = 0;
179                if (loadMainResources)
180                {
181                        for (oi = grp->loadResourceOrderMap.begin(); oi != grp->loadResourceOrderMap.end(); ++oi)
182                        {
183                                resourceCount += oi->second->size();
184                        }
185                }
186        // Estimate world geometry size
187        if (grp->worldGeometrySceneManager && loadWorldGeom)
188        {
189            resourceCount += 
190                                grp->worldGeometrySceneManager->estimateWorldGeometry(
191                                        grp->worldGeometry);
192        }
193
194                fireResourceGroupLoadStarted(name, resourceCount);
195
196                // Now load for real
197                if (loadMainResources)
198                {
199                        for (oi = grp->loadResourceOrderMap.begin(); 
200                                oi != grp->loadResourceOrderMap.end(); ++oi)
201                        {
202                                size_t n = 0;
203                                for (LoadUnloadResourceList::iterator l = oi->second->begin();
204                                        l != oi->second->end(); ++l, ++n)
205                                {
206                                        ResourcePtr res = *l;
207
208                                        // Fire resource events no matter whether resource is already
209                                        // loaded or not. This ensures that the number of callbacks
210                                        // matches the number originally estimated, which is important
211                                        // for progress bars.
212                                        fireResourceStarted(res);
213
214                                        // If loading one of these resources cascade-loads another resource,
215                                        // the list will get longer! But these should be loaded immediately
216                                        // Call load regardless, already loaded resources will be skipped
217                                        res->load();
218
219                                        // Did the resource change group? if so, our iterator will have
220                                        // been invalidated
221                                        if (res->getGroup() != name)
222                                        {
223                                                l = oi->second->begin();
224                                                std::advance(l, n);
225                                        }
226
227                                        fireResourceEnded();
228                                }
229                        }
230                }
231        // Load World Geometry
232        if (grp->worldGeometrySceneManager && loadWorldGeom)
233        {
234            grp->worldGeometrySceneManager->setWorldGeometry(
235                grp->worldGeometry);
236        }
237                fireResourceGroupLoadEnded(name);
238
239                // reset current group
240                mCurrentGroup = 0;
241               
242                LogManager::getSingleton().logMessage("Finished loading resource group " + name);
243    }
244    //-----------------------------------------------------------------------
245    void ResourceGroupManager::unloadResourceGroup(const String& name, bool reloadableOnly)
246    {
247                // Can only bulk-unload one group at a time (reasonable limitation I think)
248                OGRE_LOCK_AUTO_MUTEX
249
250                LogManager::getSingleton().logMessage("Unloading resource group " + name);
251                ResourceGroup* grp = getResourceGroup(name);
252                if (!grp)
253                {
254                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
255                                "Cannot find a group named " + name, 
256                                "ResourceGroupManager::unloadResourceGroup");
257                }
258                // Set current group
259                mCurrentGroup = grp;
260                OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
261
262                // Count up resources for starting event
263                ResourceGroup::LoadResourceOrderMap::reverse_iterator oi;
264                // unload in reverse order
265                for (oi = grp->loadResourceOrderMap.rbegin(); oi != grp->loadResourceOrderMap.rend(); ++oi)
266                {
267                        for (LoadUnloadResourceList::iterator l = oi->second->begin();
268                                l != oi->second->end(); ++l)
269                        {
270                                Resource* resource = l->get();
271                                if (!reloadableOnly || resource->isReloadable())
272                                {
273                                        resource->unload();
274                                }
275                        }
276                }
277
278                // reset current group
279                mCurrentGroup = 0;
280                LogManager::getSingleton().logMessage("Finished unloading resource group " + name);
281    }
282        //-----------------------------------------------------------------------
283        void ResourceGroupManager::unloadUnreferencedResourcesInGroup(
284                const String& name, bool reloadableOnly )
285        {
286                // Can only bulk-unload one group at a time (reasonable limitation I think)
287                OGRE_LOCK_AUTO_MUTEX
288
289                LogManager::getSingleton().logMessage(
290                        "Unloading unused resources in resource group " + name);
291                ResourceGroup* grp = getResourceGroup(name);
292                if (!grp)
293                {
294                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
295                                "Cannot find a group named " + name, 
296                                "ResourceGroupManager::unloadUnreferencedResourcesInGroup");
297                }
298                // Set current group
299                mCurrentGroup = grp;
300
301                ResourceGroup::LoadResourceOrderMap::reverse_iterator oi;
302                // unload in reverse order
303                for (oi = grp->loadResourceOrderMap.rbegin(); oi != grp->loadResourceOrderMap.rend(); ++oi)
304                {
305                        for (LoadUnloadResourceList::iterator l = oi->second->begin();
306                                l != oi->second->end(); ++l)
307                        {
308                                // A use count of 3 means that only RGM and RM have references
309                                // RGM has one (this one) and RM has 2 (by name and by handle)
310                                if (l->useCount() == RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS)
311                                {
312                                        Resource* resource = l->get();
313                                        if (!reloadableOnly || resource->isReloadable())
314                                        {
315                                                resource->unload();
316                                        }
317                                }
318                        }
319                }
320
321                // reset current group
322                mCurrentGroup = 0;
323                LogManager::getSingleton().logMessage(
324                        "Finished unloading unused resources in resource group " + name);
325        }
326        //-----------------------------------------------------------------------
327        void ResourceGroupManager::clearResourceGroup(const String& name)
328        {
329                // Can only bulk-clear one group at a time (reasonable limitation I think)
330                OGRE_LOCK_AUTO_MUTEX
331
332                        LogManager::getSingleton().logMessage("Clearing resource group " + name);
333                ResourceGroup* grp = getResourceGroup(name);
334                if (!grp)
335                {
336                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
337                                "Cannot find a group named " + name, 
338                                "ResourceGroupManager::clearResourceGroup");
339                }
340                // set current group
341                mCurrentGroup = grp;
342                dropGroupContents(grp);
343                // clear initialised flag
344                grp->initialised = false;
345                // reset current group
346                mCurrentGroup = 0;
347                LogManager::getSingleton().logMessage("Finished clearing resource group " + name);
348        }
349    //-----------------------------------------------------------------------
350    void ResourceGroupManager::destroyResourceGroup(const String& name)
351    {
352                // Can only bulk-destroy one group at a time (reasonable limitation I think)
353                OGRE_LOCK_AUTO_MUTEX
354
355                LogManager::getSingleton().logMessage("Destroying resource group " + name);
356                ResourceGroup* grp = getResourceGroup(name);
357                if (!grp)
358                {
359                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
360                                "Cannot find a group named " + name, 
361                                "ResourceGroupManager::destroyResourceGroup");
362                }
363                // set current group
364                mCurrentGroup = grp;
365        unloadResourceGroup(name, false); // will throw an exception if name not valid
366                dropGroupContents(grp);
367                deleteGroup(grp);
368        mResourceGroupMap.erase(mResourceGroupMap.find(name));
369                // reset current group
370                mCurrentGroup = 0;
371    }
372    //-----------------------------------------------------------------------
373    void ResourceGroupManager::addResourceLocation(const String& name, 
374        const String& locType, const String& resGroup, bool recursive)
375    {
376        ResourceGroup* grp = getResourceGroup(resGroup);
377        if (!grp)
378        {
379            createResourceGroup(resGroup);
380            grp = getResourceGroup(resGroup);
381        }
382
383                OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
384
385        // Get archive
386        Archive* pArch = ArchiveManager::getSingleton().load( name, locType );
387        // Add to location list
388                ResourceLocation* loc = new ResourceLocation();
389                loc->archive = pArch;
390                loc->recursive = recursive;
391        grp->locationList.push_back(loc);
392        // Index resources
393        StringVectorPtr vec = pArch->find("*", recursive);
394        for( StringVector::iterator it = vec->begin(); it != vec->end(); ++it )
395        {
396                        // Index under full name, case sensitive
397            grp->resourceIndexCaseSensitive[(*it)] = pArch;
398            if (!pArch->isCaseSensitive())
399            {
400                    // Index under lower case name too for case insensitive match
401                String indexName = (*it);
402                StringUtil::toLowerCase(indexName);
403                    grp->resourceIndexCaseInsensitive[indexName] = pArch;
404            }
405        }
406               
407                StringUtil::StrStreamType msg;
408                msg << "Added resource location '" << name << "' of type '" << locType
409                        << "' to resource group '" << resGroup << "'";
410                if (recursive)
411                        msg << " with recursive option";
412                LogManager::getSingleton().logMessage(msg.str());
413
414    }
415    //-----------------------------------------------------------------------
416    void ResourceGroupManager::removeResourceLocation(const String& name, 
417        const String& resGroup)
418    {
419                ResourceGroup* grp = getResourceGroup(resGroup);
420                if (!grp)
421        {
422            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
423                "Cannot locate a resource group called '" + resGroup + "'", 
424                "ResourceGroupManager::addResourceLocation");
425        }
426
427                OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
428
429        // Remove from location list
430                LocationList::iterator li, liend;
431                liend = grp->locationList.end();
432                for (li = grp->locationList.begin(); li != liend; ++li)
433                {
434                        Archive* pArch = (*li)->archive;
435                        if (pArch->getName() == name)
436                        {
437                                // Delete indexes
438                                ResourceLocationIndex::iterator rit, ritend;
439                                ritend = grp->resourceIndexCaseInsensitive.end();
440                                for (rit = grp->resourceIndexCaseInsensitive.begin(); rit != ritend;)
441                                {
442                                        if (rit->second == pArch)
443                                        {
444                                                ResourceLocationIndex::iterator del = rit++;
445                                                grp->resourceIndexCaseInsensitive.erase(del);
446                                        }
447                                        else
448                                        {
449                                                ++rit;
450                                        }
451                                }
452                ritend = grp->resourceIndexCaseSensitive.end();
453                for (rit = grp->resourceIndexCaseSensitive.begin(); rit != ritend;)
454                {
455                    if (rit->second == pArch)
456                    {
457                        ResourceLocationIndex::iterator del = rit++;
458                        grp->resourceIndexCaseSensitive.erase(del);
459                    }
460                    else
461                    {
462                        ++rit;
463                    }
464                }
465                                // Erase list entry
466                                delete *li;
467                                grp->locationList.erase(li);
468                                break;
469                        }
470
471                }
472
473                LogManager::getSingleton().logMessage("Removed resource location " + name);
474
475
476    }
477    //-----------------------------------------------------------------------
478    void ResourceGroupManager::declareResource(const String& name, 
479        const String& resourceType, const String& groupName,
480                const NameValuePairList& loadParameters)
481    {
482        declareResource(name, resourceType, groupName, 0, loadParameters);
483    }
484    //-----------------------------------------------------------------------
485    void ResourceGroupManager::declareResource(const String& name, 
486        const String& resourceType, const String& groupName,
487        ManualResourceLoader* loader,
488        const NameValuePairList& loadParameters)
489    {
490                ResourceGroup* grp = getResourceGroup(groupName);
491                if (!grp)
492                {
493                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
494                                "Cannot find a group named " + groupName, 
495                                "ResourceGroupManager::declareResource");
496                }
497               
498                OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
499
500                ResourceDeclaration dcl;
501                dcl.loader = loader;
502                dcl.parameters = loadParameters;
503                dcl.resourceName = name;
504                dcl.resourceType = resourceType;
505                grp->resourceDeclarations.push_back(dcl);
506    }
507    //-----------------------------------------------------------------------
508    void ResourceGroupManager::undeclareResource(const String& name, 
509                const String& groupName)
510    {
511                ResourceGroup* grp = getResourceGroup(groupName);
512                if (!grp)
513                {
514                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
515                                "Cannot find a group named " + groupName, 
516                                "ResourceGroupManager::undeclareResource");
517                }
518
519                OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
520
521                for (ResourceDeclarationList::iterator i = grp->resourceDeclarations.begin();
522                        i != grp->resourceDeclarations.end(); ++i)
523                {
524                        if (i->resourceName == name)
525                        {
526                                grp->resourceDeclarations.erase(i);
527                                break;
528                        }
529                }
530    }
531    //-----------------------------------------------------------------------
532    DataStreamPtr ResourceGroupManager::openResource(
533        const String& resourceName, const String& groupName, 
534                bool searchGroupsIfNotFound, Resource* resourceBeingLoaded)
535    {
536                OGRE_LOCK_AUTO_MUTEX
537                // Try to find in resource index first
538                ResourceGroup* grp = getResourceGroup(groupName);
539                if (!grp)
540                {
541                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
542                                "Cannot locate a resource group called '" + groupName + 
543                                "' for resource '" + resourceName + "'" , 
544                                "ResourceGroupManager::openResource");
545                }
546
547                OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
548
549                Archive* pArch = 0;
550                ResourceLocationIndex::iterator rit = grp->resourceIndexCaseSensitive.find(resourceName);
551                if (rit != grp->resourceIndexCaseSensitive.end())
552                {
553                        // Found in the index
554                        pArch = rit->second;
555                        return pArch->open(resourceName);
556                }
557        else 
558        {
559            // try case insensitive
560            String lcResourceName = resourceName;
561            StringUtil::toLowerCase(lcResourceName);
562            rit = grp->resourceIndexCaseInsensitive.find(lcResourceName);
563            if (rit != grp->resourceIndexCaseInsensitive.end())
564            {
565                // Found in the index
566                pArch = rit->second;
567                return pArch->open(resourceName);
568            }
569                    else
570                    {
571                            // Search the hard way
572                            LocationList::iterator li, liend;
573                            liend = grp->locationList.end();
574                            for (li = grp->locationList.begin(); li != liend; ++li)
575                            {
576                                    Archive* arch = (*li)->archive;
577                    if (arch->exists(resourceName))
578                                    {
579                        DataStreamPtr ptr = arch->open(resourceName);
580                                            return ptr;
581                                    }
582                            }
583                    }
584        }
585
586               
587                // Not found
588                if (searchGroupsIfNotFound)
589                {
590                        ResourceGroup* grp = findGroupContainingResourceImpl(resourceName); 
591                        if (grp)
592                        {
593                                if (resourceBeingLoaded)
594                                {
595                                        resourceBeingLoaded->changeGroupOwnership(grp->name);
596                                }
597                                return openResource(resourceName, grp->name, false);
598                        }
599                        else
600                        {
601                                OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, 
602                                        "Cannot locate resource " + resourceName + 
603                                        " in resource group " + groupName + " or any other group.", 
604                                        "ResourceGroupManager::openResource");
605                        }
606                }
607                OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, "Cannot locate resource " + 
608                        resourceName + " in resource group " + groupName + ".", 
609                        "ResourceGroupManager::openResource");
610
611                // Keep compiler happy
612                return DataStreamPtr();
613
614
615    }
616    //-----------------------------------------------------------------------
617    DataStreamListPtr ResourceGroupManager::openResources(
618        const String& pattern, const String& groupName)
619    {
620                OGRE_LOCK_AUTO_MUTEX
621                ResourceGroup* grp = getResourceGroup(groupName);
622                if (!grp)
623                {
624                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
625                                "Cannot locate a resource group called '" + groupName + "'", 
626                                "ResourceGroupManager::openResources");
627                }
628
629                OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
630
631                // Iterate through all the archives and build up a combined list of
632                // streams
633                DataStreamListPtr ret = DataStreamListPtr(new DataStreamList());
634
635                LocationList::iterator li, liend;
636                liend = grp->locationList.end();
637                for (li = grp->locationList.begin(); li != liend; ++li)
638                {
639                        Archive* arch = (*li)->archive;
640                        // Find all the names based on whether this archive is recursive
641                        StringVectorPtr names = arch->find(pattern, (*li)->recursive);
642
643                        // Iterate over the names and load a stream for each
644                        for (StringVector::iterator ni = names->begin(); ni != names->end(); ++ni)
645                        {
646                                DataStreamPtr ptr = arch->open(*ni);
647                                if (!ptr.isNull())
648                                {
649                                        ret->push_back(ptr);
650                                }
651                        }
652                }
653                return ret;
654               
655    }
656    //-----------------------------------------------------------------------
657    void ResourceGroupManager::addResourceGroupListener(ResourceGroupListener* l)
658    {
659                OGRE_LOCK_AUTO_MUTEX
660
661                mResourceGroupListenerList.push_back(l);
662    }
663    //-----------------------------------------------------------------------
664    void ResourceGroupManager::removeResourceGroupListener(ResourceGroupListener* l)
665    {
666                OGRE_LOCK_AUTO_MUTEX
667
668                for (ResourceGroupListenerList::iterator i = mResourceGroupListenerList.begin();
669                        i != mResourceGroupListenerList.end(); ++i)
670                {
671                        if (*i == l)
672                        {
673                                mResourceGroupListenerList.erase(i);
674                                break;
675                        }
676                }
677    }
678    //-----------------------------------------------------------------------
679    void ResourceGroupManager::_registerResourceManager(
680        const String& resourceType, ResourceManager* rm)
681    {
682                OGRE_LOCK_AUTO_MUTEX
683
684                LogManager::getSingleton().logMessage(
685                        "Registering ResourceManager for type " + resourceType);
686                mResourceManagerMap[resourceType] = rm;
687    }
688    //-----------------------------------------------------------------------
689    void ResourceGroupManager::_unregisterResourceManager(
690        const String& resourceType)
691    {
692                OGRE_LOCK_AUTO_MUTEX
693
694                LogManager::getSingleton().logMessage(
695                        "Unregistering ResourceManager for type " + resourceType);
696               
697                ResourceManagerMap::iterator i = mResourceManagerMap.find(resourceType);
698                if (i != mResourceManagerMap.end())
699                {
700                        mResourceManagerMap.erase(i);
701                }
702    }
703        //-----------------------------------------------------------------------
704    void ResourceGroupManager::_registerScriptLoader(ScriptLoader* su)
705        {
706                OGRE_LOCK_AUTO_MUTEX
707
708                mScriptLoaderOrderMap.insert(
709                        ScriptLoaderOrderMap::value_type(su->getLoadingOrder(), su));
710        }
711        //-----------------------------------------------------------------------
712    void ResourceGroupManager::_unregisterScriptLoader(ScriptLoader* su)
713        {
714                OGRE_LOCK_AUTO_MUTEX
715
716                Real order = su->getLoadingOrder();
717                ScriptLoaderOrderMap::iterator oi = mScriptLoaderOrderMap.find(order);
718                while (oi != mScriptLoaderOrderMap.end() && oi->first == order)
719                {
720                        if (oi->second == su)
721                        {
722                                // erase does not invalidate on multimap, except current
723                                ScriptLoaderOrderMap::iterator del = oi++;
724                                mScriptLoaderOrderMap.erase(del);
725                        }
726                        else
727                        {
728                                ++oi;
729                        }
730                }
731        }
732        //-----------------------------------------------------------------------
733        void ResourceGroupManager::parseResourceGroupScripts(ResourceGroup* grp)
734        {
735
736                LogManager::getSingleton().logMessage(
737                        "Parsing scripts for resource group " + grp->name);
738
739                // Count up the number of scripts we have to parse
740        typedef std::list<FileInfoListPtr> FileListList;
741        typedef SharedPtr<FileListList> FileListListPtr;
742        typedef std::pair<ScriptLoader*, FileListListPtr> LoaderFileListPair;
743        typedef std::list<LoaderFileListPair> ScriptLoaderFileList;
744        ScriptLoaderFileList scriptLoaderFileList;
745                size_t scriptCount = 0;
746                // Iterate over script users in loading order and get streams
747                ScriptLoaderOrderMap::iterator oi;
748                for (oi = mScriptLoaderOrderMap.begin();
749                        oi != mScriptLoaderOrderMap.end(); ++oi)
750                {
751                        ScriptLoader* su = oi->second;
752            FileListListPtr fileListList(new FileListList);
753
754                        // Get all the patterns and search them
755                        const StringVector& patterns = su->getScriptPatterns();
756                        for (StringVector::const_iterator p = patterns.begin(); p != patterns.end(); ++p)
757                        {
758                                FileInfoListPtr fileList = findResourceFileInfo(grp->name, *p);
759                                scriptCount += fileList->size();
760                                fileListList->push_back(fileList);
761                        }
762            scriptLoaderFileList.push_back(
763                LoaderFileListPair(su, fileListList));
764                }
765                // Fire scripting event
766                fireResourceGroupScriptingStarted(grp->name, scriptCount);
767
768                // Iterate over scripts and parse
769                // Note we respect original ordering
770        for (ScriptLoaderFileList::iterator slfli = scriptLoaderFileList.begin();
771            slfli != scriptLoaderFileList.end(); ++slfli)
772        {
773                        ScriptLoader* su = slfli->first;
774            // Iterate over each list
775            for (FileListList::iterator flli = slfli->second->begin(); flli != slfli->second->end(); ++flli)
776            {
777                            // Iterate over each item in the list
778                            for (FileInfoList::iterator fii = (*flli)->begin(); fii != (*flli)->end(); ++fii)
779                            {
780                    LogManager::getSingleton().logMessage(
781                        "Parsing script " + fii->filename);
782                    fireScriptStarted(fii->filename);
783                    {
784                        DataStreamPtr stream = fii->archive->open(fii->filename);
785                        if (!stream.isNull())
786                        {
787                            su->parseScript(stream, grp->name);
788                        }
789                    }
790                                    fireScriptEnded(fii->filename);
791                            }
792            }
793                }
794
795                fireResourceGroupScriptingEnded(grp->name);
796                LogManager::getSingleton().logMessage(
797                        "Finished parsing scripts for resource group " + grp->name);
798        }
799        //-----------------------------------------------------------------------
800        void ResourceGroupManager::createDeclaredResources(ResourceGroup* grp)
801        {
802
803                for (ResourceDeclarationList::iterator i = grp->resourceDeclarations.begin();
804                        i != grp->resourceDeclarations.end(); ++i)
805                {
806                        ResourceDeclaration& dcl = *i;
807                        // Retrieve the appropriate manager
808                        ResourceManager* mgr = _getResourceManager(dcl.resourceType);
809                        // Create the resource
810                        ResourcePtr res = mgr->create(dcl.resourceName, grp->name,
811                dcl.loader != 0, dcl.loader, &dcl.parameters);
812                        // Add resource to load list
813                        ResourceGroup::LoadResourceOrderMap::iterator li = 
814                                grp->loadResourceOrderMap.find(mgr->getLoadingOrder());
815                        LoadUnloadResourceList* loadList;
816                        if (li == grp->loadResourceOrderMap.end())
817                        {
818                                loadList = new LoadUnloadResourceList();
819                                grp->loadResourceOrderMap[mgr->getLoadingOrder()] = loadList;
820                        }
821                        else
822                        {
823                                loadList = li->second;
824                        }
825                        loadList->push_back(res);
826
827                }
828
829        }
830    //-----------------------------------------------------------------------
831        void ResourceGroupManager::_notifyResourceCreated(ResourcePtr& res)
832        {
833                if (mCurrentGroup && res->getGroup() == mCurrentGroup->name)
834                {
835                        // Use current group (batch loading)
836                        addCreatedResource(res, *mCurrentGroup);
837                }
838                else
839                {
840                        // Find group
841                        ResourceGroup* grp = getResourceGroup(res->getGroup());
842                        if (grp)
843                        {
844                                addCreatedResource(res, *grp);
845                        }
846                }
847        }
848        //-----------------------------------------------------------------------
849        void ResourceGroupManager::_notifyResourceRemoved(ResourcePtr& res)
850        {
851                if (mCurrentGroup)
852                {
853                        // Do nothing - we're batch unloading so list will be cleared
854                }
855                else
856                {
857                        // Find group
858                        ResourceGroup* grp = getResourceGroup(res->getGroup());
859                        if (grp)
860                        {
861                                OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
862                                ResourceGroup::LoadResourceOrderMap::iterator i = 
863                                        grp->loadResourceOrderMap.find(
864                                                res->getCreator()->getLoadingOrder());
865                                if (i != grp->loadResourceOrderMap.end())
866                                {
867                                        // Iterate over the resource list and remove
868                                        LoadUnloadResourceList* resList = i->second;
869                                        for (LoadUnloadResourceList::iterator l = resList->begin();
870                                                l != resList->end(); ++ l)
871                                        {
872                                                if ((*l).getPointer() == res.getPointer())
873                                                {
874                                                        // this is the one
875                                                        resList->erase(l);
876                                                        break;
877                                                }
878                                        }
879                                }
880                        }
881                }
882        }
883        //-----------------------------------------------------------------------
884        void ResourceGroupManager::_notifyResourceGroupChanged(const String& oldGroup, 
885                Resource* res)
886        {
887                OGRE_LOCK_AUTO_MUTEX
888       
889                // New group
890                ResourceGroup* newGrp = getResourceGroup(res->getGroup());
891                // find old entry
892                ResourceGroupMap::iterator grpi = mResourceGroupMap.find(oldGroup);
893
894                assert(grpi != mResourceGroupMap.end());
895                ResourceGroup* grp = grpi->second;
896                Real order = res->getCreator()->getLoadingOrder();
897                ResourceGroup::LoadResourceOrderMap::iterator i = 
898                        grp->loadResourceOrderMap.find(order);
899                assert(i != grp->loadResourceOrderMap.end());
900                LoadUnloadResourceList* loadList = i->second;
901                for (LoadUnloadResourceList::iterator l = loadList->begin(); 
902                        l != loadList->end(); ++l)
903                {
904                        if ((*l).getPointer() == res)
905                        {
906                                addCreatedResource(*l, *newGrp);
907                                loadList->erase(l);
908                                break;
909                        }
910                }
911
912        }
913        //-----------------------------------------------------------------------
914        void ResourceGroupManager::_notifyAllResourcesRemoved(ResourceManager* manager)
915        {
916                OGRE_LOCK_AUTO_MUTEX
917
918                // Iterate over all groups
919                for (ResourceGroupMap::iterator grpi = mResourceGroupMap.begin();
920                        grpi != mResourceGroupMap.end(); ++grpi)
921                {
922                        OGRE_LOCK_MUTEX(grpi->second->OGRE_AUTO_MUTEX_NAME)
923                        // Iterate over all priorities
924                        for (ResourceGroup::LoadResourceOrderMap::iterator oi = grpi->second->loadResourceOrderMap.begin();
925                                oi != grpi->second->loadResourceOrderMap.end(); ++oi)
926                        {
927                                // Iterate over all resources
928                                for (LoadUnloadResourceList::iterator l = oi->second->begin();
929                                        l != oi->second->end(); )
930                                {
931                                        if ((*l)->getCreator() == manager)
932                                        {
933                                                // Increment first since iterator will be invalidated
934                                                LoadUnloadResourceList::iterator del = l++;
935                                                oi->second->erase(del);
936                                        }
937                                        else
938                                        {
939                                                ++l;
940                                        }
941                                }
942                        }
943
944                }
945        }
946        //-----------------------------------------------------------------------
947        void ResourceGroupManager::addCreatedResource(ResourcePtr& res, ResourceGroup& grp)
948        {
949                OGRE_LOCK_MUTEX(grp.OGRE_AUTO_MUTEX_NAME)
950                Real order = res->getCreator()->getLoadingOrder();
951
952                ResourceGroup::LoadResourceOrderMap::iterator i = grp.loadResourceOrderMap.find(order);
953                LoadUnloadResourceList* loadList;
954                if (i == grp.loadResourceOrderMap.end())
955                {
956                        loadList = new LoadUnloadResourceList();
957                        grp.loadResourceOrderMap[order] = loadList;
958                }
959                else
960                {
961                        loadList = i->second;
962                }
963                loadList->push_back(res);
964        }
965        //-----------------------------------------------------------------------
966        ResourceGroupManager::ResourceGroup* ResourceGroupManager::getResourceGroup(const String& name)
967        {
968                OGRE_LOCK_AUTO_MUTEX
969
970                ResourceGroupMap::iterator i = mResourceGroupMap.find(name);
971                if (i != mResourceGroupMap.end())
972                {
973                        return i->second;
974                }
975                return 0;
976
977        }
978    //-----------------------------------------------------------------------
979    ResourceManager* ResourceGroupManager::_getResourceManager(const String& resourceType) 
980    {
981                OGRE_LOCK_AUTO_MUTEX
982
983        ResourceManagerMap::iterator i = mResourceManagerMap.find(resourceType);
984        if (i == mResourceManagerMap.end())
985        {
986            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
987                "Cannot locate resource manager for resource type '" +
988                resourceType + "'", "ResourceGroupManager::_getResourceManager");
989        }
990        return i->second;
991
992    }
993        //-----------------------------------------------------------------------
994        void ResourceGroupManager::dropGroupContents(ResourceGroup* grp)
995        {
996                OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME)
997
998                bool groupSet = false;
999                if (!mCurrentGroup)
1000                {
1001                        // Set current group to indicate ignoring of notifications
1002                        mCurrentGroup = grp;
1003                        groupSet = true;
1004                }
1005                // delete all the load list entries
1006                ResourceGroup::LoadResourceOrderMap::iterator j, jend;
1007                jend = grp->loadResourceOrderMap.end();
1008                for (j = grp->loadResourceOrderMap.begin(); j != jend; ++j)
1009                {
1010                        // Iterate over resources
1011                        for (LoadUnloadResourceList::iterator k = j->second->begin();
1012                                k != j->second->end(); ++k)
1013                        {
1014                                (*k)->getCreator()->remove((*k)->getHandle());
1015                        }
1016                        delete j->second;
1017                }
1018        grp->loadResourceOrderMap.clear();
1019
1020                if (groupSet)
1021                {
1022                        mCurrentGroup = 0;
1023                }
1024        }
1025        //-----------------------------------------------------------------------
1026        void ResourceGroupManager::deleteGroup(ResourceGroup* grp)
1027        {
1028        {
1029                    OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME)
1030                    // delete all the load list entries
1031                    ResourceGroup::LoadResourceOrderMap::iterator j, jend;
1032                    jend = grp->loadResourceOrderMap.end();
1033                    for (j = grp->loadResourceOrderMap.begin(); j != jend; ++j)
1034                    {
1035                            // Don't iterate over resources to drop with ResourceManager
1036                            // Assume this is being done anyway since this is a shutdown method
1037                            delete j->second;
1038                    }
1039                    // Drop location list
1040                    for (LocationList::iterator ll = grp->locationList.begin();
1041                            ll != grp->locationList.end(); ++ll)
1042                    {
1043                            delete *ll;
1044                    }
1045        }
1046
1047                // delete ResourceGroup
1048                delete grp;
1049        }
1050        //-----------------------------------------------------------------------
1051        void ResourceGroupManager::fireResourceGroupScriptingStarted(const String& groupName, size_t scriptCount)
1052        {
1053                OGRE_LOCK_AUTO_MUTEX
1054                for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin();
1055                        l != mResourceGroupListenerList.end(); ++l)
1056                {
1057                        (*l)->resourceGroupScriptingStarted(groupName, scriptCount);
1058                }
1059        }
1060        //-----------------------------------------------------------------------
1061        void ResourceGroupManager::fireScriptStarted(const String& scriptName)
1062        {
1063                OGRE_LOCK_AUTO_MUTEX
1064                for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin();
1065                        l != mResourceGroupListenerList.end(); ++l)
1066                {
1067                        (*l)->scriptParseStarted(scriptName);
1068                }
1069        }
1070    //-----------------------------------------------------------------------
1071    void ResourceGroupManager::fireScriptEnded(const String& scriptName)
1072    {
1073        OGRE_LOCK_AUTO_MUTEX
1074            for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin();
1075                l != mResourceGroupListenerList.end(); ++l)
1076            {
1077                (*l)->scriptParseEnded(scriptName);
1078            }
1079    }
1080        //-----------------------------------------------------------------------
1081        void ResourceGroupManager::fireResourceGroupScriptingEnded(const String& groupName)
1082        {
1083                OGRE_LOCK_AUTO_MUTEX
1084                for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin();
1085                        l != mResourceGroupListenerList.end(); ++l)
1086                {
1087                        (*l)->resourceGroupScriptingEnded(groupName);
1088                }
1089        }
1090        //-----------------------------------------------------------------------
1091        void ResourceGroupManager::fireResourceGroupLoadStarted(const String& groupName, size_t resourceCount)
1092        {
1093                OGRE_LOCK_AUTO_MUTEX
1094                for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin();
1095                        l != mResourceGroupListenerList.end(); ++l)
1096                {
1097                        (*l)->resourceGroupLoadStarted(groupName, resourceCount);
1098                }
1099        }
1100        //-----------------------------------------------------------------------
1101        void ResourceGroupManager::fireResourceStarted(const ResourcePtr& resource)
1102        {
1103                OGRE_LOCK_AUTO_MUTEX
1104                for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin();
1105                        l != mResourceGroupListenerList.end(); ++l)
1106                {
1107                        (*l)->resourceLoadStarted(resource);
1108                }
1109        }
1110    //-----------------------------------------------------------------------
1111    void ResourceGroupManager::fireResourceEnded(void)
1112    {
1113        OGRE_LOCK_AUTO_MUTEX
1114            for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin();
1115                l != mResourceGroupListenerList.end(); ++l)
1116            {
1117                (*l)->resourceLoadEnded();
1118            }
1119    }
1120    //-----------------------------------------------------------------------
1121    void ResourceGroupManager::_notifyWorldGeometryStageStarted(const String& desc)
1122    {
1123                OGRE_LOCK_AUTO_MUTEX
1124                for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin();
1125                        l != mResourceGroupListenerList.end(); ++l)
1126                {
1127                        (*l)->worldGeometryStageStarted(desc);
1128                }
1129    }
1130    //-----------------------------------------------------------------------
1131    void ResourceGroupManager::_notifyWorldGeometryStageEnded(void)
1132    {
1133        OGRE_LOCK_AUTO_MUTEX
1134            for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin();
1135                l != mResourceGroupListenerList.end(); ++l)
1136            {
1137                (*l)->worldGeometryStageEnded();
1138            }
1139    }
1140        //-----------------------------------------------------------------------
1141        void ResourceGroupManager::fireResourceGroupLoadEnded(const String& groupName)
1142        {
1143                OGRE_LOCK_AUTO_MUTEX
1144                for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin();
1145                        l != mResourceGroupListenerList.end(); ++l)
1146                {
1147                        (*l)->resourceGroupLoadEnded(groupName);
1148                }
1149        }
1150        //-----------------------------------------------------------------------
1151    void ResourceGroupManager::shutdownAll(void)
1152    {
1153        OGRE_LOCK_AUTO_MUTEX
1154
1155        ResourceManagerMap::iterator i, iend;
1156        iend = mResourceManagerMap.end();
1157        for (i = mResourceManagerMap.begin(); i != iend; ++i)
1158        {
1159            i->second->removeAll();
1160        }
1161    }
1162    //-----------------------------------------------------------------------
1163    StringVectorPtr ResourceGroupManager::listResourceNames(const String& groupName, bool dirs)
1164    {
1165        OGRE_LOCK_AUTO_MUTEX
1166        StringVectorPtr vec(new StringVector());
1167
1168        // Try to find in resource index first
1169        ResourceGroup* grp = getResourceGroup(groupName);
1170        if (!grp)
1171        {
1172            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
1173                "Cannot locate a resource group called '" + groupName + "'", 
1174                "ResourceGroupManager::listResourceNames");
1175        }
1176
1177        OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
1178
1179        // Iterate over the archives
1180        LocationList::iterator i, iend;
1181        iend = grp->locationList.end();
1182        for (i = grp->locationList.begin(); i != iend; ++i)
1183        {
1184            StringVectorPtr lst = (*i)->archive->list((*i)->recursive, dirs);
1185            vec->insert(vec->end(), lst->begin(), lst->end());
1186        }
1187
1188        return vec;
1189
1190
1191    }
1192    //-----------------------------------------------------------------------
1193    FileInfoListPtr ResourceGroupManager::listResourceFileInfo(const String& groupName, bool dirs)
1194    {
1195        OGRE_LOCK_AUTO_MUTEX
1196        FileInfoListPtr vec(new FileInfoList());
1197
1198        // Try to find in resource index first
1199        ResourceGroup* grp = getResourceGroup(groupName);
1200        if (!grp)
1201        {
1202            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
1203                "Cannot locate a resource group called '" + groupName + "'", 
1204                "ResourceGroupManager::listResourceFileInfo");
1205        }
1206
1207        OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
1208
1209        // Iterate over the archives
1210        LocationList::iterator i, iend;
1211        iend = grp->locationList.end();
1212        for (i = grp->locationList.begin(); i != iend; ++i)
1213        {
1214            FileInfoListPtr lst = (*i)->archive->listFileInfo((*i)->recursive, dirs);
1215            vec->insert(vec->end(), lst->begin(), lst->end());
1216        }
1217
1218        return vec;
1219
1220    }
1221    //-----------------------------------------------------------------------
1222    StringVectorPtr ResourceGroupManager::findResourceNames(const String& groupName, 
1223        const String& pattern, bool dirs)
1224    {
1225        OGRE_LOCK_AUTO_MUTEX
1226        StringVectorPtr vec(new StringVector());
1227
1228        // Try to find in resource index first
1229        ResourceGroup* grp = getResourceGroup(groupName);
1230        if (!grp)
1231        {
1232            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
1233                "Cannot locate a resource group called '" + groupName + "'", 
1234                "ResourceGroupManager::findResourceNames");
1235        }
1236
1237        OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
1238
1239            // Iterate over the archives
1240            LocationList::iterator i, iend;
1241        iend = grp->locationList.end();
1242        for (i = grp->locationList.begin(); i != iend; ++i)
1243        {
1244            StringVectorPtr lst = (*i)->archive->find(pattern, (*i)->recursive, dirs);
1245            vec->insert(vec->end(), lst->begin(), lst->end());
1246        }
1247
1248        return vec;
1249    }
1250    //-----------------------------------------------------------------------
1251    FileInfoListPtr ResourceGroupManager::findResourceFileInfo(const String& groupName, 
1252        const String& pattern, bool dirs)
1253    {
1254        OGRE_LOCK_AUTO_MUTEX
1255        FileInfoListPtr vec(new FileInfoList());
1256
1257        // Try to find in resource index first
1258        ResourceGroup* grp = getResourceGroup(groupName);
1259        if (!grp)
1260        {
1261            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
1262                "Cannot locate a resource group called '" + groupName + "'", 
1263                "ResourceGroupManager::findResourceFileInfo");
1264        }
1265
1266        OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
1267
1268            // Iterate over the archives
1269            LocationList::iterator i, iend;
1270        iend = grp->locationList.end();
1271        for (i = grp->locationList.begin(); i != iend; ++i)
1272        {
1273            FileInfoListPtr lst = (*i)->archive->findFileInfo(pattern, (*i)->recursive, dirs);
1274            vec->insert(vec->end(), lst->begin(), lst->end());
1275        }
1276
1277        return vec;
1278    }
1279    //-----------------------------------------------------------------------
1280        bool ResourceGroupManager::resourceExists(const String& groupName, const String& resourceName)
1281        {
1282        OGRE_LOCK_AUTO_MUTEX
1283
1284                // Try to find in resource index first
1285        ResourceGroup* grp = getResourceGroup(groupName);
1286        if (!grp)
1287        {
1288            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
1289                "Cannot locate a resource group called '" + groupName + "'", 
1290                "ResourceGroupManager::resourceExists");
1291        }
1292
1293                return resourceExists(grp, resourceName);
1294        }
1295    //-----------------------------------------------------------------------
1296        bool ResourceGroupManager::resourceExists(ResourceGroup* grp, const String& resourceName)
1297        {
1298
1299                OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
1300
1301                // Try indexes first
1302                ResourceLocationIndex::iterator rit = grp->resourceIndexCaseSensitive.find(resourceName);
1303                if (rit != grp->resourceIndexCaseSensitive.end())
1304                {
1305                        // Found in the index
1306                        return true;
1307                }
1308        else 
1309        {
1310            // try case insensitive
1311            String lcResourceName = resourceName;
1312            StringUtil::toLowerCase(lcResourceName);
1313            rit = grp->resourceIndexCaseInsensitive.find(lcResourceName);
1314            if (rit != grp->resourceIndexCaseInsensitive.end())
1315            {
1316                // Found in the index
1317                return true;
1318            }
1319                    else
1320                    {
1321                            // Search the hard way
1322                            LocationList::iterator li, liend;
1323                            liend = grp->locationList.end();
1324                            for (li = grp->locationList.begin(); li != liend; ++li)
1325                            {
1326                                    Archive* arch = (*li)->archive;
1327                    if (arch->exists(resourceName))
1328                                    {
1329                                                return true;
1330                                    }
1331                            }
1332                    }
1333        }
1334
1335                return false;
1336
1337        }
1338    //-----------------------------------------------------------------------
1339        ResourceGroupManager::ResourceGroup* 
1340        ResourceGroupManager::findGroupContainingResourceImpl(const String& filename)
1341        {
1342        OGRE_LOCK_AUTO_MUTEX
1343
1344                        // Iterate over resource groups and find
1345                for (ResourceGroupMap::iterator i = mResourceGroupMap.begin();
1346                        i != mResourceGroupMap.end(); ++i)
1347                {
1348                ResourceGroup* grp = i->second;
1349
1350                        OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
1351                               
1352                        if (resourceExists(grp, filename))
1353                                return grp;
1354                }
1355                // Not found
1356                return 0;
1357        }
1358    //-----------------------------------------------------------------------
1359        const String& ResourceGroupManager::findGroupContainingResource(const String& filename)
1360        {
1361                ResourceGroup* grp = findGroupContainingResourceImpl(filename);
1362                if (!grp)
1363                {
1364                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
1365                                "Unable to derive resource group for " + 
1366                                filename + " automatically since the resource was not "
1367                                "found.", 
1368                                "ResourceGroupManager::findGroupContainingResource");
1369                }
1370                return grp->name;
1371        }
1372    //-----------------------------------------------------------------------
1373    void ResourceGroupManager::linkWorldGeometryToResourceGroup(const String& group, 
1374        const String& worldGeometry, SceneManager* sceneManager)
1375    {
1376        OGRE_LOCK_AUTO_MUTEX
1377        ResourceGroup* grp = getResourceGroup(group);
1378        if (!grp)
1379        {
1380            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
1381                "Cannot locate a resource group called '" + group + "'", 
1382                "ResourceGroupManager::linkWorldGeometryToResourceGroup");
1383        }
1384
1385        OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
1386
1387        grp->worldGeometry = worldGeometry;
1388        grp->worldGeometrySceneManager = sceneManager;
1389    }
1390    //-----------------------------------------------------------------------
1391    void ResourceGroupManager::unlinkWorldGeometryFromResourceGroup(const String& group)
1392    {
1393        OGRE_LOCK_AUTO_MUTEX
1394        ResourceGroup* grp = getResourceGroup(group);
1395        if (!grp)
1396        {
1397            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
1398                "Cannot locate a resource group called '" + group + "'", 
1399                "ResourceGroupManager::unlinkWorldGeometryFromResourceGroup");
1400        }
1401
1402                OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
1403        grp->worldGeometry = StringUtil::BLANK;
1404        grp->worldGeometrySceneManager = 0;
1405    }
1406    //-----------------------------------------------------------------------
1407        StringVector ResourceGroupManager::getResourceGroups(void)
1408        {
1409        OGRE_LOCK_AUTO_MUTEX
1410                StringVector vec;
1411                for (ResourceGroupMap::iterator i = mResourceGroupMap.begin();
1412                        i != mResourceGroupMap.end(); ++i)
1413                {
1414                        vec.push_back(i->second->name);
1415                }
1416                return vec;
1417        }
1418    //-----------------------------------------------------------------------
1419        ResourceGroupManager::ResourceDeclarationList
1420        ResourceGroupManager::getResourceDeclarationList(const String& group)
1421        {
1422        OGRE_LOCK_AUTO_MUTEX
1423        ResourceGroup* grp = getResourceGroup(group);
1424        if (!grp)
1425        {
1426            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
1427                "Cannot locate a resource group called '" + group + "'", 
1428                "ResourceGroupManager::getResourceDeclarationList");
1429        }
1430
1431                OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex
1432                return grp->resourceDeclarations;
1433        }
1434        //-----------------------------------------------------------------------
1435        ScriptLoader::~ScriptLoader()
1436        {
1437        }
1438
1439
1440}
Note: See TracBrowser for help on using the repository browser.