Coverage Report

Created: 2025-10-10 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ogre/OgreMain/include/OgreResourceGroupManager.h
Line
Count
Source
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
#ifndef _ResourceGroupManager_H__
29
#define _ResourceGroupManager_H__
30
31
#include "OgrePrerequisites.h"
32
#include "OgreSingleton.h"
33
#include "OgreDataStream.h"
34
#include "OgreArchive.h"
35
#include "OgreIteratorWrapper.h"
36
#include "OgreCommon.h"
37
#include "Threading/OgreThreadHeaders.h"
38
#include <ctime>
39
#include "OgreHeaderPrefix.h"
40
41
// If X11/Xlib.h gets included before this header (for example it happens when
42
// including wxWidgets and FLTK), Status is defined as an int which we don't
43
// want as we have an enum named Status.
44
#ifdef Status
45
#undef Status
46
#endif
47
48
#if OGRE_RESOURCEMANAGER_STRICT == 0
49
#   define OGRE_RESOURCE_GROUP_INIT = RGN_AUTODETECT
50
#elif OGRE_RESOURCEMANAGER_STRICT == 1
51
#   define OGRE_RESOURCE_GROUP_INIT
52
#else
53
#   define OGRE_RESOURCE_GROUP_INIT = RGN_DEFAULT
54
#endif
55
56
namespace Ogre {
57
58
    /** \addtogroup Core
59
    *  @{
60
    */
61
    /** \addtogroup Resources
62
    *  @{
63
    */
64
65
    /// Default resource group name
66
    _OgreExport extern const char* const RGN_DEFAULT;
67
    /// Internal resource group name (should be used by OGRE internal only)
68
    _OgreExport extern const char* const RGN_INTERNAL;
69
    /// Special resource group name which causes resource group to be automatically determined based on searching for the resource in all groups.
70
    _OgreExport extern const char* const RGN_AUTODETECT;
71
72
    /** This class defines an interface which is called back during
73
        resource group loading to indicate the progress of the load. 
74
75
        Resource group loading is in 2 phases - creating resources from 
76
        declarations (which includes parsing scripts), and loading
77
        resources. Note that you don't necessarily have to have both; it
78
        is quite possible to just parse all the scripts for a group (see
79
        ResourceGroupManager::initialiseResourceGroup, but not to 
80
        load the resource group. 
81
        The sequence of events is (* signifies a repeating item):
82
        <ul>
83
        <li>resourceGroupScriptingStarted</li>
84
        <li>scriptParseStarted (*)</li>
85
        <li>scriptParseEnded (*)</li>
86
        <li>resourceGroupScriptingEnded</li>
87
        <li>resourceGroupLoadStarted</li>
88
        <li>resourceLoadStarted (*)</li>
89
        <li>resourceLoadEnded (*)</li>
90
        <li>customStageStarted (*)</li>
91
        <li>customStageEnded (*)</li>
92
        <li>resourceGroupLoadEnded</li>
93
        <li>resourceGroupPrepareStarted</li>
94
        <li>resourcePrepareStarted (*)</li>
95
        <li>resourcePrepareEnded (*)</li>
96
        <li>resourceGroupPrepareEnded</li>
97
        </ul>
98
    @note
99
        If OGRE_THREAD_SUPPORT is 1, this class is thread-safe.
100
101
    */
102
    class _OgreExport ResourceGroupListener
103
    {
104
    public:
105
0
        virtual ~ResourceGroupListener() {}
106
107
        /** This event is fired when a resource group begins parsing scripts.
108
        @note
109
            Remember that if you are loading resources through ResourceBackgroundQueue,
110
            these callbacks will occur in the background thread, so you should
111
            not perform any thread-unsafe actions in this callback if that's the
112
            case (check the group name / script name).
113
        @param groupName The name of the group 
114
        @param scriptCount The number of scripts which will be parsed
115
        */
116
0
        virtual void resourceGroupScriptingStarted(const String& groupName, size_t scriptCount) {}
117
        /** This event is fired when a script is about to be parsed.
118
            @param scriptName Name of the to be parsed
119
            @param skipThisScript A boolean passed by reference which is by default set to 
120
            false. If the event sets this to true, the script will be skipped and not
121
            parsed. Note that in this case the scriptParseEnded event will not be raised
122
            for this script.
123
        */
124
0
        virtual void scriptParseStarted(const String& scriptName, bool& skipThisScript) {}
125
126
        /** This event is fired when the script has been fully parsed.
127
        */
128
0
        virtual void scriptParseEnded(const String& scriptName, bool skipped) {}
129
        /** This event is fired when a resource group finished parsing scripts. */
130
0
        virtual void resourceGroupScriptingEnded(const String& groupName) {}
131
132
        /** This event is fired  when a resource group begins preparing.
133
        @param groupName The name of the group being prepared
134
        @param resourceCount The number of resources which will be prepared, including
135
            a number of stages required to prepare any linked world geometry
136
        */
137
        virtual void resourceGroupPrepareStarted(const String& groupName, size_t resourceCount)
138
0
                { (void)groupName; (void)resourceCount; }
139
140
        /** This event is fired when a declared resource is about to be prepared. 
141
        @param resource Weak reference to the resource prepared.
142
        */
143
        virtual void resourcePrepareStarted(const ResourcePtr& resource)
144
0
                { (void)resource; }
145
146
        /** This event is fired when the resource has been prepared. 
147
        */
148
0
        virtual void resourcePrepareEnded(void) {}
149
        /** This event is fired when a resource group finished preparing. */
150
        virtual void resourceGroupPrepareEnded(const String& groupName)
151
0
        { (void)groupName; }
152
153
        /** This event is fired  when a resource group begins loading.
154
        @param groupName The name of the group being loaded
155
        @param resourceCount The number of resources which will be loaded, including
156
            a number of custom stages required to load anything else
157
        */
158
0
        virtual void resourceGroupLoadStarted(const String& groupName, size_t resourceCount) {}
159
        /** This event is fired when a declared resource is about to be loaded. 
160
        @param resource Weak reference to the resource loaded.
161
        */
162
0
        virtual void resourceLoadStarted(const ResourcePtr& resource) {}
163
        /** This event is fired when the resource has been loaded. 
164
        */
165
0
        virtual void resourceLoadEnded(void) {}
166
        /** This event is fired when a custom loading stage
167
            is about to start. The number of stages required will have been 
168
            included in the resourceCount passed in resourceGroupLoadStarted.
169
        @param description Text description of what is about to be done
170
        */
171
0
        virtual void customStageStarted(const String& description){}
172
        /** This event is fired when a custom loading stage
173
            has been completed. The number of stages required will have been 
174
            included in the resourceCount passed in resourceGroupLoadStarted.
175
        */
176
0
        virtual void customStageEnded(void) {}
177
        /** This event is fired when a resource group finished loading. */
178
0
        virtual void resourceGroupLoadEnded(const String& groupName) {}
179
        /** This event is fired when a resource was just created.
180
        @param resource Weak reference to the resource created.
181
        */
182
        virtual void resourceCreated(const ResourcePtr& resource)
183
0
        { (void)resource; }
184
        /** This event is fired when a resource is about to be removed.
185
        @param resource Weak reference to the resource removed.
186
        */
187
        virtual void resourceRemove(const ResourcePtr& resource)
188
0
        { (void)resource; }
189
    };
190
191
    /**
192
    This class allows users to override resource loading behavior.
193
194
    By overriding this class' methods, you can change how resources
195
    are loaded and the behavior for resource name collisions.
196
    */
197
    class ResourceLoadingListener
198
    {
199
    public:
200
0
        virtual ~ResourceLoadingListener() {}
201
202
        /** This event is called when a resource beings loading. */
203
0
        virtual DataStreamPtr resourceLoading(const String &name, const String &group, Resource *resource) { return NULL; }
204
205
        /** This event is called when a resource stream has been opened, but not processed yet. 
206
207
            You may alter the stream if you wish or alter the incoming pointer to point at
208
            another stream if you wish.
209
        */
210
0
        virtual void resourceStreamOpened(const String &name, const String &group, Resource *resource, DataStreamPtr& dataStream) {}
211
212
        /** This event is called when a resource collides with another existing one in a resource manager
213
214
            @param resource the new resource that conflicts with an existing one
215
            @param resourceManager the according resource manager 
216
            @return false to skip registration of the conflicting resource and continue using the previous instance.
217
          */
218
0
        virtual bool resourceCollision(Resource *resource, ResourceManager *resourceManager) { return true; }
219
    };
220
221
    /** This singleton class manages the list of resource groups, and notifying
222
        the various resource managers of their obligations to load / unload
223
        resources in a group. It also provides facilities to monitor resource
224
        loading per group (to do progress bars etc), provided the resources 
225
        that are required are pre-registered.
226
227
        Defining new resource groups, and declaring the resources you intend to
228
        use in advance is optional, however it is a very useful feature. In addition, 
229
        if a ResourceManager supports the definition of resources through scripts, 
230
        then this is the class which drives the locating of the scripts and telling
231
        the ResourceManager to parse them. 
232
        
233
        @see @ref Resource-Management
234
    */
235
    class _OgreExport ResourceGroupManager : public Singleton<ResourceGroupManager>, public ResourceAlloc
236
    {
237
    public:
238
        OGRE_AUTO_MUTEX; // public to allow external locking
239
        /// same as @ref RGN_DEFAULT
240
        static const String DEFAULT_RESOURCE_GROUP_NAME;
241
        /// same as @ref RGN_INTERNAL
242
        static const String INTERNAL_RESOURCE_GROUP_NAME;
243
        /// same as @ref RGN_AUTODETECT
244
        static const String AUTODETECT_RESOURCE_GROUP_NAME;
245
        /// The number of reference counts held per resource by the resource system
246
        static const long RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS;
247
        /// Nested struct defining a resource declaration
248
        struct ResourceDeclaration
249
        {
250
            String resourceName;
251
            String resourceType;
252
            ManualResourceLoader* loader;
253
            NameValuePairList parameters;
254
        };
255
        /// List of resource declarations
256
        typedef std::list<ResourceDeclaration> ResourceDeclarationList;
257
        typedef std::map<String, ResourceManager*> ResourceManagerMap;
258
        typedef MapIterator<ResourceManagerMap> ResourceManagerIterator;
259
        /// Resource location entry
260
        struct ResourceLocation
261
        {
262
            /// Pointer to the archive which is the destination
263
            Archive* archive;
264
            /// Whether this location was added recursively
265
            bool recursive;
266
        };
267
        /// List of possible file locations
268
        typedef std::vector<ResourceLocation> LocationList;
269
270
    private:
271
        /// Map of resource types (strings) to ResourceManagers, used to notify them to load / unload group contents
272
        ResourceManagerMap mResourceManagerMap;
273
274
        /// Map of loading order (Real) to ScriptLoader, used to order script parsing
275
        typedef std::multimap<Real, ScriptLoader*> ScriptLoaderOrderMap;
276
        ScriptLoaderOrderMap mScriptLoaderOrderMap;
277
278
        typedef std::vector<ResourceGroupListener*> ResourceGroupListenerList;
279
        ResourceGroupListenerList mResourceGroupListenerList;
280
281
        ResourceLoadingListener *mLoadingListener;
282
283
        /// Resource index entry, resourcename->location 
284
        typedef std::map<String, Archive*> ResourceLocationIndex;
285
286
        /// List of resources which can be loaded / unloaded
287
        typedef std::list<ResourcePtr> LoadUnloadResourceList;
288
        /// Resource group entry
289
        struct ResourceGroup
290
        {
291
            enum Status
292
            {
293
                UNINITIALSED = 0,
294
                INITIALISING = 1,
295
                INITIALISED = 2,
296
                LOADING = 3,
297
                LOADED = 4
298
            };
299
            /// General mutex for dealing with group content
300
                    OGRE_AUTO_MUTEX;
301
            /// Status-specific mutex, separate from content-changing mutex
302
                    OGRE_MUTEX(statusMutex);
303
            /// Group name
304
            String name;
305
            /// Group status
306
            Status groupStatus;
307
            /// List of possible locations to search
308
            LocationList locationList;
309
            /// Index of resource names to locations, built for speedy access (case sensitive archives)
310
            ResourceLocationIndex resourceIndexCaseSensitive;
311
#if !OGRE_RESOURCEMANAGER_STRICT
312
            /// Index of resource names to locations, built for speedy access (case insensitive archives)
313
            ResourceLocationIndex resourceIndexCaseInsensitive;
314
#endif
315
            /// Pre-declared resources, ready to be created
316
            ResourceDeclarationList resourceDeclarations;
317
            /// Created resources which are ready to be loaded / unloaded
318
            // Group by loading order of the type (defined by ResourceManager)
319
            // (e.g. skeletons and materials before meshes)
320
            typedef std::map<Real, LoadUnloadResourceList> LoadResourceOrderMap;
321
            LoadResourceOrderMap loadResourceOrderMap;
322
            uint32 customStageCount;
323
            // in global pool flag - if true the resource will be loaded even a different   group was requested in the load method as a parameter.
324
            bool inGlobalPool;
325
326
            void addToIndex(const String& filename, Archive* arch);
327
            void removeFromIndex(const String& filename, Archive* arch);
328
            void removeFromIndex(Archive* arch);
329
330
        };
331
        /// Map from resource group names to groups
332
        typedef std::map<String, ResourceGroup*> ResourceGroupMap;
333
        ResourceGroupMap mResourceGroupMap;
334
335
        /// Group name for world resources
336
        String mWorldGroupName;
337
338
        /** Parses all the available scripts found in the resource locations
339
        for the given group, for all ResourceManagers.
340
341
            Called as part of initialiseResourceGroup
342
        */
343
        void parseResourceGroupScripts(ResourceGroup* grp) const;
344
        /** Create all the pre-declared resources.
345
346
            Called as part of initialiseResourceGroup
347
        */
348
        void createDeclaredResources(ResourceGroup* grp);
349
        /** Adds a created resource to a group. */
350
        void addCreatedResource(ResourcePtr& res, ResourceGroup& group) const;
351
        /** Get resource group */
352
        ResourceGroup* getResourceGroup(const String& name, bool throwOnFailure = false) const;
353
        /** Drops contents of a group, leave group there, notify ResourceManagers. */
354
        void dropGroupContents(ResourceGroup* grp);
355
        /** Delete a group for shutdown - don't notify ResourceManagers. */
356
        void deleteGroup(ResourceGroup* grp);
357
        /// Internal find method for auto groups
358
        std::pair<Archive*, ResourceGroup*>
359
        resourceExistsInAnyGroupImpl(const String& filename) const;
360
        /// Internal event firing method
361
        void fireResourceGroupScriptingStarted(const String& groupName, size_t scriptCount) const;
362
        /// Internal event firing method
363
        void fireScriptStarted(const String& scriptName, bool &skipScript) const;
364
        /// Internal event firing method
365
        void fireScriptEnded(const String& scriptName, bool skipped) const;
366
        /// Internal event firing method
367
        void fireResourceGroupScriptingEnded(const String& groupName) const;
368
        /// Internal event firing method
369
        void fireResourceGroupLoadStarted(const String& groupName, size_t resourceCount) const;
370
        /// Internal event firing method
371
        void fireResourceLoadStarted(const ResourcePtr& resource) const;
372
        /// Internal event firing method
373
        void fireResourceLoadEnded(void) const;
374
        /// Internal event firing method
375
        void fireResourceGroupLoadEnded(const String& groupName) const;
376
        /// Internal event firing method
377
        void fireResourceGroupPrepareStarted(const String& groupName, size_t resourceCount) const;
378
        /// Internal event firing method
379
        void fireResourcePrepareStarted(const ResourcePtr& resource) const;
380
        /// Internal event firing method
381
        void fireResourcePrepareEnded(void) const;
382
        /// Internal event firing method
383
        void fireResourceGroupPrepareEnded(const String& groupName) const;
384
        /// Internal event firing method
385
        void fireResourceCreated(const ResourcePtr& resource) const;
386
        /// Internal event firing method
387
        void fireResourceRemove(const ResourcePtr& resource) const;
388
        /** Internal modification time retrieval */
389
        time_t resourceModifiedTime(ResourceGroup* group, const String& filename) const;
390
391
        /** Find out if the named file exists in a group. Internal use only
392
         @param group Pointer to the resource group
393
         @param filename Fully qualified name of the file to test for
394
         */
395
        Archive* resourceExists(ResourceGroup* group, const String& filename) const;
396
397
        /** Open resource with optional searching in other groups if it is not found. Internal use only */
398
        DataStreamPtr openResourceImpl(const String& resourceName,
399
            const String& groupName,
400
            bool searchGroupsIfNotFound,
401
            Resource* resourceBeingLoaded,
402
            bool throwOnFailure = true) const;
403
404
        /// Stored current group - optimisation for when bulk loading a group
405
        ResourceGroup* mCurrentGroup;
406
    public:
407
        ResourceGroupManager();
408
        virtual ~ResourceGroupManager();
409
410
        /** Create a resource group.
411
412
        @param name The name to give the resource group.
413
        @param inGlobalPool if true the resource will be loaded even a different
414
            group was requested in the load method as a parameter.
415
        @see @ref Resource-Management
416
        */
417
        void createResourceGroup(const String& name, bool inGlobalPool = !OGRE_RESOURCEMANAGER_STRICT);
418
419
420
        /** Initialises a resource group.
421
        @note 
422
            When you call Root::initialise, all resource groups that have already been
423
            created are automatically initialised too. Therefore you do not need to 
424
            call this method for groups you define and set up before you call 
425
            Root::initialise. However, since one of the most useful features of 
426
            resource groups is to set them up after the main system initialisation
427
            has occurred (e.g. a group per game level), you must remember to call this
428
            method for the groups you create after this.
429
430
        @param name The name of the resource group to initialise
431
        @see @ref Resource-Management
432
        */
433
        void initialiseResourceGroup(const String& name);
434
435
        /** Initialise all resource groups which are yet to be initialised.
436
        @see #initialiseResourceGroup
437
        */
438
        void initialiseAllResourceGroups(void);
439
440
        /** Prepares a resource group.
441
442
            Prepares any created resources which are part of the named group.
443
            Note that resources must have already been created by calling
444
            ResourceManager::createResource, or declared using declareResource() or
445
            in a script (such as .material and .overlay). The latter requires
446
            that initialiseResourceGroup() has been called.
447
        
448
            When this method is called, this class will callback any ResourceGroupListener
449
            which have been registered to update them on progress. 
450
        @param name The name of the resource group to prepare.
451
        */
452
        void prepareResourceGroup(const String& name);
453
454
        /** Loads a resource group.
455
456
            Loads any created resources which are part of the named group.
457
            Note that resources must have already been created by calling
458
            ResourceManager::createResource, or declared using declareResource() or
459
            in a script (such as .material and .overlay). The latter requires
460
            that initialiseResourceGroup() has been called.
461
        
462
            When this method is called, this class will callback any ResourceGroupListeners
463
            which have been registered to update them on progress. 
464
        @param name The name of the resource group to load.
465
        */
466
        void loadResourceGroup(const String& name);
467
468
        /** Unloads a resource group.
469
470
            This method unloads all the resources that have been declared as
471
            being part of the named resource group. Note that these resources
472
            will still exist in their respective ResourceManager classes, but
473
            will be in an unloaded state. If you want to remove them entirely,
474
            you should use clearResourceGroup() or destroyResourceGroup().
475
        @param name The name to of the resource group to unload.
476
        @param reloadableOnly If set to true, only unload the resource that is
477
            reloadable. Because some resources isn't reloadable, they will be
478
            unloaded but can't load them later. Thus, you might not want to them
479
            unloaded. Or, you might unload all of them, and then populate them
480
            manually later.
481
            @see Resource::isReloadable for resource is reloadable.
482
        */
483
        void unloadResourceGroup(const String& name, bool reloadableOnly = true);
484
485
        /** Unload all resources which are not referenced by any other object.
486
487
            This method behaves like unloadResourceGroup(), except that it only
488
            unloads resources in the group which are not in use, ie not referenced
489
            by other objects. This allows you to free up some memory selectively
490
            whilst still keeping the group around (and the resources present,
491
            just not using much memory).
492
        @param name The name of the group to check for unreferenced resources
493
        @param reloadableOnly If true (the default), only unloads resources
494
            which can be subsequently automatically reloaded
495
        */
496
        void unloadUnreferencedResourcesInGroup(const String& name, 
497
            bool reloadableOnly = true);
498
499
        /** Clears a resource group. 
500
501
            This method unloads all resources in the group, but in addition it
502
            removes all those resources from their ResourceManagers, and then 
503
            clears all the members from the list. That means after calling this
504
            method, there are no resources declared as part of the named group
505
            any more. Resource locations still persist though.
506
        @param name The name to of the resource group to clear.
507
        */
508
        void clearResourceGroup(const String& name);
509
        
510
        /** Destroys a resource group, clearing it first, destroying the resources
511
            which are part of it, and then removing it from
512
            the list of resource groups. 
513
        @param name The name of the resource group to destroy.
514
        */
515
        void destroyResourceGroup(const String& name);
516
517
        /** Checks the status of a resource group.
518
519
            Looks at the state of a resource group.
520
            If initialiseResourceGroup has been called for the resource
521
            group return true, otherwise return false.
522
        @param name The name to of the resource group to access.
523
        */
524
        bool isResourceGroupInitialised(const String& name) const;
525
526
        /** Checks the status of a resource group.
527
528
            Looks at the state of a resource group.
529
            If loadResourceGroup has been called for the resource
530
            group return true, otherwise return false.
531
        @param name The name to of the resource group to access.
532
        */
533
        bool isResourceGroupLoaded(const String& name) const;
534
535
        /*** Verify if a resource group exists
536
        @param name The name of the resource group to look for
537
        */
538
        bool resourceGroupExists(const String& name) const;
539
540
        /** Adds a location to the list of searchable locations for a
541
            Resource type.
542
543
            @param
544
                name The name of the location, e.g. './data' or
545
                '/compressed/gamedata.zip'
546
            @param
547
                locType A string identifying the location type, e.g.
548
                'FileSystem' (for folders), 'Zip' etc. Must map to a
549
                registered plugin which deals with this type (FileSystem and
550
                Zip should always be available)
551
            @param
552
                resGroup the resource group which this location
553
                should apply to; defaults to the General group which applies to
554
                all non-specific resources.
555
            @param
556
                recursive If the resource location has a concept of recursive
557
                directory traversal, enabling this option will mean you can load
558
                resources in subdirectories using their qualified name.
559
                The default is to ignore subdirectories which results in "flat" resource names.
560
            @param readOnly whether the Archive is read only
561
            @see @ref Resource-Management
562
        */
563
        void addResourceLocation(const String& name, const String& locType, 
564
            const String& resGroup = DEFAULT_RESOURCE_GROUP_NAME, bool recursive = false, bool readOnly = true);
565
        /** Removes a resource location from the search path. */ 
566
        void removeResourceLocation(const String& name, 
567
            const String& resGroup = DEFAULT_RESOURCE_GROUP_NAME);
568
        /** Verify if a resource location exists for the given group. */ 
569
        bool resourceLocationExists(const String& name, 
570
            const String& resGroup = DEFAULT_RESOURCE_GROUP_NAME) const;
571
572
        /** Declares a resource to be a part of a resource group, allowing you 
573
            to load and unload it as part of the group.
574
575
        @param name The resource name. 
576
        @param resourceType The type of the resource. Ogre comes preconfigured with 
577
            a number of resource types: 
578
            <ul>
579
            <li>Font</li>
580
            <li>GpuProgram</li>
581
            <li>HighLevelGpuProgram</li>
582
            <li>Material</li>
583
            <li>Mesh</li>
584
            <li>Skeleton</li>
585
            <li>Texture</li>
586
            </ul>
587
            .. but more can be added by plugin ResourceManager classes.
588
        @param groupName The name of the group to which it will belong.
589
        @param loadParameters A list of name / value pairs which supply custom
590
            parameters to the resource which will be required before it can 
591
            be loaded. These are specific to the resource type.
592
        @see @ref Resource-Management
593
        */
594
        void declareResource(const String& name, const String& resourceType,
595
            const String& groupName = DEFAULT_RESOURCE_GROUP_NAME,
596
            const NameValuePairList& loadParameters = NameValuePairList());
597
        /** @copydoc declareResource
598
            @param loader Pointer to a ManualResourceLoader implementation which will
599
            be called when the Resource wishes to load. If supplied, the resource
600
            is manually loaded, otherwise it'll loading from file automatic.
601
            @note We don't support declare manually loaded resource without loader
602
                here, since it's meaningless.
603
        */
604
        void declareResource(const String& name, const String& resourceType,
605
            const String& groupName, ManualResourceLoader* loader,
606
            const NameValuePairList& loadParameters = NameValuePairList());
607
        /** Undeclare a resource.
608
609
            Note that this will not cause it to be unloaded
610
            if it is already loaded, nor will it destroy a resource which has 
611
            already been created if initialiseResourceGroup has been called already.
612
            Only unloadResourceGroup / clearResourceGroup / destroyResourceGroup 
613
            will do that. 
614
        @param name The name of the resource. 
615
        @param groupName The name of the group this resource was declared in. 
616
        */
617
        void undeclareResource(const String& name, const String& groupName);
618
619
        /** Open a single resource by name and return a DataStream
620
            pointing at the source of the data.
621
        @param resourceName The name of the resource to locate.
622
            Even if resource locations are added recursively, you
623
            must provide a fully qualified name to this method. You
624
            can find out the matching fully qualified names by using the
625
            find() method if you need to.
626
        @param groupName The name of the resource group; this determines which
627
            locations are searched.
628
            If you're loading a @ref Resource using #RGN_AUTODETECT, you **must**
629
            also provide the resourceBeingLoaded parameter to enable the
630
            group membership to be changed
631
        @param resourceBeingLoaded Optional pointer to the resource being
632
            loaded, which you should supply if you want
633
        @param throwOnFailure throw an exception. Returns nullptr otherwise
634
        @return Shared pointer to data stream containing the data, will be
635
            destroyed automatically when no longer referenced
636
        */
637
        DataStreamPtr openResource(const String& resourceName,
638
                                   const String& groupName = DEFAULT_RESOURCE_GROUP_NAME,
639
                                   Resource* resourceBeingLoaded = NULL,
640
                                   bool throwOnFailure = true) const
641
0
        {
642
0
            return openResourceImpl(resourceName, groupName, false,
643
0
                                    resourceBeingLoaded, throwOnFailure);
644
0
        }
645
646
        /** 
647
            @overload
648
            if the resource is not found in the group specified, other groups will be searched.
649
            @deprecated use AUTODETECT_RESOURCE_GROUP_NAME instead of searchGroupsIfNotFound
650
        */
651
        OGRE_DEPRECATED DataStreamPtr openResource(const String& resourceName,
652
                                                   const String& groupName,
653
                                                   bool searchGroupsIfNotFound,
654
                                                   Resource* resourceBeingLoaded = 0) const
655
0
        {
656
0
            return openResourceImpl(resourceName, groupName, searchGroupsIfNotFound, resourceBeingLoaded);
657
0
        }
658
659
        /** Open all resources matching a given pattern (which can contain
660
            the character '*' as a wildcard), and return a collection of 
661
            DataStream objects on them.
662
        @param pattern The pattern to look for. If resource locations have been
663
            added recursively, subdirectories will be searched too so this
664
            does not need to be fully qualified.
665
        @param groupName The resource group; this determines which locations
666
            are searched.
667
        @return Shared pointer to a data stream list , will be
668
            destroyed automatically when no longer referenced
669
        */
670
        DataStreamList openResources(const String& pattern,
671
            const String& groupName = DEFAULT_RESOURCE_GROUP_NAME) const;
672
        
673
        /** List all file or directory names in a resource group.
674
        @note
675
        This method only returns filenames, you can also retrieve other
676
        information using listFileInfo.
677
        @param groupName The name of the group
678
        @param dirs If true, directory names will be returned instead of file names
679
        @return A list of filenames matching the criteria, all are fully qualified
680
        */
681
        StringVectorPtr listResourceNames(const String& groupName, bool dirs = false) const;
682
683
        /** List all files in a resource group with accompanying information.
684
        @param groupName The name of the group
685
        @param dirs If true, directory names will be returned instead of file names
686
        @return A list of structures detailing quite a lot of information about
687
        all the files in the archive.
688
        */
689
        FileInfoListPtr listResourceFileInfo(const String& groupName, bool dirs = false) const;
690
691
        /** Find all file or directory names matching a given pattern in a
692
            resource group.
693
        @note
694
        This method only returns filenames, you can also retrieve other
695
        information using findFileInfo.
696
        @param groupName The name of the group
697
        @param pattern The pattern to search for; wildcards (*) are allowed
698
        @param dirs Set to true if you want the directories to be listed
699
            instead of files
700
        @return A list of filenames matching the criteria, all are fully qualified
701
        */
702
        StringVectorPtr findResourceNames(const String& groupName, const String& pattern,
703
            bool dirs = false) const;
704
705
        /** Find out if the named file exists in a group. 
706
        @param group The name of the resource group
707
        @param filename Fully qualified name of the file to test for
708
        */
709
        bool resourceExists(const String& group, const String& filename) const;
710
        
711
        /** Find out if the named file exists in any group. 
712
        @param filename Fully qualified name of the file to test for
713
        */
714
        bool resourceExistsInAnyGroup(const String& filename) const;
715
716
        /** Find the group in which a resource exists.
717
        @param filename Fully qualified name of the file the resource should be
718
            found as
719
        @return Name of the resource group the resource was found in. An
720
            exception is thrown if the group could not be determined.
721
        */
722
        const String& findGroupContainingResource(const String& filename) const;
723
724
        /** Find all files or directories matching a given pattern in a group
725
            and get some detailed information about them.
726
        @param group The name of the resource group
727
        @param pattern The pattern to search for; wildcards (*) are allowed
728
        @param dirs Set to true if you want the directories to be listed
729
            instead of files
730
        @return A list of file information structures for all files matching 
731
        the criteria.
732
        */
733
        FileInfoListPtr findResourceFileInfo(const String& group, const String& pattern,
734
            bool dirs = false) const;
735
736
        /** Retrieve the modification time of a given file */
737
        time_t resourceModifiedTime(const String& group, const String& filename) const;
738
        /** List all resource locations in a resource group.
739
        @param groupName The name of the group
740
        @return A list of resource locations matching the criteria
741
        */
742
        StringVectorPtr listResourceLocations(const String& groupName) const;
743
744
        /** Find all resource location names matching a given pattern in a
745
            resource group.
746
        @param groupName The name of the group
747
        @param pattern The pattern to search for; wildcards (*) are allowed
748
        @return A list of resource locations matching the criteria
749
        */
750
        StringVectorPtr findResourceLocation(const String& groupName, const String& pattern) const;
751
752
        /** Create a new resource file in a given group.
753
754
            This method creates a new file in a resource group and passes you back a 
755
            writeable stream. 
756
        @param filename The name of the file to create
757
        @param groupName The name of the group in which to create the file
758
        @param overwrite If true, an existing file will be overwritten, if false
759
            an error will occur if the file already exists
760
        @param locationPattern If the resource group contains multiple locations, 
761
            then usually the file will be created in the first writable location. If you 
762
            want to be more specific, you can include a location pattern here and 
763
            only locations which match that pattern (as determined by StringUtil::match)
764
            will be considered candidates for creation.
765
        */
766
        DataStreamPtr createResource(const String& filename, const String& groupName = DEFAULT_RESOURCE_GROUP_NAME, 
767
            bool overwrite = false, const String& locationPattern = BLANKSTRING);
768
769
        /** Delete a single resource file.
770
        @param filename The name of the file to delete. 
771
        @param groupName The name of the group in which to search
772
        @param locationPattern If the resource group contains multiple locations, 
773
            then usually first matching file found in any location will be deleted. If you 
774
            want to be more specific, you can include a location pattern here and 
775
            only locations which match that pattern (as determined by StringUtil::match)
776
            will be considered candidates for deletion.
777
        */
778
        void deleteResource(const String& filename, const String& groupName = DEFAULT_RESOURCE_GROUP_NAME, 
779
            const String& locationPattern = BLANKSTRING);
780
781
        /** Delete all matching resource files.
782
        @param filePattern The pattern (see StringUtil::match) of the files to delete. 
783
        @param groupName The name of the group in which to search
784
        @param locationPattern If the resource group contains multiple locations, 
785
            then usually all matching files in any location will be deleted. If you 
786
            want to be more specific, you can include a location pattern here and 
787
            only locations which match that pattern (as determined by StringUtil::match)
788
            will be considered candidates for deletion.
789
        */
790
        void deleteMatchingResources(const String& filePattern, const String& groupName = DEFAULT_RESOURCE_GROUP_NAME, 
791
            const String& locationPattern = BLANKSTRING);
792
793
        /** Adds a ResourceGroupListener which will be called back during 
794
            resource loading events. 
795
        */
796
        void addResourceGroupListener(ResourceGroupListener* l);
797
        /** Removes a ResourceGroupListener */
798
        void removeResourceGroupListener(ResourceGroupListener* l);
799
800
        /** Sets the resource group that 'world' resources will use.
801
802
            This is the group which should be used by SceneManagers implementing
803
            world geometry when looking for their resources. Defaults to the 
804
            DEFAULT_RESOURCE_GROUP_NAME but this can be altered.
805
        */
806
0
        void setWorldResourceGroupName(const String& groupName) {mWorldGroupName = groupName;}
807
808
        /// Gets the resource group that 'world' resources will use.
809
0
        const String& getWorldResourceGroupName(void) const { return mWorldGroupName; }
810
811
        /** Declare the number custom loading stages for a resource group
812
813
        This allows you to include them in a loading progress report.
814
        @param group The name of the resource group
815
        @param stageCount The number of extra stages
816
        @see #addResourceGroupListener
817
        @see #_notifyCustomStageStarted
818
        @see #_notifyCustomStageEnded
819
        */
820
        void setCustomStagesForResourceGroup(const String& group, uint32 stageCount);
821
822
        uint32 getCustomStagesForResourceGroup(const String& group);
823
824
            /** Checks the status of a resource group.
825
826
            Looks at the state of a resource group.
827
            If loadResourceGroup has been called for the resource
828
            group return true, otherwise return false.
829
        @param name The name to of the resource group to access.
830
        */
831
        bool isResourceGroupInGlobalPool(const String& name) const;
832
833
        /** Shutdown all ResourceManagers, performed as part of clean-up. */
834
        void shutdownAll(void);
835
836
837
        /** Internal method for registering a ResourceManager (which should be
838
            a singleton). Creators of plugins can register new ResourceManagers
839
            this way if they wish.
840
841
            ResourceManagers that wish to parse scripts must also call 
842
            _registerScriptLoader.
843
        @param resourceType String identifying the resource type, must be unique.
844
        @param rm Pointer to the ResourceManager instance.
845
        */
846
        void _registerResourceManager(const String& resourceType, ResourceManager* rm);
847
848
        /** Internal method for unregistering a ResourceManager.
849
850
            ResourceManagers that wish to parse scripts must also call 
851
            _unregisterScriptLoader.
852
        @param resourceType String identifying the resource type.
853
        */
854
        void _unregisterResourceManager(const String& resourceType);
855
856
        /** Get the registered resource managers.
857
        */
858
0
        const ResourceManagerMap& getResourceManagers() const { return mResourceManagerMap; }
859
860
        /// @deprecated use getResourceManagers()
861
        OGRE_DEPRECATED ResourceManagerIterator getResourceManagerIterator()
862
0
        { return ResourceManagerIterator(
863
0
            mResourceManagerMap.begin(), mResourceManagerMap.end()); }
864
865
        /** Internal method for registering a ScriptLoader.
866
        @remarks ScriptLoaders parse scripts when resource groups are initialised.
867
        @param su Pointer to the ScriptLoader instance.
868
        */
869
        void _registerScriptLoader(ScriptLoader* su);
870
871
        /** Internal method for unregistering a ScriptLoader.
872
        @param su Pointer to the ScriptLoader instance.
873
        */
874
        void _unregisterScriptLoader(ScriptLoader* su);
875
876
        /** Method used to directly query for registered script loaders.
877
        @param pattern The specific script pattern (e.g. *.material) the script loader handles
878
        */
879
        ScriptLoader *_findScriptLoader(const String &pattern) const;
880
881
        /** Internal method for getting a registered ResourceManager.
882
        @param resourceType String identifying the resource type.
883
        */
884
        ResourceManager* _getResourceManager(const String& resourceType) const;
885
886
        /** Internal method called by ResourceManager when a resource is created.
887
        @param res Weak reference to resource
888
        */
889
        void _notifyResourceCreated(ResourcePtr& res) const;
890
891
        /** Internal method called by ResourceManager when a resource is removed.
892
        @param res Weak reference to resource
893
        */
894
        void _notifyResourceRemoved(const ResourcePtr& res) const;
895
896
        /** Internal method to notify the group manager that a resource has
897
            changed group (only applicable for autodetect group) */
898
        void _notifyResourceGroupChanged(const String& oldGroup, Resource* res) const;
899
900
        /** Internal method called by ResourceManager when all resources 
901
            for that manager are removed.
902
        @param manager Pointer to the manager for which all resources are being removed
903
        */
904
        void _notifyAllResourcesRemoved(ResourceManager* manager) const;
905
906
        /** Notify this manager that one custom loading stage has been started
907
908
        User code should call this method the number of times equal to the value declared
909
        in #setCustomStagesForResourceGroup.
910
        */
911
        void _notifyCustomStageStarted(const String& description) const;
912
        /** Notify this manager that one custom loading stage has been completed
913
914
        User code should call this method the number of times equal to the value declared
915
        #setCustomStagesForResourceGroup.
916
        */
917
        void _notifyCustomStageEnded(void) const;
918
919
        /** Get a list of the currently defined resource groups. 
920
        @note This method intentionally returns a copy rather than a reference in
921
            order to avoid any contention issues in multithreaded applications.
922
        @return A copy of list of currently defined groups.
923
        */
924
        StringVector getResourceGroups(void) const;
925
        /** Get the list of resource declarations for the specified group name. 
926
        @note This method intentionally returns a copy rather than a reference in
927
            order to avoid any contention issues in multithreaded applications.
928
        @param groupName The name of the group
929
        @return A copy of list of currently defined resources.
930
        */
931
        ResourceDeclarationList getResourceDeclarationList(const String& groupName) const;
932
933
        /** Get the list of resource locations for the specified group name.
934
        @param groupName The name of the group
935
        @return The list of resource locations associated with the given group.
936
        */      
937
        const LocationList& getResourceLocationList(const String& groupName) const;
938
939
        /// Sets a new loading listener
940
        void setLoadingListener(ResourceLoadingListener *listener);
941
        /// Returns the current loading listener
942
        ResourceLoadingListener *getLoadingListener() const;
943
944
        /// @copydoc Singleton::getSingleton()
945
        static ResourceGroupManager& getSingleton(void);
946
        /// @copydoc Singleton::getSingleton()
947
        static ResourceGroupManager* getSingletonPtr(void);
948
949
    };
950
    /** @} */
951
    /** @} */
952
}
953
954
#include "OgreHeaderSuffix.h"
955
956
#endif