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-2013 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 "OgreCommon.h"
34 #include "OgreDataStream.h"
35 #include "OgreResource.h"
36 #include "OgreArchive.h"
37 #include "OgreIteratorWrappers.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 namespace Ogre {
49 
50 	/** \addtogroup Core
51 	*  @{
52 	*/
53 	/** \addtogroup Resources
54 	*  @{
55 	*/
56 	/** This abstract class defines an interface which is called back during
57         resource group loading to indicate the progress of the load.
58 	@remarks
59 		Resource group loading is in 2 phases - creating resources from
60 		declarations (which includes parsing scripts), and loading
61 		resources. Note that you don't necessarily have to have both; it
62 		is quite possible to just parse all the scripts for a group (see
63 		ResourceGroupManager::initialiseResourceGroup, but not to
64 		load the resource group.
65 		The sequence of events is (* signifies a repeating item):
66 		<ul>
67 		<li>resourceGroupScriptingStarted</li>
68 		<li>scriptParseStarted (*)</li>
69         <li>scriptParseEnded (*)</li>
70 		<li>resourceGroupScriptingEnded</li>
71 		<li>resourceGroupLoadStarted</li>
72 		<li>resourceLoadStarted (*)</li>
73         <li>resourceLoadEnded (*)</li>
74         <li>worldGeometryStageStarted (*)</li>
75         <li>worldGeometryStageEnded (*)</li>
76 		<li>resourceGroupLoadEnded</li>
77 		<li>resourceGroupPrepareStarted</li>
78 		<li>resourcePrepareStarted (*)</li>
79         <li>resourcePrepareEnded (*)</li>
80 		<li>resourceGroupPrepareEnded</li>
81 		</ul>
82     @note
83         If OGRE_THREAD_SUPPORT is 1, this class is thread-safe.
84 
85     */
86     class _OgreExport ResourceGroupListener
87     {
88     public:
~ResourceGroupListener()89         virtual ~ResourceGroupListener() {}
90 
91 		/** This event is fired when a resource group begins parsing scripts.
92 		@note
93 			Remember that if you are loading resources through ResourceBackgroundQueue,
94 			these callbacks will occur in the background thread, so you should
95 			not perform any thread-unsafe actions in this callback if that's the
96 			case (check the group name / script name).
97 		@param groupName The name of the group
98 		@param scriptCount The number of scripts which will be parsed
99 		*/
100 		virtual void resourceGroupScriptingStarted(const String& groupName, size_t scriptCount) = 0;
101 		/** This event is fired when a script is about to be parsed.
102 			@param scriptName Name of the to be parsed
103 			@param skipThisScript A boolean passed by reference which is by default set to
104 			false. If the event sets this to true, the script will be skipped and not
105 			parsed. Note that in this case the scriptParseEnded event will not be raised
106 			for this script.
107 		*/
108 		virtual void scriptParseStarted(const String& scriptName, bool& skipThisScript) = 0;
109 
110 		/** This event is fired when the script has been fully parsed.
111 		*/
112 		virtual void scriptParseEnded(const String& scriptName, bool skipped) = 0;
113 		/** This event is fired when a resource group finished parsing scripts. */
114 		virtual void resourceGroupScriptingEnded(const String& groupName) = 0;
115 
116 		/** This event is fired  when a resource group begins preparing.
117 		@param groupName The name of the group being prepared
118 		@param resourceCount The number of resources which will be prepared, including
119             a number of stages required to prepare any linked world geometry
120 		*/
resourceGroupPrepareStarted(const String & groupName,size_t resourceCount)121 		virtual void resourceGroupPrepareStarted(const String& groupName, size_t resourceCount)
122                 { (void)groupName; (void)resourceCount; }
123 
124 		/** This event is fired when a declared resource is about to be prepared.
125 		@param resource Weak reference to the resource prepared.
126 		*/
resourcePrepareStarted(const ResourcePtr & resource)127 		virtual void resourcePrepareStarted(const ResourcePtr& resource)
128                 { (void)resource; }
129 
130         /** This event is fired when the resource has been prepared.
131         */
resourcePrepareEnded(void)132         virtual void resourcePrepareEnded(void) {}
133         /** This event is fired when a stage of preparing linked world geometry
134             is about to start. The number of stages required will have been
135             included in the resourceCount passed in resourceGroupLoadStarted.
136         @param description Text description of what was just prepared
137         */
worldGeometryPrepareStageStarted(const String & description)138         virtual void worldGeometryPrepareStageStarted(const String& description)
139         { (void)description; }
140 
141         /** This event is fired when a stage of preparing linked world geometry
142             has been completed. The number of stages required will have been
143             included in the resourceCount passed in resourceGroupLoadStarted.
144         */
worldGeometryPrepareStageEnded(void)145         virtual void worldGeometryPrepareStageEnded(void) {}
146         /** This event is fired when a resource group finished preparing. */
resourceGroupPrepareEnded(const String & groupName)147         virtual void resourceGroupPrepareEnded(const String& groupName)
148         { (void)groupName; }
149 
150 		/** This event is fired  when a resource group begins loading.
151 		@param groupName The name of the group being loaded
152 		@param resourceCount The number of resources which will be loaded, including
153             a number of stages required to load any linked world geometry
154 		*/
155 		virtual void resourceGroupLoadStarted(const String& groupName, size_t resourceCount) = 0;
156 		/** This event is fired when a declared resource is about to be loaded.
157 		@param resource Weak reference to the resource loaded.
158 		*/
159 		virtual void resourceLoadStarted(const ResourcePtr& resource) = 0;
160         /** This event is fired when the resource has been loaded.
161         */
162         virtual void resourceLoadEnded(void) = 0;
163         /** This event is fired when a stage of loading linked world geometry
164             is about to start. The number of stages required will have been
165             included in the resourceCount passed in resourceGroupLoadStarted.
166         @param description Text description of what was just loaded
167         */
168         virtual void worldGeometryStageStarted(const String& description) = 0;
169         /** This event is fired when a stage of loading linked world geometry
170             has been completed. The number of stages required will have been
171             included in the resourceCount passed in resourceGroupLoadStarted.
172         */
173         virtual void worldGeometryStageEnded(void) = 0;
174         /** This event is fired when a resource group finished loading. */
175 		virtual void resourceGroupLoadEnded(const String& groupName) = 0;
176 		/** This event is fired when a resource was just created.
177 		@param resource Weak reference to the resource created.
178 		*/
resourceCreated(const ResourcePtr & resource)179 		virtual void resourceCreated(const ResourcePtr& resource)
180 		{ (void)resource; }
181 		/** This event is fired when a resource is about to be removed.
182 		@param resource Weak reference to the resource removed.
183 		*/
resourceRemove(const ResourcePtr & resource)184 		virtual void resourceRemove(const ResourcePtr& resource)
185 		{ (void)resource; }
186     };
187 
188 	/**
189 	 @remarks	This class allows users to override resource loading behavior.
190 				By overriding this class' methods, you can change how resources
191 				are loaded and the behavior for resource name collisions.
192 	*/
193 	class ResourceLoadingListener
194 	{
195 	public:
~ResourceLoadingListener()196 		virtual ~ResourceLoadingListener() {}
197 
198 		/** This event is called when a resource beings loading. */
199 		virtual DataStreamPtr resourceLoading(const String &name, const String &group, Resource *resource) = 0;
200 
201 		/** This event is called when a resource stream has been opened, but not processed yet.
202 		@remarks
203 			You may alter the stream if you wish or alter the incoming pointer to point at
204 			another stream if you wish.
205 		*/
206 		virtual void resourceStreamOpened(const String &name, const String &group, Resource *resource, DataStreamPtr& dataStream) = 0;
207 
208 		/** This event is called when a resource collides with another existing one in a resource manager
209 		  */
210 		virtual bool resourceCollision(Resource *resource, ResourceManager *resourceManager) = 0;
211 	};
212 
213     /** This singleton class manages the list of resource groups, and notifying
214         the various resource managers of their obligations to load / unload
215         resources in a group. It also provides facilities to monitor resource
216         loading per group (to do progress bars etc), provided the resources
217         that are required are pre-registered.
218     @par
219         Defining new resource groups,  and declaring the resources you intend to
220         use in advance is optional, however it is a very useful feature. In addition,
221 		if a ResourceManager supports the definition of resources through scripts,
222 		then this is the class which drives the locating of the scripts and telling
223 		the ResourceManager to parse them.
224 	@par
225 		There are several states that a resource can be in (the concept, not the
226 		object instance in this case):
227 		<ol>
228 		<li><b>Undefined</b>. Nobody knows about this resource yet. It might be
229 		in the filesystem, but Ogre is oblivious to it at the moment - there
230 		is no Resource instance. This might be because it's never been declared
231 		(either in a script, or using ResourceGroupManager::declareResource), or
232 		it may have previously been a valid Resource instance but has been
233 		removed, either individually through ResourceManager::remove or as a group
234 		through ResourceGroupManager::clearResourceGroup.</li>
235 		<li><b>Declared</b>. Ogre has some forewarning of this resource, either
236 		through calling ResourceGroupManager::declareResource, or by declaring
237 		the resource in a script file which is on one of the resource locations
238 		which has been defined for a group. There is still no instance of Resource,
239 		but Ogre will know to create this resource when
240 		ResourceGroupManager::initialiseResourceGroup is called (which is automatic
241 		if you declare the resource group before Root::initialise).</li>
242 		<li><b>Unloaded</b>. There is now a Resource instance for this resource,
243 		although it is not loaded. This means that code which looks for this
244 		named resource will find it, but the Resource is not using a lot of memory
245 		because it is in an unloaded state. A Resource can get into this state
246 		by having just been created by ResourceGroupManager::initialiseResourceGroup
247 		(either from a script, or from a call to declareResource), by
248 		being created directly from code (ResourceManager::create), or it may
249 		have previously been loaded and has been unloaded, either individually
250 		through Resource::unload, or as a group through ResourceGroupManager::unloadResourceGroup.</li>
251 		<li><b>Loaded</b>The Resource instance is fully loaded. This may have
252 		happened implicitly because something used it, or it may have been
253 		loaded as part of a group.</li>
254 		</ol>
255 		@see ResourceGroupManager::declareResource
256 		@see ResourceGroupManager::initialiseResourceGroup
257 		@see ResourceGroupManager::loadResourceGroup
258 		@see ResourceGroupManager::unloadResourceGroup
259 		@see ResourceGroupManager::clearResourceGroup
260     */
261     class _OgreExport ResourceGroupManager : public Singleton<ResourceGroupManager>, public ResourceAlloc
262     {
263     public:
264         OGRE_AUTO_MUTEX; // public to allow external locking
265 		/// Default resource group name
266 		static String DEFAULT_RESOURCE_GROUP_NAME;
267         /// Internal resource group name (should be used by OGRE internal only)
268         static String INTERNAL_RESOURCE_GROUP_NAME;
269 		/// Special resource group name which causes resource group to be automatically determined based on searching for the resource in all groups.
270 		static String AUTODETECT_RESOURCE_GROUP_NAME;
271 		/// The number of reference counts held per resource by the resource system
272 		static size_t RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS;
273         /// Nested struct defining a resource declaration
274         struct ResourceDeclaration
275         {
276             String resourceName;
277             String resourceType;
278             ManualResourceLoader* loader;
279 			NameValuePairList parameters;
280         };
281         /// List of resource declarations
282         typedef list<ResourceDeclaration>::type ResourceDeclarationList;
283 		typedef map<String, ResourceManager*>::type ResourceManagerMap;
284 		typedef MapIterator<ResourceManagerMap> ResourceManagerIterator;
285 		/// Resource location entry
286 		struct ResourceLocation
287 		{
288 			/// Pointer to the archive which is the destination
289 			Archive* archive;
290 			/// Whether this location was added recursively
291 			bool recursive;
292 		};
293 		/// List of possible file locations
294 		typedef list<ResourceLocation*>::type LocationList;
295 
296     protected:
297 		/// Map of resource types (strings) to ResourceManagers, used to notify them to load / unload group contents
298         ResourceManagerMap mResourceManagerMap;
299 
300 		/// Map of loading order (Real) to ScriptLoader, used to order script parsing
301 		typedef multimap<Real, ScriptLoader*>::type ScriptLoaderOrderMap;
302 		ScriptLoaderOrderMap mScriptLoaderOrderMap;
303 
304 		typedef vector<ResourceGroupListener*>::type ResourceGroupListenerList;
305         ResourceGroupListenerList mResourceGroupListenerList;
306 
307 		ResourceLoadingListener *mLoadingListener;
308 
309         /// Resource index entry, resourcename->location
310         typedef map<String, Archive*>::type ResourceLocationIndex;
311 
312 		/// List of resources which can be loaded / unloaded
313 		typedef list<ResourcePtr>::type LoadUnloadResourceList;
314 		/// Resource group entry
315 		struct ResourceGroup
316 		{
317 			enum Status
318 			{
319 				UNINITIALSED = 0,
320 				INITIALISING = 1,
321 				INITIALISED = 2,
322 				LOADING = 3,
323 				LOADED = 4
324 			};
325 			/// General mutex for dealing with group content
326                     OGRE_AUTO_MUTEX;
327 			/// Status-specific mutex, separate from content-changing mutex
328                     OGRE_MUTEX(statusMutex);
329 			/// Group name
330 			String name;
331 			/// Group status
332 			Status groupStatus;
333 			/// List of possible locations to search
334 			LocationList locationList;
335 			/// Index of resource names to locations, built for speedy access (case sensitive archives)
336 			ResourceLocationIndex resourceIndexCaseSensitive;
337             /// Index of resource names to locations, built for speedy access (case insensitive archives)
338             ResourceLocationIndex resourceIndexCaseInsensitive;
339 			/// Pre-declared resources, ready to be created
340 			ResourceDeclarationList resourceDeclarations;
341 			/// Created resources which are ready to be loaded / unloaded
342 			// Group by loading order of the type (defined by ResourceManager)
343 			// (e.g. skeletons and materials before meshes)
344 			typedef map<Real, LoadUnloadResourceList*>::type LoadResourceOrderMap;
345 			LoadResourceOrderMap loadResourceOrderMap;
346             /// Linked world geometry, as passed to setWorldGeometry
347             String worldGeometry;
348             /// Scene manager to use with linked world geometry
349             SceneManager* worldGeometrySceneManager;
350 			// in global pool flag - if true the resource will be loaded even a different	group was requested in the load method as a parameter.
351 			bool inGlobalPool;
352 
353 			void addToIndex(const String& filename, Archive* arch);
354 			void removeFromIndex(const String& filename, Archive* arch);
355 			void removeFromIndex(Archive* arch);
356 
357 		};
358         /// Map from resource group names to groups
359         typedef map<String, ResourceGroup*>::type ResourceGroupMap;
360         ResourceGroupMap mResourceGroupMap;
361 
362         /// Group name for world resources
363         String mWorldGroupName;
364 
365 		/** Parses all the available scripts found in the resource locations
366 		for the given group, for all ResourceManagers.
367 		@remarks
368 			Called as part of initialiseResourceGroup
369 		*/
370 		void parseResourceGroupScripts(ResourceGroup* grp);
371 		/** Create all the pre-declared resources.
372 		@remarks
373 			Called as part of initialiseResourceGroup
374 		*/
375 		void createDeclaredResources(ResourceGroup* grp);
376 		/** Adds a created resource to a group. */
377 		void addCreatedResource(ResourcePtr& res, ResourceGroup& group);
378 		/** Get resource group */
379 		ResourceGroup* getResourceGroup(const String& name);
380 		/** Drops contents of a group, leave group there, notify ResourceManagers. */
381 		void dropGroupContents(ResourceGroup* grp);
382 		/** Delete a group for shutdown - don't notify ResourceManagers. */
383 		void deleteGroup(ResourceGroup* grp);
384 		/// Internal find method for auto groups
385 		ResourceGroup* findGroupContainingResourceImpl(const String& filename);
386 		/// Internal event firing method
387 		void fireResourceGroupScriptingStarted(const String& groupName, size_t scriptCount);
388 		/// Internal event firing method
389 		void fireScriptStarted(const String& scriptName, bool &skipScript);
390         /// Internal event firing method
391         void fireScriptEnded(const String& scriptName, bool skipped);
392 		/// Internal event firing method
393 		void fireResourceGroupScriptingEnded(const String& groupName);
394         /// Internal event firing method
395 		void fireResourceGroupLoadStarted(const String& groupName, size_t resourceCount);
396         /// Internal event firing method
397         void fireResourceLoadStarted(const ResourcePtr& resource);
398 		/// Internal event firing method
399 		void fireResourceLoadEnded(void);
400 		/// Internal event firing method
401 		void fireResourceGroupLoadEnded(const String& groupName);
402         /// Internal event firing method
403 		void fireResourceGroupPrepareStarted(const String& groupName, size_t resourceCount);
404         /// Internal event firing method
405         void fireResourcePrepareStarted(const ResourcePtr& resource);
406 		/// Internal event firing method
407 		void fireResourcePrepareEnded(void);
408 		/// Internal event firing method
409 		void fireResourceGroupPrepareEnded(const String& groupName);
410 		/// Internal event firing method
411 		void fireResourceCreated(const ResourcePtr& resource);
412 		/// Internal event firing method
413 		void fireResourceRemove(const ResourcePtr& resource);
414 		/** Internal modification time retrieval */
415 		time_t resourceModifiedTime(ResourceGroup* group, const String& filename);
416 
417         /** Find out if the named file exists in a group. Internal use only
418          @param group Pointer to the resource group
419          @param filename Fully qualified name of the file to test for
420          */
421         bool resourceExists(ResourceGroup* group, const String& filename);
422 
423 		/// Stored current group - optimisation for when bulk loading a group
424 		ResourceGroup* mCurrentGroup;
425     public:
426         ResourceGroupManager();
427         virtual ~ResourceGroupManager();
428 
429         /** Create a resource group.
430         @remarks
431             A resource group allows you to define a set of resources that can
432             be loaded / unloaded as a unit. For example, it might be all the
433             resources used for the level of a game. There is always one predefined
434             resource group called ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
435 			which is typically used to hold all resources which do not need to
436 			be unloaded until shutdown. There is another predefined resource
437             group called ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME too,
438             which should be used by OGRE internal only, the resources created
439             in this group aren't supposed to modify, unload or remove by user.
440             You can create additional ones so that you can control the life of
441             your resources in whichever way you wish.
442 			There is one other predefined value,
443 			ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME; using this
444 			causes the group name to be derived at load time by searching for
445 			the resource in the resource locations of each group in turn.
446         @par
447             Once you have defined a resource group, resources which will be loaded
448 			as part of it are defined in one of 3 ways:
449 			<ol>
450 			<li>Manually through declareResource(); this is useful for scripted
451 				declarations since it is entirely generalised, and does not
452 				create Resource instances right away</li>
453 			<li>Through the use of scripts; some ResourceManager subtypes have
454 				script formats (e.g. .material, .overlay) which can be used
455 				to declare resources</li>
456 			<li>By calling ResourceManager::create to create a resource manually.
457 			This resource will go on the list for it's group and will be loaded
458 			and unloaded with that group</li>
459 			</ol>
460 			You must remember to call initialiseResourceGroup if you intend to use
461 			the first 2 types.
462         @param name The name to give the resource group.
463 		@param inGlobalPool if true the resource will be loaded even a different
464 			group was requested in the load method as a parameter.
465         */
466         void createResourceGroup(const String& name, const bool inGlobalPool = true);
467 
468 
469         /** Initialises a resource group.
470 		@remarks
471 			After creating a resource group, adding some resource locations, and
472 			perhaps pre-declaring some resources using declareResource(), but
473 			before you need to use the resources in the group, you
474 			should call this method to initialise the group. By calling this,
475 			you are triggering the following processes:
476 			<ol>
477 			<li>Scripts for all resource types which support scripting are
478 				parsed from the resource locations, and resources within them are
479 				created (but not loaded yet).</li>
480 			<li>Creates all the resources which have just pre-declared using
481 			declareResource (again, these are not loaded yet)</li>
482 			</ol>
483 			So what this essentially does is create a bunch of unloaded Resource entries
484 			in the respective ResourceManagers based on scripts, and resources
485 			you've pre-declared. That means that code looking for these resources
486 			will find them, but they won't be taking up much memory yet, until
487 			they are either used, or they are loaded in bulk using loadResourceGroup.
488 			Loading the resource group in bulk is entirely optional, but has the
489 			advantage of coming with progress reporting as resources are loaded.
490 		@par
491 			Failure to call this method means that loadResourceGroup will do
492 			nothing, and any resources you define in scripts will not be found.
493 			Similarly, once you have called this method you won't be able to
494 			pick up any new scripts or pre-declared resources, unless you
495 			call clearResourceGroup, set up declared resources, and call this
496 			method again.
497 		@note
498 			When you call Root::initialise, all resource groups that have already been
499 			created are automatically initialised too. Therefore you do not need to
500 			call this method for groups you define and set up before you call
501 			Root::initialise. However, since one of the most useful features of
502 			resource groups is to set them up after the main system initialisation
503 			has occurred (e.g. a group per game level), you must remember to call this
504 			method for the groups you create after this.
505 
506 		@param name The name of the resource group to initialise
507 		*/
508 		void initialiseResourceGroup(const String& name);
509 
510 		/** Initialise all resource groups which are yet to be initialised.
511 		@see ResourceGroupManager::intialiseResourceGroup
512 		*/
513 		void initialiseAllResourceGroups(void);
514 
515 		/** Prepares a resource group.
516         @remarks
517 			Prepares any created resources which are part of the named group.
518 			Note that resources must have already been created by calling
519 			ResourceManager::create, or declared using declareResource() or
520 			in a script (such as .material and .overlay). The latter requires
521 			that initialiseResourceGroup has been called.
522 
523 			When this method is called, this class will callback any ResourceGroupListeners
524 			which have been registered to update them on progress.
525         @param name The name of the resource group to prepare.
526 		@param prepareMainResources If true, prepares normal resources associated
527 			with the group (you might want to set this to false if you wanted
528 			to just prepare world geometry in bulk)
529 		@param prepareWorldGeom If true, prepares any linked world geometry
530 			@see ResourceGroupManager::linkWorldGeometryToResourceGroup
531         */
532         void prepareResourceGroup(const String& name, bool prepareMainResources = true,
533 			bool prepareWorldGeom = true);
534 
535 		/** Loads a resource group.
536         @remarks
537 			Loads any created resources which are part of the named group.
538 			Note that resources must have already been created by calling
539 			ResourceManager::create, or declared using declareResource() or
540 			in a script (such as .material and .overlay). The latter requires
541 			that initialiseResourceGroup has been called.
542 
543 			When this method is called, this class will callback any ResourceGroupListeners
544 			which have been registered to update them on progress.
545         @param name The name of the resource group to load.
546 		@param loadMainResources If true, loads normal resources associated
547 			with the group (you might want to set this to false if you wanted
548 			to just load world geometry in bulk)
549 		@param loadWorldGeom If true, loads any linked world geometry
550 			@see ResourceGroupManager::linkWorldGeometryToResourceGroup
551         */
552         void loadResourceGroup(const String& name, bool loadMainResources = true,
553 			bool loadWorldGeom = true);
554 
555         /** Unloads a resource group.
556         @remarks
557             This method unloads all the resources that have been declared as
558             being part of the named resource group. Note that these resources
559             will still exist in their respective ResourceManager classes, but
560             will be in an unloaded state. If you want to remove them entirely,
561             you should use clearResourceGroup or destroyResourceGroup.
562         @param name The name to of the resource group to unload.
563         @param reloadableOnly If set to true, only unload the resource that is
564             reloadable. Because some resources isn't reloadable, they will be
565             unloaded but can't load them later. Thus, you might not want to them
566             unloaded. Or, you might unload all of them, and then populate them
567             manually later.
568             @see Resource::isReloadable for resource is reloadable.
569         */
570         void unloadResourceGroup(const String& name, bool reloadableOnly = true);
571 
572 		/** Unload all resources which are not referenced by any other object.
573 		@remarks
574 			This method behaves like unloadResourceGroup, except that it only
575 			unloads resources in the group which are not in use, ie not referenced
576 			by other objects. This allows you to free up some memory selectively
577 			whilst still keeping the group around (and the resources present,
578 			just not using much memory).
579 		@param name The name of the group to check for unreferenced resources
580 		@param reloadableOnly If true (the default), only unloads resources
581 			which can be subsequently automatically reloaded
582 		*/
583 		void unloadUnreferencedResourcesInGroup(const String& name,
584 			bool reloadableOnly = true);
585 
586 		/** Clears a resource group.
587 		@remarks
588 			This method unloads all resources in the group, but in addition it
589 			removes all those resources from their ResourceManagers, and then
590 			clears all the members from the list. That means after calling this
591 			method, there are no resources declared as part of the named group
592 			any more. Resource locations still persist though.
593         @param name The name to of the resource group to clear.
594 		*/
595 		void clearResourceGroup(const String& name);
596 
597         /** Destroys a resource group, clearing it first, destroying the resources
598             which are part of it, and then removing it from
599             the list of resource groups.
600         @param name The name of the resource group to destroy.
601         */
602         void destroyResourceGroup(const String& name);
603 
604 		/** Checks the status of a resource group.
605 		@remarks
606 			Looks at the state of a resource group.
607 			If initialiseResourceGroup has been called for the resource
608 			group return true, otherwise return false.
609 		@param name The name to of the resource group to access.
610 		*/
611 		bool isResourceGroupInitialised(const String& name);
612 
613 		/** Checks the status of a resource group.
614 		@remarks
615 			Looks at the state of a resource group.
616 			If loadResourceGroup has been called for the resource
617 			group return true, otherwise return false.
618 		@param name The name to of the resource group to access.
619 		*/
620 		bool isResourceGroupLoaded(const String& name);
621 
622 		/*** Verify if a resource group exists
623 		@param name The name of the resource group to look for
624 		*/
625 		bool resourceGroupExists(const String& name);
626 
627         /** Method to add a resource location to for a given resource group.
628         @remarks
629             Resource locations are places which are searched to load resource files.
630             When you choose to load a file, or to search for valid files to load,
631             the resource locations are used.
632         @param name The name of the resource location; probably a directory, zip file, URL etc.
633         @param locType The codename for the resource type, which must correspond to the
634             Archive factory which is providing the implementation.
635         @param resGroup The name of the resource group for which this location is
636             to apply. ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME is the
637 			default group which always exists, and can
638             be used for resources which are unlikely to be unloaded until application
639             shutdown. Otherwise it must be the name of a group; if it
640             has not already been created with createResourceGroup then it is created
641             automatically.
642         @param recursive Whether subdirectories will be searched for files when using
643 			a pattern match (such as *.material), and whether subdirectories will be
644 			indexed. This can slow down initial loading of the archive and searches.
645 			When opening a resource you still need to use the fully qualified name,
646 			this allows duplicate names in alternate paths.
647         */
648         void addResourceLocation(const String& name, const String& locType,
649             const String& resGroup = DEFAULT_RESOURCE_GROUP_NAME, bool recursive = false, bool readOnly = true);
650         /** Removes a resource location from the search path. */
651         void removeResourceLocation(const String& name,
652 			const String& resGroup = DEFAULT_RESOURCE_GROUP_NAME);
653         /** Verify if a resource location exists for the given group. */
654 		bool resourceLocationExists(const String& name,
655 			const String& resGroup = DEFAULT_RESOURCE_GROUP_NAME);
656 
657         /** Declares a resource to be a part of a resource group, allowing you
658             to load and unload it as part of the group.
659         @remarks
660             By declaring resources before you attempt to use them, you can
661             more easily control the loading and unloading of those resources
662             by their group. Declaring them also allows them to be enumerated,
663             which means events can be raised to indicate the loading progress
664             (@see ResourceGroupListener). Note that another way of declaring
665 			resources is to use a script specific to the resource type, if
666 			available (e.g. .material).
667 		@par
668 			Declared resources are not created as Resource instances (and thus
669 			are not available through their ResourceManager) until initialiseResourceGroup
670 			is called, at which point all declared resources will become created
671 			(but unloaded) Resource instances, along with any resources declared
672 			in scripts in resource locations associated with the group.
673         @param name The resource name.
674         @param resourceType The type of the resource. Ogre comes preconfigured with
675             a number of resource types:
676             <ul>
677             <li>Font</li>
678             <li>GpuProgram</li>
679             <li>HighLevelGpuProgram</li>
680             <li>Material</li>
681             <li>Mesh</li>
682             <li>Skeleton</li>
683             <li>Texture</li>
684             </ul>
685             .. but more can be added by plugin ResourceManager classes.
686         @param groupName The name of the group to which it will belong.
687 		@param loadParameters A list of name / value pairs which supply custom
688 			parameters to the resource which will be required before it can
689 			be loaded. These are specific to the resource type.
690         */
691         void declareResource(const String& name, const String& resourceType,
692             const String& groupName = DEFAULT_RESOURCE_GROUP_NAME,
693 			const NameValuePairList& loadParameters = NameValuePairList());
694         /** Declares a resource to be a part of a resource group, allowing you
695             to load and unload it as part of the group.
696         @remarks
697             By declaring resources before you attempt to use them, you can
698             more easily control the loading and unloading of those resources
699             by their group. Declaring them also allows them to be enumerated,
700             which means events can be raised to indicate the loading progress
701             (@see ResourceGroupListener). Note that another way of declaring
702             resources is to use a script specific to the resource type, if
703             available (e.g. .material).
704         @par
705             Declared resources are not created as Resource instances (and thus
706             are not available through their ResourceManager) until initialiseResourceGroup
707             is called, at which point all declared resources will become created
708             (but unloaded) Resource instances, along with any resources declared
709             in scripts in resource locations associated with the group.
710         @param name The resource name.
711         @param resourceType The type of the resource. Ogre comes preconfigured with
712             a number of resource types:
713             <ul>
714             <li>Font</li>
715             <li>GpuProgram</li>
716             <li>HighLevelGpuProgram</li>
717             <li>Material</li>
718             <li>Mesh</li>
719             <li>Skeleton</li>
720             <li>Texture</li>
721             </ul>
722             .. but more can be added by plugin ResourceManager classes.
723         @param groupName The name of the group to which it will belong.
724         @param loader Pointer to a ManualResourceLoader implementation which will
725             be called when the Resource wishes to load. If supplied, the resource
726             is manually loaded, otherwise it'll loading from file automatic.
727             @note We don't support declare manually loaded resource without loader
728                 here, since it's meaningless.
729         @param loadParameters A list of name / value pairs which supply custom
730             parameters to the resource which will be required before it can
731             be loaded. These are specific to the resource type.
732         */
733         void declareResource(const String& name, const String& resourceType,
734             const String& groupName, ManualResourceLoader* loader,
735             const NameValuePairList& loadParameters = NameValuePairList());
736         /** Undeclare a resource.
737 		@remarks
738 			Note that this will not cause it to be unloaded
739             if it is already loaded, nor will it destroy a resource which has
740 			already been created if initialiseResourceGroup has been called already.
741 			Only unloadResourceGroup / clearResourceGroup / destroyResourceGroup
742 			will do that.
743         @param name The name of the resource.
744 		@param groupName The name of the group this resource was declared in.
745         */
746         void undeclareResource(const String& name, const String& groupName);
747 
748 		/** Open a single resource by name and return a DataStream
749 		 	pointing at the source of the data.
750 		@param resourceName The name of the resource to locate.
751 			Even if resource locations are added recursively, you
752 			must provide a fully qualified name to this method. You
753 			can find out the matching fully qualified names by using the
754 			find() method if you need to.
755 		@param groupName The name of the resource group; this determines which
756 			locations are searched.
757 		@param searchGroupsIfNotFound If true, if the resource is not found in
758 			the group specified, other groups will be searched. If you're
759 			loading a real Resource using this option, you <strong>must</strong>
760 			also provide the resourceBeingLoaded parameter to enable the
761 			group membership to be changed
762 		@param resourceBeingLoaded Optional pointer to the resource being
763 			loaded, which you should supply if you want
764 		@return Shared pointer to data stream containing the data, will be
765 			destroyed automatically when no longer referenced
766 		*/
767 		DataStreamPtr openResource(const String& resourceName,
768 			const String& groupName = DEFAULT_RESOURCE_GROUP_NAME,
769 			bool searchGroupsIfNotFound = true, Resource* resourceBeingLoaded = 0);
770 
771 		/** Open all resources matching a given pattern (which can contain
772 			the character '*' as a wildcard), and return a collection of
773 			DataStream objects on them.
774 		@param pattern The pattern to look for. If resource locations have been
775 			added recursively, subdirectories will be searched too so this
776 			does not need to be fully qualified.
777 		@param groupName The resource group; this determines which locations
778 			are searched.
779 		@return Shared pointer to a data stream list , will be
780 			destroyed automatically when no longer referenced
781 		*/
782 		DataStreamListPtr openResources(const String& pattern,
783 			const String& groupName = DEFAULT_RESOURCE_GROUP_NAME);
784 
785         /** List all file or directory names in a resource group.
786         @note
787         This method only returns filenames, you can also retrieve other
788         information using listFileInfo.
789         @param groupName The name of the group
790         @param dirs If true, directory names will be returned instead of file names
791         @return A list of filenames matching the criteria, all are fully qualified
792         */
793         StringVectorPtr listResourceNames(const String& groupName, bool dirs = false);
794 
795         /** List all files in a resource group with accompanying information.
796         @param groupName The name of the group
797         @param dirs If true, directory names will be returned instead of file names
798         @return A list of structures detailing quite a lot of information about
799         all the files in the archive.
800         */
801         FileInfoListPtr listResourceFileInfo(const String& groupName, bool dirs = false);
802 
803         /** Find all file or directory names matching a given pattern in a
804             resource group.
805         @note
806         This method only returns filenames, you can also retrieve other
807         information using findFileInfo.
808         @param groupName The name of the group
809         @param pattern The pattern to search for; wildcards (*) are allowed
810         @param dirs Set to true if you want the directories to be listed
811             instead of files
812         @return A list of filenames matching the criteria, all are fully qualified
813         */
814         StringVectorPtr findResourceNames(const String& groupName, const String& pattern,
815             bool dirs = false);
816 
817         /** Find out if the named file exists in a group.
818         @param group The name of the resource group
819         @param filename Fully qualified name of the file to test for
820         */
821         bool resourceExists(const String& group, const String& filename);
822 
823         /** Find out if the named file exists in any group.
824         @param filename Fully qualified name of the file to test for
825         */
826         bool resourceExistsInAnyGroup(const String& filename);
827 
828 		/** Find the group in which a resource exists.
829 		@param filename Fully qualified name of the file the resource should be
830 			found as
831 		@return Name of the resource group the resource was found in. An
832 			exception is thrown if the group could not be determined.
833 		*/
834 		const String& findGroupContainingResource(const String& filename);
835 
836         /** Find all files or directories matching a given pattern in a group
837             and get some detailed information about them.
838         @param group The name of the resource group
839         @param pattern The pattern to search for; wildcards (*) are allowed
840         @param dirs Set to true if you want the directories to be listed
841             instead of files
842         @return A list of file information structures for all files matching
843         the criteria.
844         */
845         FileInfoListPtr findResourceFileInfo(const String& group, const String& pattern,
846             bool dirs = false);
847 
848 		/** Retrieve the modification time of a given file */
849 		time_t resourceModifiedTime(const String& group, const String& filename);
850         /** List all resource locations in a resource group.
851         @param groupName The name of the group
852         @return A list of resource locations matching the criteria
853         */
854         StringVectorPtr listResourceLocations(const String& groupName);
855 
856         /** Find all resource location names matching a given pattern in a
857             resource group.
858         @param groupName The name of the group
859         @param pattern The pattern to search for; wildcards (*) are allowed
860         @return A list of resource locations matching the criteria
861         */
862         StringVectorPtr findResourceLocation(const String& groupName, const String& pattern);
863 
864 		/** Create a new resource file in a given group.
865 		@remarks
866 			This method creates a new file in a resource group and passes you back a
867 			writeable stream.
868 		@param filename The name of the file to create
869 		@param groupName The name of the group in which to create the file
870 		@param overwrite If true, an existing file will be overwritten, if false
871 			an error will occur if the file already exists
872 		@param locationPattern If the resource group contains multiple locations,
873 			then usually the file will be created in the first writable location. If you
874 			want to be more specific, you can include a location pattern here and
875 			only locations which match that pattern (as determined by StringUtil::match)
876 			will be considered candidates for creation.
877 		*/
878 		DataStreamPtr createResource(const String& filename, const String& groupName = DEFAULT_RESOURCE_GROUP_NAME,
879 			bool overwrite = false, const String& locationPattern = StringUtil::BLANK);
880 
881 		/** Delete a single resource file.
882 		@param filename The name of the file to delete.
883 		@param groupName The name of the group in which to search
884 		@param locationPattern If the resource group contains multiple locations,
885 			then usually first matching file found in any location will be deleted. If you
886 			want to be more specific, you can include a location pattern here and
887 			only locations which match that pattern (as determined by StringUtil::match)
888 			will be considered candidates for deletion.
889 		*/
890 		void deleteResource(const String& filename, const String& groupName = DEFAULT_RESOURCE_GROUP_NAME,
891 			const String& locationPattern = StringUtil::BLANK);
892 
893 		/** Delete all matching resource files.
894 		@param filePattern The pattern (see StringUtil::match) of the files to delete.
895 		@param groupName The name of the group in which to search
896 		@param locationPattern If the resource group contains multiple locations,
897 			then usually all matching files in any location will be deleted. If you
898 			want to be more specific, you can include a location pattern here and
899 			only locations which match that pattern (as determined by StringUtil::match)
900 			will be considered candidates for deletion.
901 		*/
902 		void deleteMatchingResources(const String& filePattern, const String& groupName = DEFAULT_RESOURCE_GROUP_NAME,
903 			const String& locationPattern = StringUtil::BLANK);
904 
905 		/** Adds a ResourceGroupListener which will be called back during
906             resource loading events.
907         */
908         void addResourceGroupListener(ResourceGroupListener* l);
909         /** Removes a ResourceGroupListener */
910         void removeResourceGroupListener(ResourceGroupListener* l);
911 
912         /** Sets the resource group that 'world' resources will use.
913         @remarks
914             This is the group which should be used by SceneManagers implementing
915             world geometry when looking for their resources. Defaults to the
916             DEFAULT_RESOURCE_GROUP_NAME but this can be altered.
917         */
setWorldResourceGroupName(const String & groupName)918         void setWorldResourceGroupName(const String& groupName) {mWorldGroupName = groupName;}
919 
920         /// Gets the resource group that 'world' resources will use.
getWorldResourceGroupName(void)921         const String& getWorldResourceGroupName(void) const { return mWorldGroupName; }
922 
923         /** Associates some world geometry with a resource group, causing it to
924             be loaded / unloaded with the resource group.
925         @remarks
926             You would use this method to essentially defer a call to
927             SceneManager::setWorldGeometry to the time when the resource group
928             is loaded. The advantage of this is that compatible scene managers
929             will include the estimate of the number of loading stages for that
930             world geometry when the resource group begins loading, allowing you
931             to include that in a loading progress report.
932         @param group The name of the resource group
933         @param worldGeometry The parameter which should be passed to setWorldGeometry
934         @param sceneManager The SceneManager which should be called
935         */
936         void linkWorldGeometryToResourceGroup(const String& group,
937             const String& worldGeometry, SceneManager* sceneManager);
938 
939         /** Clear any link to world geometry from a resource group.
940         @remarks
941             Basically undoes a previous call to linkWorldGeometryToResourceGroup.
942         */
943         void unlinkWorldGeometryFromResourceGroup(const String& group);
944 
945 			/** Checks the status of a resource group.
946 		@remarks
947 			Looks at the state of a resource group.
948 			If loadResourceGroup has been called for the resource
949 			group return true, otherwise return false.
950 		@param name The name to of the resource group to access.
951 		*/
952 		bool isResourceGroupInGlobalPool(const String& name);
953 
954         /** Shutdown all ResourceManagers, performed as part of clean-up. */
955         void shutdownAll(void);
956 
957 
958         /** Internal method for registering a ResourceManager (which should be
959             a singleton). Creators of plugins can register new ResourceManagers
960             this way if they wish.
961 		@remarks
962 			ResourceManagers that wish to parse scripts must also call
963 			_registerScriptLoader.
964         @param resourceType String identifying the resource type, must be unique.
965         @param rm Pointer to the ResourceManager instance.
966         */
967         void _registerResourceManager(const String& resourceType, ResourceManager* rm);
968 
969         /** Internal method for unregistering a ResourceManager.
970 		@remarks
971 			ResourceManagers that wish to parse scripts must also call
972 			_unregisterScriptLoader.
973         @param resourceType String identifying the resource type.
974         */
975         void _unregisterResourceManager(const String& resourceType);
976 
977 		/** Get an iterator over the registered resource managers.
978 		*/
getResourceManagerIterator()979 		ResourceManagerIterator getResourceManagerIterator()
980 		{ return ResourceManagerIterator(
981 			mResourceManagerMap.begin(), mResourceManagerMap.end()); }
982 
983         /** Internal method for registering a ScriptLoader.
984 		@remarks ScriptLoaders parse scripts when resource groups are initialised.
985         @param su Pointer to the ScriptLoader instance.
986         */
987         void _registerScriptLoader(ScriptLoader* su);
988 
989         /** Internal method for unregistering a ScriptLoader.
990         @param su Pointer to the ScriptLoader instance.
991         */
992         void _unregisterScriptLoader(ScriptLoader* su);
993 
994 		/** Method used to directly query for registered script loaders.
995 		@param pattern The specific script pattern (e.g. *.material) the script loader handles
996 		*/
997 		ScriptLoader *_findScriptLoader(const String &pattern);
998 
999 		/** Internal method for getting a registered ResourceManager.
1000 		@param resourceType String identifying the resource type.
1001 		*/
1002 		ResourceManager* _getResourceManager(const String& resourceType);
1003 
1004 		/** Internal method called by ResourceManager when a resource is created.
1005 		@param res Weak reference to resource
1006 		*/
1007 		void _notifyResourceCreated(ResourcePtr& res);
1008 
1009 		/** Internal method called by ResourceManager when a resource is removed.
1010 		@param res Weak reference to resource
1011 		*/
1012 		void _notifyResourceRemoved(ResourcePtr& res);
1013 
1014 		/** Internal method to notify the group manager that a resource has
1015 			changed group (only applicable for autodetect group) */
1016 		void _notifyResourceGroupChanged(const String& oldGroup, Resource* res);
1017 
1018 		/** Internal method called by ResourceManager when all resources
1019 			for that manager are removed.
1020 		@param manager Pointer to the manager for which all resources are being removed
1021 		*/
1022 		void _notifyAllResourcesRemoved(ResourceManager* manager);
1023 
1024         /** Notify this manager that one stage of world geometry loading has been
1025             started.
1026         @remarks
1027             Custom SceneManagers which load custom world geometry should call this
1028             method the number of times equal to the value they return from
1029             SceneManager::estimateWorldGeometry while loading their geometry.
1030         */
1031         void _notifyWorldGeometryStageStarted(const String& description);
1032         /** Notify this manager that one stage of world geometry loading has been
1033             completed.
1034         @remarks
1035             Custom SceneManagers which load custom world geometry should call this
1036             method the number of times equal to the value they return from
1037             SceneManager::estimateWorldGeometry while loading their geometry.
1038         */
1039         void _notifyWorldGeometryStageEnded(void);
1040 
1041 		/** Get a list of the currently defined resource groups.
1042 		@note This method intentionally returns a copy rather than a reference in
1043 			order to avoid any contention issues in multithreaded applications.
1044 		@return A copy of list of currently defined groups.
1045 		*/
1046 		StringVector getResourceGroups(void);
1047 		/** Get the list of resource declarations for the specified group name.
1048 		@note This method intentionally returns a copy rather than a reference in
1049 			order to avoid any contention issues in multithreaded applications.
1050 		@param groupName The name of the group
1051 		@return A copy of list of currently defined resources.
1052 		*/
1053 		ResourceDeclarationList getResourceDeclarationList(const String& groupName);
1054 
1055 		/** Get the list of resource locations for the specified group name.
1056 		@param groupName The name of the group
1057 		@return The list of resource locations associated with the given group.
1058 		*/
1059 		const LocationList& getResourceLocationList(const String& groupName);
1060 
1061 		/// Sets a new loading listener
1062 		void setLoadingListener(ResourceLoadingListener *listener);
1063 		/// Returns the current loading listener
1064 		ResourceLoadingListener *getLoadingListener();
1065 
1066 		/** Override standard Singleton retrieval.
1067         @remarks
1068         Why do we do this? Well, it's because the Singleton
1069         implementation is in a .h file, which means it gets compiled
1070         into anybody who includes it. This is needed for the
1071         Singleton template to work, but we actually only want it
1072         compiled into the implementation of the class based on the
1073         Singleton, not all of them. If we don't change this, we get
1074         link errors when trying to use the Singleton-based class from
1075         an outside dll.
1076         @par
1077         This method just delegates to the template version anyway,
1078         but the implementation stays in this single compilation unit,
1079         preventing link errors.
1080         */
1081         static ResourceGroupManager& getSingleton(void);
1082         /** Override standard Singleton retrieval.
1083         @remarks
1084         Why do we do this? Well, it's because the Singleton
1085         implementation is in a .h file, which means it gets compiled
1086         into anybody who includes it. This is needed for the
1087         Singleton template to work, but we actually only want it
1088         compiled into the implementation of the class based on the
1089         Singleton, not all of them. If we don't change this, we get
1090         link errors when trying to use the Singleton-based class from
1091         an outside dll.
1092         @par
1093         This method just delegates to the template version anyway,
1094         but the implementation stays in this single compilation unit,
1095         preventing link errors.
1096         */
1097         static ResourceGroupManager* getSingletonPtr(void);
1098 
1099     };
1100 	/** @} */
1101 	/** @} */
1102 }
1103 
1104 #include "OgreHeaderSuffix.h"
1105 
1106 #endif
1107