Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/include/OgreResource.h @ 5

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

=hoffentlich gehts jetzt

File size: 15.3 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#ifndef _Resource_H__
30#define _Resource_H__
31
32#include "OgrePrerequisites.h"
33#include "OgreString.h"
34#include "OgreSharedPtr.h"
35#include "OgreStringInterface.h"
36
37namespace Ogre {
38
39    typedef unsigned long ResourceHandle;
40
41
42        // Forward declaration
43        class ManualResourceLoader;
44
45        /** Abstract class reprensenting a loadable resource (e.g. textures, sounds etc)
46        @remarks
47            Resources are data objects that must be loaded and managed throughout
48                        an application. A resource might be a mesh, a texture, or any other
49                        piece of data - the key thing is that they must be identified by
50                        a name which is unique, must be loaded only once,
51                        must be managed efficiently in terms of retrieval, and they may
52                        also be unloadable to free memory up when they have not been used for
53                        a while and the memory budget is under stress.
54                @par
55                        All Resource instances must be a member of a resource group; see
56                        ResourceGroupManager for full details.
57        @par
58            Subclasses must implement:
59                        <ol>
60                        <li>A constructor, overriding the same parameters as the constructor
61                            defined by this class. Subclasses are not allowed to define
62                                constructors with other parameters; other settings must be
63                                settable through accessor methods before loading.</li>
64            <li>The loadImpl() and unloadImpl() methods - mSize must be set
65                                after loadImpl()</li>
66                        <li>StringInterface ParamCommand and ParamDictionary setups
67                            in order to allow setting of core parameters (prior to load)
68                                through a generic interface.</li>
69                        </ol>
70    */
71        class _OgreExport Resource : public StringInterface
72    {
73        public:
74                OGRE_AUTO_MUTEX // public to allow external locking
75                class Listener
76                {
77                public:
78                        Listener() {}
79                        virtual ~Listener() {}
80
81                        /** Callback to indicate that background loading has completed.
82                        @remarks
83                                This callback is only relevant when a Resource has been
84                                marked as background loaded (@see Resource::setBackgroundLoaded)
85                                , and occurs when that loading has completed. The call itself
86                                does not itself occur in the thread which is doing the loading;
87                                when loading is complete a response indicator is placed with the
88                                ResourceGroupManager, which will then be sent back to the
89                                listener as part of the application's primary frame loop thread.
90                        */
91                        virtual void backgroundLoadingComplete(Resource*) {}
92                       
93                };
94               
95                /// Enum identifying the loading state of the resource
96                enum LoadingState
97                {
98                        /// Not loaded
99                        LOADSTATE_UNLOADED,
100                        /// Loading is in progress
101                        LOADSTATE_LOADING,
102                        /// Fully loaded
103                        LOADSTATE_LOADED,
104                        /// Currently unloading
105                        LOADSTATE_UNLOADING
106                };
107    protected:
108                /// Creator
109                ResourceManager* mCreator;
110                /// Unique name of the resource
111        String mName;
112                /// The name of the resource group
113                String mGroup;
114                /// Numeric handle for more efficient look up than name
115        ResourceHandle mHandle;
116                /// Is the resource currently loaded?
117        volatile LoadingState mLoadingState;
118                /// Is this resource going to be background loaded? Only applicable for multithreaded
119                volatile bool mIsBackgroundLoaded;
120                /// Mutex to cover the status of loading
121                OGRE_MUTEX(mLoadingStatusMutex)
122                /// The size of the resource in bytes
123        size_t mSize;
124                /// Is this file manually loaded?
125                bool mIsManual;
126                /// Origin of this resource (e.g. script name) - optional
127                String mOrigin;
128                /// Optional manual loader; if provided, data is loaded from here instead of a file
129                ManualResourceLoader* mLoader;
130
131                typedef std::list<Listener*> ListenerList;
132                ListenerList mListenerList;
133
134                /** Protected unnamed constructor to prevent default construction.
135                */
136                Resource() 
137                        : mCreator(0), mHandle(0), mLoadingState(LOADSTATE_UNLOADED), 
138                        mIsBackgroundLoaded(false),     mSize(0), mIsManual(0), mLoader(0)
139                { 
140                }
141
142                /** Internal hook to perform actions before the load process, but
143                        after the resource has been marked as 'loading'.
144                @note Mutex will have already been acquired by the loading thread.
145                        Also, this call will occur even when using a ManualResourceLoader
146                        (when loadImpl is not actually called)
147                */
148                virtual void preLoadImpl(void) {}
149                /** Internal hook to perform actions after the load process, but
150                        before the resource has been marked as fully loaded.
151                @note Mutex will have already been acquired by the loading thread.
152                        Also, this call will occur even when using a ManualResourceLoader
153                        (when loadImpl is not actually called)
154                */
155                virtual void postLoadImpl(void) {}
156
157                /** Internal hook to perform actions before the unload process.
158                @note Mutex will have already been acquired by the unloading thread.
159                */
160                virtual void preUnloadImpl(void) {}
161                /** Internal hook to perform actions after the unload process, but
162                before the resource has been marked as fully unloaded.
163                @note Mutex will have already been acquired by the unloading thread.
164                */
165                virtual void postUnloadImpl(void) {}
166
167                /** Internal implementation of the meat of the 'load' action, only called if this
168                        resource is not being loaded from a ManualResourceLoader.
169                */
170                virtual void loadImpl(void) = 0;
171                /** Internal implementation of the 'unload' action; called regardless of
172                        whether this resource is being loaded from a ManualResourceLoader.
173                */
174                virtual void unloadImpl(void) = 0;
175                /** Calculate the size of a resource; this will only be called after 'load' */
176                virtual size_t calculateSize(void) const = 0;
177
178                /// Queue the firing of background loading complete event
179                virtual void queueFireBackgroundLoadingComplete(void);
180
181    public:
182                /** Standard constructor.
183                @param creator Pointer to the ResourceManager that is creating this resource
184                @param name The unique name of the resource
185                @param group The name of the resource group to which this resource belongs
186                @param isManual Is this resource manually loaded? If so, you should really
187                        populate the loader parameter in order that the load process
188                        can call the loader back when loading is required.
189                @param loader Pointer to a ManualResourceLoader implementation which will be called
190                        when the Resource wishes to load (should be supplied if you set
191                        isManual to true). You can in fact leave this parameter null
192                        if you wish, but the Resource will never be able to reload if
193                        anything ever causes it to unload. Therefore provision of a proper
194                        ManualResourceLoader instance is strongly recommended.
195                */
196                Resource(ResourceManager* creator, const String& name, ResourceHandle handle,
197                        const String& group, bool isManual = false, ManualResourceLoader* loader = 0);
198
199        /** Virtual destructor. Shouldn't need to be overloaded, as the resource
200            deallocation code should reside in unload()
201            @see
202                Resource::unload()
203        */
204        virtual ~Resource();
205
206        /** Loads the resource, if it is not already.
207                @remarks
208                        If the resource is loaded from a file, loading is automatic. If not,
209                        if for example this resource gained it's data from procedural calls
210                        rather than loading from a file, then this resource will not reload
211                        on it's own.
212                @param backgroundThread Indicates whether the caller of this method is
213                        the background resource loading thread.
214                       
215        */
216        virtual void load(bool backgroundThread = false);
217
218                /** Reloads the resource, if it is already loaded.
219                @remarks
220                        Calls unload() and then load() again, if the resource is already
221                        loaded. If it is not loaded already, then nothing happens.
222                */
223                virtual void reload(void);
224
225        /** Returns true if the Resource is reloadable, false otherwise.
226        */
227        bool isReloadable(void) const
228        {
229            return !mIsManual || mLoader;
230        }
231
232        /** Is this resource manually loaded?
233                */
234                bool isManuallyLoaded(void) const
235                {
236                        return mIsManual;
237                }
238
239                /** Unloads the resource; this is not permanent, the resource can be
240                        reloaded later if required.
241        */
242                virtual void unload(void);
243
244        /** Retrieves info about the size of the resource.
245        */
246        size_t getSize(void) const
247        { 
248            return mSize; 
249        }
250
251        /** 'Touches' the resource to indicate it has been used.
252        */
253        virtual void touch(void);
254
255        /** Gets resource name.
256        */
257        const String& getName(void) const 
258        { 
259            return mName; 
260        }
261
262        ResourceHandle getHandle(void) const
263        {
264            return mHandle;
265        }
266
267        /** Returns true if the Resource has been loaded, false otherwise.
268        */
269        bool isLoaded(void) const 
270        { 
271                        // No lock required to read this state since no modify
272            return (mLoadingState == LOADSTATE_LOADED); 
273        }
274
275                /** Returns whether the resource is currently in the process of
276                        background loading.
277                */
278                LoadingState isLoading() const
279                {
280                        return mLoadingState;
281                }
282
283                /** Returns the current loading state.
284                */
285                LoadingState getLoadingState() const
286                {
287                        return mLoadingState;
288                }
289
290
291
292                /** Returns whether this Resource has been earmarked for background loading.
293                @remarks
294                        This option only makes sense when you have built Ogre with
295                        thread support (OGRE_THREAD_SUPPORT). If a resource has been marked
296                        for background loading, then it won't load on demand like normal
297                        when load() is called. Instead, it will ignore request to load()
298                        except if the caller indicates it is the background loader. Any
299                        other users of this resource should check isLoaded(), and if that
300                        returns false, don't use the resource and come back later.
301                */
302                bool isBackgroundLoaded(void) const { return mIsBackgroundLoaded; }
303
304                /** Tells the resource whether it is background loaded or not.
305                @remarks
306                        @see Resource::isBackgroundLoaded . Note that calling this only
307                        defers the normal on-demand loading behaviour of a resource, it
308                        does not actually set up a thread to make sure the resource gets
309                        loaded in the background. You should use ResourceBackgroundLoadingQueue
310                        to manage the actual loading (which will call this method itself).
311                */
312                void setBackgroundLoaded(bool bl) { mIsBackgroundLoaded = bl; }
313
314                /** Escalates the loading of a background loaded resource.
315                @remarks
316                        If a resource is set to load in the background, but something needs
317                        it before it's been loaded, there could be a problem. If the user
318                        of this resource really can't wait, they can escalate the loading
319                        which basically pulls the loading into the current thread immediately.
320                        If the resource is already being loaded but just hasn't quite finished
321                        then this method will simply wait until the background load is complete.
322                */
323                void escalateLoading();
324
325                /** Register a listener on this resource.
326                        @see Resource::Listener
327                */
328                void addListener(Listener* lis);
329
330                /** Remove a listener on this resource.
331                        @see Resource::Listener
332                */
333                void removeListener(Listener* lis);
334
335                /// Gets the group which this resource is a member of
336                const String& getGroup(void) { return mGroup; }
337
338                /** Change the resource group ownership of a Resource.
339                @remarks
340                        This method is generally reserved for internal use, although
341                        if you really know what you're doing you can use it to move
342                        this resource from one group to another.
343                @param newGroup Name of the new group
344                */
345                void changeGroupOwnership(const String& newGroup);
346
347                /// Gets the manager which created this resource
348                ResourceManager* getCreator(void) { return mCreator; }
349                /** Get the origin of this resource, e.g. a script file name.
350                @remarks
351                        This property will only contain something if the creator of
352                        this resource chose to populate it. Script loaders are advised
353                        to populate it.
354                */
355                const String& getOrigin(void) const { return mOrigin; }
356                /// Notify this resource of it's origin
357                void _notifyOrigin(const String& origin) { mOrigin = origin; }
358
359    };
360
361        /** Shared pointer to a Resource.
362        @remarks
363                This shared pointer allows many references to a resource to be held, and
364                when the final reference is removed, the resource will be destroyed.
365                Note that the ResourceManager which created this Resource will be holding
366                at least one reference, so this resource will not get destroyed until
367                someone removes the resource from the manager - this at least gives you
368                strong control over when resources are freed. But the nature of the
369                shared pointer means that if anyone refers to the removed resource in the
370                meantime, the resource will remain valid.
371        @par
372                You may well see references to ResourcePtr (i.e. ResourcePtr&) being passed
373                around internally within Ogre. These are 'weak references' ie they do
374                not increment the reference count on the Resource. This is done for
375                efficiency in temporary operations that shouldn't need to incur the
376                overhead of maintaining the reference count; however we don't recommend
377                you do it yourself since these references are not guaranteed to remain valid.
378        */
379        typedef SharedPtr<Resource> ResourcePtr;
380
381        /** Interface describing a manual resource loader.
382        @remarks
383                Resources are usually loaded from files; however in some cases you
384                want to be able to set the data up manually instead. This provides
385                some problems, such as how to reload a Resource if it becomes
386                unloaded for some reason, either because of memory constraints, or
387                because a device fails and some or all of the data is lost.
388        @par
389                This interface should be implemented by all classes which wish to
390                provide manual data to a resource. They provide a pointer to themselves
391                when defining the resource (via the appropriate ResourceManager),
392                and will be called when the Resource tries to load.
393                They should implement the loadResource method such that the Resource
394                is in the end set up exactly as if it had loaded from a file,
395                although the implementations will likely differ between subclasses
396                of Resource, which is why no generic algorithm can be stated here.
397        @note
398                The loader must remain valid for the entire life of the resource,
399                so that if need be it can be called upon to re-load the resource
400                at any time.
401        */
402        class _OgreExport ManualResourceLoader
403        {
404        public:
405                ManualResourceLoader() {}
406                virtual ~ManualResourceLoader() {}
407
408                /** Called when a resource wishes to load.
409                @param resource The resource which wishes to load
410                */
411                virtual void loadResource(Resource* resource) = 0;
412        };
413}
414
415#endif
Note: See TracBrowser for help on using the repository browser.