source: nrEngine/include/Resource.h @ 15

Revision 15, 8.1 KB checked in by art, 13 years ago (diff)
Line 
1/***************************************************************************
2 *                                                                         *
3 *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
4 *       mailto: <tevs@mpi-sb.mpg.de>                                      *
5 *                                                                         *
6 *   This program is free software; you can redistribute it and/or modify  *
7 *   it under the terms of the GNU General Public License as published by  *
8 *   the Free Software Foundation; either version 2 of the License, or     *
9 *   (at your option) any later version.                                   *
10 *                                                                         *
11 ***************************************************************************/
12
13
14#ifndef _NR_I_RESOURCE__H_
15#define _NR_I_RESOURCE__H_
16
17
18//----------------------------------------------------------------------------------
19// Includes
20//----------------------------------------------------------------------------------
21#include "Prerequisities.h"
22#include "ResourceSystem.h"
23#include <boost/enable_shared_from_this.hpp>
24
25namespace nrEngine{
26
27        //! General interface to hold any kind of resources
28        /**
29        * This is an interface which is describing how resource classes should looks like.
30        * Derive your own classes to get resource management system working. Each
31        * resource containing only once in the memory if it has the same name. So all
32        * names of resources should be unique. Resource is not directly stored by the
33        * manager but by the ResourceHolder. This holder just stores the resource
34        * and is unique for each resource. Manager just manages such holders and
35        * gives the resource pointers access to it.
36        *
37        * All derived classes must implement the behavior of resource objects correctly.
38        * Correct behavior of resource objects is done if resources do nothing what can
39        * change the empty resource behavior if they are empty. For example if you use texture
40        * and user is setting some values to it and it is at the moment unloaded, so the method
41        * will be called by the empty texture object. Empty texture object should stay empty and
42        * therefor there should not be any changes. So texture object has to check whenever it is
43        * an empty resource and should not do anything.
44        *
45        * The empty flag should be set by the loader, because only the loader does know
46        * if and when a resource can be defined as empty. For example you have to load the empty
47        * resource texture before you declare this resource as empty.
48        *
49        * \ingroup resource
50        **/
51        class _NRExport IResource : public boost::enable_shared_from_this<IResource>{
52        public:
53
54                /**
55                * Here the class should return cound of bytes reserved
56                * by the resource. The size must not contain the size of the class itself.
57                * For example: 32Bit Texture of 16x16 Pixel has the size: 16*16*4 = 1024 Bytes +
58                * some more bytes which does class need to store himself in the memory.
59                **/
60                NR_FORCEINLINE std::size_t getResDataSize(){return mResDataSize;}
61
62
63                /**
64                * Return here the name of the resource type. This name will be used
65                * to assign right empty resources to the resource pointer/holder objects.
66                * E.g: "Texture", "Sound",  ...
67                **/
68                NR_FORCEINLINE const std::string& getResType() const { return mResType; }
69
70
71                /**
72                * Return true if the resource is marked as loaded. If any resource is loaded
73                * so it contains in the memory and has it's full data there.
74                **/
75                NR_FORCEINLINE bool                             isResLoaded() const {return mResIsLoaded;}
76
77                /**
78                * Return handle of this resource
79                **/
80                NR_FORCEINLINE ResourceHandle           getResHandle() const {return mResHandle;}
81
82                /**
83                * Return group name to which one this resource belongs
84                **/
85                NR_FORCEINLINE const std::string&       getResGroup() const {return mResGroup;}
86
87                /**
88                * Get the name of the resource
89                **/
90                NR_FORCEINLINE const std::string&       getResName() const {return mResName;}
91
92                /**
93                * Get the file name from which one this resource can be restored or loaded
94                **/
95                NR_FORCEINLINE const std::string&       getResFileName() const {return mResFileName;}
96
97                /**
98                * Returns true if this resource is a empty resource. Empty resources are used
99                * to replace normal resources if they are unloaded.
100                **/
101                NR_FORCEINLINE bool                             isResEmpty()    {return mResIsEmpty;}
102
103        protected:
104               
105                /**
106                 * Create resource instance.
107                 **/
108                IResource(const std::string& resourceType);
109
110
111                /**
112                 * As soon as this destructor is called, the according loader will be
113                 * notified about removing the resource from the memory. So the loader
114                 * will correct it's database and notify also the ResourceManager about this
115                 * event.
116                 *
117                 * You have to call the unloadRes() method if you have some specific unloading
118                 * routines for your resource object. We can not call this from here, because
119                 * calling of virtual functions from constructor/destructor cause in
120                 * undefined behaviour. However we call the appropriate resource loader
121                 * to notify him that this resource is getting unloaded now.
122                 **/
123                virtual ~IResource();
124
125                /**
126                 * Unload the resource. Each resource should know how to unload it from
127                 * the memory. Unloading does not remove the resource it just unload used
128                 * data from memory. To remove the resource from memory you have either
129                 * to use ResourceManager or the ResourceLoader.
130                 *
131                 * Do here resource specific stuff. The method will be called by the loader,
132                 * so you do not have to notify the loader about this event.
133                 **/
134                virtual Result unloadRes();
135
136                /**
137                 * Loader will notify the resource that it has been restored.
138                 * A resource is restored if it was reloaded by the manager or
139                 * loader. The loader will restore the data in the way like it
140                 * has done when loading the resource. After that the loader will
141                 * notify the resource that it has been restored, so resource has
142                 * to do some initialization on this data if needed.
143                 *
144                 * The default behaviour on this function is just not to do anything.
145                 * So overload this method with your own, if you need any specific behaviour
146                 * on the restored data.
147                 **/
148                //virtual void notifyResReloaded() { }
149               
150                /**
151                 * Mark a resource as loaded. This method will not call the reloadRes()
152                 * method. Instead it will just mark this resource as it were loaded,
153                 * so you get access to real resource object through the pointers instead
154                 * of emtpy resource. Call this method if you create a resource by your
155                 * own without loading by loader.
156                 **/
157                NR_FORCEINLINE void markResLoaded() { mResIsLoaded = true; }
158               
159        private:
160               
161                //! Only loader can change resource data
162                friend class IResourceLoader;
163
164                //! Also resource manager is a friend
165                friend class ResourceManager;
166
167                //! Shows whenever resource is loaded (is in the memory)
168                bool mResIsLoaded;
169
170                //! If true so this is a empty resource
171                bool mResIsEmpty;
172
173                //! Resource's loader with which one it was created
174                SharedPtr<IResourceLoader>      mResLoader;
175
176                //! Handle of the resource given from manager
177                ResourceHandle  mResHandle;
178
179                //! Filename from which one this resource can be reloaded/loaded
180                std::string     mResFileName;
181
182                //! Count of bytes that this resource is occupies in the memory
183                std::size_t             mResDataSize;
184
185                //! Name of the resource type
186                std::string             mResType;
187               
188                //! Group name to which one this resource own
189                std::string mResGroup;
190
191                //! Name of the resource
192                std::string mResName;
193               
194                /**
195                 * Set the resource type for this resource.
196                 * Method is declared as protected, so only engine can do this.
197                 *
198                 * @param type Name of the resource type
199                 **/
200                NR_FORCEINLINE void     setResourceType(const std::string& type) { mResType = type; }
201
202                /**
203                 * If the unloading of resource is done through the resource manager,
204                 * so this method will be called.
205                 **/
206                Result unloadResThroughLoader();
207               
208                /**
209                 * Reload the resource through the according resource loader.
210                 **/
211                Result reloadResThroughLoader();
212
213                /**
214                 * Remove the resource through it's loader
215                 **/
216                Result removeResThroughLoader();
217
218                /**
219                * Get shared pointer from this class
220                **/     
221                SharedPtr<IResource> getSharedPtrFromThis()
222                {
223                        return shared_from_this();
224                }
225               
226                class _deleter{
227                public:
228                        void operator()(IResource* p) { delete p; }
229                };
230        };
231
232};
233
234#endif
Note: See TracBrowser for help on using the repository browser.