[692] | 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-2005 The OGRE Team
|
---|
| 8 | Also see acknowledgements in Readme.html
|
---|
| 9 |
|
---|
| 10 | This program is free software; you can redistribute it and/or modify it under
|
---|
| 11 | the terms of the GNU Lesser General Public License as published by the Free Software
|
---|
| 12 | Foundation; either version 2 of the License, or (at your option) any later
|
---|
| 13 | version.
|
---|
| 14 |
|
---|
| 15 | This program is distributed in the hope that it will be useful, but WITHOUT
|
---|
| 16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
---|
| 17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
---|
| 18 |
|
---|
| 19 | You should have received a copy of the GNU Lesser General Public License along with
|
---|
| 20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
---|
| 21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to
|
---|
| 22 | http://www.gnu.org/copyleft/lesser.txt.
|
---|
| 23 | -----------------------------------------------------------------------------
|
---|
| 24 | */
|
---|
| 25 | #ifndef _Resource_H__
|
---|
| 26 | #define _Resource_H__
|
---|
| 27 |
|
---|
| 28 | #include "OgrePrerequisites.h"
|
---|
| 29 | #include "OgreString.h"
|
---|
| 30 | #include "OgreSharedPtr.h"
|
---|
| 31 | #include "OgreStringInterface.h"
|
---|
| 32 |
|
---|
| 33 | namespace Ogre {
|
---|
| 34 |
|
---|
| 35 | typedef unsigned long ResourceHandle;
|
---|
| 36 |
|
---|
| 37 |
|
---|
| 38 | // Forward declaration
|
---|
| 39 | class ManualResourceLoader;
|
---|
| 40 |
|
---|
| 41 | /** Abstract class reprensenting a loadable resource (e.g. textures, sounds etc)
|
---|
| 42 | @remarks
|
---|
| 43 | Resources are data objects that must be loaded and managed throughout
|
---|
| 44 | an application. A resource might be a mesh, a texture, or any other
|
---|
| 45 | piece of data - the key thing is that they must be identified by
|
---|
| 46 | a name which is unique, must be loaded only once,
|
---|
| 47 | must be managed efficiently in terms of retrieval, and they may
|
---|
| 48 | also be unloadable to free memory up when they have not been used for
|
---|
| 49 | a while and the memory budget is under stress.
|
---|
| 50 | @par
|
---|
| 51 | All Resource instances must be a member of a resource group; see
|
---|
| 52 | ResourceGroupManager for full details.
|
---|
| 53 | @par
|
---|
| 54 | Subclasses must implement:
|
---|
| 55 | <ol>
|
---|
| 56 | <li>A constructor, overriding the same parameters as the constructor
|
---|
| 57 | defined by this class. Subclasses are not allowed to define
|
---|
| 58 | constructors with other parameters; other settings must be
|
---|
| 59 | settable through accessor methods before loading.</li>
|
---|
| 60 | <li>The loadImpl() and unloadImpl() methods - mSize must be set
|
---|
| 61 | after loadImpl()</li>
|
---|
| 62 | <li>StringInterface ParamCommand and ParamDictionary setups
|
---|
| 63 | in order to allow setting of core parameters (prior to load)
|
---|
| 64 | through a generic interface.</li>
|
---|
| 65 | </ol>
|
---|
| 66 | */
|
---|
| 67 | class _OgreExport Resource : public StringInterface
|
---|
| 68 | {
|
---|
| 69 | public:
|
---|
| 70 | OGRE_AUTO_MUTEX // public to allow external locking
|
---|
| 71 | protected:
|
---|
| 72 | /// Creator
|
---|
| 73 | ResourceManager* mCreator;
|
---|
| 74 | /// Unique name of the resource
|
---|
| 75 | String mName;
|
---|
| 76 | /// The name of the resource group
|
---|
| 77 | String mGroup;
|
---|
| 78 | /// Numeric handle for more efficient look up than name
|
---|
| 79 | ResourceHandle mHandle;
|
---|
| 80 | /// Is the resource currently loaded?
|
---|
| 81 | bool mIsLoaded;
|
---|
| 82 | /// The size of the resource in bytes
|
---|
| 83 | size_t mSize;
|
---|
| 84 | /// Is this file manually loaded?
|
---|
| 85 | bool mIsManual;
|
---|
| 86 | /// Origin of this resource (e.g. script name) - optional
|
---|
| 87 | String mOrigin;
|
---|
| 88 | /// Optional manual loader; if provided, data is loaded from here instead of a file
|
---|
| 89 | ManualResourceLoader* mLoader;
|
---|
| 90 |
|
---|
| 91 | /** Protected unnamed constructor to prevent default construction.
|
---|
| 92 | */
|
---|
| 93 | Resource()
|
---|
| 94 | : mCreator(0), mHandle(0), mIsLoaded(false), mSize(0), mIsManual(0), mLoader(0)
|
---|
| 95 | {
|
---|
| 96 | }
|
---|
| 97 |
|
---|
| 98 | /** Internal implementation of the 'load' action, only called if this
|
---|
| 99 | resource is not being loaded from a ManualResourceLoader.
|
---|
| 100 | */
|
---|
| 101 | virtual void loadImpl(void) = 0;
|
---|
| 102 | /** Internal implementation of the 'unload' action; called regardless of
|
---|
| 103 | whether this resource is being loaded from a ManualResourceLoader.
|
---|
| 104 | */
|
---|
| 105 | virtual void unloadImpl(void) = 0;
|
---|
| 106 | /** Calculate the size of a resource; this will only be called after 'load' */
|
---|
| 107 | virtual size_t calculateSize(void) const = 0;
|
---|
| 108 |
|
---|
| 109 | public:
|
---|
| 110 | /** Standard constructor.
|
---|
| 111 | @param creator Pointer to the ResourceManager that is creating this resource
|
---|
| 112 | @param name The unique name of the resource
|
---|
| 113 | @param group The name of the resource group to which this resource belongs
|
---|
| 114 | @param isManual Is this resource manually loaded? If so, you should really
|
---|
| 115 | populate the loader parameter in order that the load process
|
---|
| 116 | can call the loader back when loading is required.
|
---|
| 117 | @param loader Pointer to a ManualResourceLoader implementation which will be called
|
---|
| 118 | when the Resource wishes to load (should be supplied if you set
|
---|
| 119 | isManual to true). You can in fact leave this parameter null
|
---|
| 120 | if you wish, but the Resource will never be able to reload if
|
---|
| 121 | anything ever causes it to unload. Therefore provision of a proper
|
---|
| 122 | ManualResourceLoader instance is strongly recommended.
|
---|
| 123 | */
|
---|
| 124 | Resource(ResourceManager* creator, const String& name, ResourceHandle handle,
|
---|
| 125 | const String& group, bool isManual = false, ManualResourceLoader* loader = 0);
|
---|
| 126 |
|
---|
| 127 | /** Virtual destructor. Shouldn't need to be overloaded, as the resource
|
---|
| 128 | deallocation code should reside in unload()
|
---|
| 129 | @see
|
---|
| 130 | Resource::unload()
|
---|
| 131 | */
|
---|
| 132 | virtual ~Resource();
|
---|
| 133 |
|
---|
| 134 | /** Loads the resource, if it is not already.
|
---|
| 135 | @remarks
|
---|
| 136 | If the resource is loaded from a file, loading is automatic. If not,
|
---|
| 137 | if for example this resource gained it's data from procedural calls
|
---|
| 138 | rather than loading from a file, then this resource will not reload
|
---|
| 139 | on it's own
|
---|
| 140 |
|
---|
| 141 | */
|
---|
| 142 | virtual void load(void);
|
---|
| 143 |
|
---|
| 144 | /** Reloads the resource, if it is already loaded.
|
---|
| 145 | @remarks
|
---|
| 146 | Calls unload() and then load() again, if the resource is already
|
---|
| 147 | loaded. If it is not loaded already, then nothing happens.
|
---|
| 148 | */
|
---|
| 149 | virtual void reload(void);
|
---|
| 150 |
|
---|
| 151 | /** Returns true if the Resource is reloadable, false otherwise.
|
---|
| 152 | */
|
---|
| 153 | bool isReloadable(void) const
|
---|
| 154 | {
|
---|
| 155 | return !mIsManual || mLoader;
|
---|
| 156 | }
|
---|
| 157 |
|
---|
| 158 | /** Is this resource manually loaded?
|
---|
| 159 | */
|
---|
| 160 | bool isManuallyLoaded(void) const
|
---|
| 161 | {
|
---|
| 162 | return mIsManual;
|
---|
| 163 | }
|
---|
| 164 |
|
---|
| 165 | /** Unloads the resource; this is not permanent, the resource can be
|
---|
| 166 | reloaded later if required.
|
---|
| 167 | */
|
---|
| 168 | virtual void unload(void);
|
---|
| 169 |
|
---|
| 170 | /** Retrieves info about the size of the resource.
|
---|
| 171 | */
|
---|
| 172 | size_t getSize(void) const
|
---|
| 173 | {
|
---|
| 174 | return mSize;
|
---|
| 175 | }
|
---|
| 176 |
|
---|
| 177 | /** 'Touches' the resource to indicate it has been used.
|
---|
| 178 | */
|
---|
| 179 | virtual void touch(void);
|
---|
| 180 |
|
---|
| 181 | /** Gets resource name.
|
---|
| 182 | */
|
---|
| 183 | const String& getName(void) const
|
---|
| 184 | {
|
---|
| 185 | return mName;
|
---|
| 186 | }
|
---|
| 187 |
|
---|
| 188 | ResourceHandle getHandle(void) const
|
---|
| 189 | {
|
---|
| 190 | return mHandle;
|
---|
| 191 | }
|
---|
| 192 |
|
---|
| 193 | /** Returns true if the Resource has been loaded, false otherwise.
|
---|
| 194 | */
|
---|
| 195 | bool isLoaded(void) const
|
---|
| 196 | {
|
---|
| 197 | OGRE_LOCK_AUTO_MUTEX
|
---|
| 198 | return mIsLoaded;
|
---|
| 199 | }
|
---|
| 200 |
|
---|
| 201 | /// Gets the group which this resource is a member of
|
---|
| 202 | const String& getGroup(void) { return mGroup; }
|
---|
| 203 |
|
---|
| 204 | /** Change the resource group ownership of a Resource.
|
---|
| 205 | @remarks
|
---|
| 206 | This method is generally reserved for internal use, although
|
---|
| 207 | if you really know what you're doing you can use it to move
|
---|
| 208 | this resource from one group to another.
|
---|
| 209 | @param newGroup Name of the new group
|
---|
| 210 | */
|
---|
| 211 | void changeGroupOwnership(const String& newGroup);
|
---|
| 212 |
|
---|
| 213 | /// Gets the manager which created this resource
|
---|
| 214 | ResourceManager* getCreator(void) { return mCreator; }
|
---|
| 215 | /** Get the origin of this resource, e.g. a script file name.
|
---|
| 216 | @remarks
|
---|
| 217 | This property will only contain something if the creator of
|
---|
| 218 | this resource chose to populate it. Script loaders are advised
|
---|
| 219 | to populate it.
|
---|
| 220 | */
|
---|
| 221 | const String& getOrigin(void) const { return mOrigin; }
|
---|
| 222 | /// Notify this resource of it's origin
|
---|
| 223 | void _notifyOrigin(const String& origin) { mOrigin = origin; }
|
---|
| 224 |
|
---|
| 225 | };
|
---|
| 226 |
|
---|
| 227 | /** Shared pointer to a Resource.
|
---|
| 228 | @remarks
|
---|
| 229 | This shared pointer allows many references to a resource to be held, and
|
---|
| 230 | when the final reference is removed, the resource will be destroyed.
|
---|
| 231 | Note that the ResourceManager which created this Resource will be holding
|
---|
| 232 | at least one reference, so this resource will not get destroyed until
|
---|
| 233 | someone removes the resource from the manager - this at least gives you
|
---|
| 234 | strong control over when resources are freed. But the nature of the
|
---|
| 235 | shared pointer means that if anyone refers to the removed resource in the
|
---|
| 236 | meantime, the resource will remain valid.
|
---|
| 237 | @par
|
---|
| 238 | You may well see references to ResourcePtr (i.e. ResourcePtr&) being passed
|
---|
| 239 | around internally within Ogre. These are 'weak references' ie they do
|
---|
| 240 | not increment the reference count on the Resource. This is done for
|
---|
| 241 | efficiency in temporary operations that shouldn't need to incur the
|
---|
| 242 | overhead of maintaining the reference count; however we don't recommend
|
---|
| 243 | you do it yourself since these references are not guaranteed to remain valid.
|
---|
| 244 | */
|
---|
| 245 | typedef SharedPtr<Resource> ResourcePtr;
|
---|
| 246 |
|
---|
| 247 | /** Interface describing a manual resource loader.
|
---|
| 248 | @remarks
|
---|
| 249 | Resources are usually loaded from files; however in some cases you
|
---|
| 250 | want to be able to set the data up manually instead. This provides
|
---|
| 251 | some problems, such as how to reload a Resource if it becomes
|
---|
| 252 | unloaded for some reason, either because of memory constraints, or
|
---|
| 253 | because a device fails and some or all of the data is lost.
|
---|
| 254 | @par
|
---|
| 255 | This interface should be implemented by all classes which wish to
|
---|
| 256 | provide manual data to a resource. They provide a pointer to themselves
|
---|
| 257 | when defining the resource (via the appropriate ResourceManager),
|
---|
| 258 | and will be called when the Resource tries to load.
|
---|
| 259 | They should implement the loadResource method such that the Resource
|
---|
| 260 | is in the end set up exactly as if it had loaded from a file,
|
---|
| 261 | although the implementations will likely differ between subclasses
|
---|
| 262 | of Resource, which is why no generic algorithm can be stated here.
|
---|
| 263 | @note
|
---|
| 264 | The loader must remain valid for the entire life of the resource,
|
---|
| 265 | so that if need be it can be called upon to re-load the resource
|
---|
| 266 | at any time.
|
---|
| 267 | */
|
---|
| 268 | class _OgreExport ManualResourceLoader
|
---|
| 269 | {
|
---|
| 270 | public:
|
---|
| 271 | ManualResourceLoader() {}
|
---|
| 272 | virtual ~ManualResourceLoader() {}
|
---|
| 273 |
|
---|
| 274 | /** Called when a resource wishes to load.
|
---|
| 275 | @param resource The resource which wishes to load
|
---|
| 276 | */
|
---|
| 277 | virtual void loadResource(Resource* resource) = 0;
|
---|
| 278 | };
|
---|
| 279 | }
|
---|
| 280 |
|
---|
| 281 | #endif
|
---|