nux-1.14.0
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #ifndef GLRESOURCEMANAGER_H 00024 #define GLRESOURCEMANAGER_H 00025 00026 namespace nux 00027 { 00028 00029 // class BaseTexture; 00030 // class Texture2D; 00031 // class TextureRectangle; 00032 // class TextureCube; 00033 // class TextureVolume; 00034 // class TextureFrameAnimation; 00035 // 00036 // class NVertexBuffer; 00037 // class NIndexBuffer; 00038 // 00039 // class CachedTexture2D; 00040 // class CachedTextureRectangle; 00041 // class CachedTextureCube; 00042 // class CachedTextureVolume; 00043 // class CachedTextureFrameAnimation; 00044 00045 // ResourceData CachedResourceData 00046 // | | 00047 // BaseTexture CachedBaseTexture 00048 // | | 00049 // Texture2D CachedTexture2D 00050 // 00051 // 00052 // NResourceFactory 00053 // | 00054 // NGLResourceFactory 00055 // | 00056 // TGLResourceFactory<class Texture2D, class CachedTexture2D> 00057 // 00058 // 00059 // NResourceSet 00060 // | 00061 // TResourceCache<class IdType(int), class ResourceType(CachedResourceData)> 00062 // | 00063 // NResourceCache: TResourceCache<int, CachedResourceData> 00064 // 00065 // 00066 00068 class ResourceData: public Object 00069 { 00070 NUX_DECLARE_OBJECT_TYPE (ResourceData, Object); 00071 public: 00072 ResourceData (NUX_FILE_LINE_PROTO); 00073 virtual ~ResourceData (); 00074 int GetResourceIndex () const; 00075 00076 private: 00077 int m_ResourceIndex; 00078 }; 00079 00080 class CachedResourceData; 00081 00082 class NResourceSet 00083 { 00084 public: 00085 NResourceSet(); 00086 virtual ~NResourceSet() {}; 00087 00088 protected: 00089 CachedResourceData *FirstResource; 00090 00091 // Flush 00092 virtual void Flush() {} 00093 00094 // FreeResource - Called when a potentially cached resource has been freed. 00095 virtual void FreeResource (ResourceData *Resource) {} 00096 00097 // FlushResource - Removes a resource from the set. 00098 virtual void FlushResource (CachedResourceData *Resource) {} 00099 00100 friend class CachedResourceData; 00101 }; 00102 00103 enum EResourceUpdateHint 00104 { 00105 RUH_Static, // The resource is updated once, at creation time. 00106 RUH_CacheableDynamic, // The resource is updated occasionally, but not every frame. 00107 RUH_Dynamic // The resource changes every frame. 00108 }; 00109 00110 class CachedResourceData: public Object 00111 { 00112 NUX_DECLARE_OBJECT_TYPE (CachedResourceData, Object); 00113 00114 public: 00115 CachedResourceData (NResourceSet *InSet); 00116 virtual ~CachedResourceData(); 00117 00119 00122 virtual unsigned int GetSize() const 00123 { 00124 return Size; 00125 } 00126 00128 00133 virtual unsigned int GetMaxLodSize() const 00134 { 00135 return Size; 00136 } 00137 00141 virtual bool UpdateResource (ResourceData *Resource) = 0; 00142 00143 protected: 00144 NResourceSet *Set; 00145 bool _cached; 00146 unsigned int NumRefs; 00147 NObjectType *ResourceType; 00148 00149 unsigned int Size; 00150 EResourceUpdateHint UpdateHint; 00151 00152 CachedResourceData *PrevResource; 00153 CachedResourceData *NextResource; 00154 00155 template<class IdType, class ResourceType> 00156 friend class TResourceCache; 00157 friend class NResourceCache; 00158 }; 00159 00160 00162 class NResourceFactory 00163 { 00164 public: 00165 NResourceFactory (NObjectType *Type) 00166 : m_ResourceType (Type) 00167 {} 00168 00169 // Returns the resource type for this factory 00170 const NObjectType &Type() const 00171 { 00172 return *m_ResourceType; 00173 } 00174 00179 bool BuildsThisResource (ResourceData *Resource) 00180 { 00181 return Resource->Type().IsObjectType (Type() ); 00182 } 00183 00184 virtual CachedResourceData *BuildResource (NResourceSet *ResourceManager, ResourceData *Resource) 00185 { 00186 return NULL; 00187 } 00188 00189 private: 00191 NObjectType *m_ResourceType; 00192 }; 00193 00194 template <typename T, typename U> 00195 class TGLResourceFactory : public NResourceFactory 00196 { 00197 public: 00202 TGLResourceFactory (NObjectType *Type) 00203 : NResourceFactory (Type) 00204 {} 00205 00206 virtual ~TGLResourceFactory (void) 00207 {} 00208 00210 00215 virtual CachedResourceData *BuildResource(NResourceSet *ResourceManager, ResourceData *Resource) 00216 { 00217 return new U(ResourceManager, (T *)Resource); 00218 } 00219 }; 00220 00221 00223 class NResourceUpdater 00224 { 00225 public: 00226 NResourceUpdater (NObjectType *Type) 00227 : m_ResourceType (Type) 00228 {} 00229 00231 const NObjectType &Type() const 00232 { 00233 return *m_ResourceType; 00234 } 00235 00240 bool UpdatesThisResource (ResourceData *Resource) 00241 { 00242 return Resource->Type().IsObjectType (Type() ); 00243 } 00244 00245 virtual bool UpdateResource (ObjectPtr< CachedResourceData > DeviceResource, ResourceData *Resource) const 00246 { 00247 return DeviceResource->UpdateResource (Resource); 00248 } 00249 00250 private: 00252 NObjectType *m_ResourceType; 00253 }; 00254 00255 template<typename IdType, typename ResourceType> 00256 class TResourceCache: public NResourceSet 00257 { 00258 public: 00259 std::map< IdType, ObjectPtr< ResourceType > > ResourceMap; 00260 00261 // Resource factory instances for each ResourceData/CachedResourceData pair. 00262 std::vector<NResourceFactory *> ResourceFactories; 00263 00264 // Resource updater instances for each ResourceData type. 00265 std::vector<NResourceUpdater *> ResourceUpdaters; 00266 00267 00268 TResourceCache() 00269 : NResourceSet() 00270 {} 00271 00272 void Flush() 00273 { 00274 // See the language FAQ 35.18 at http://www.parashift.com/c++-faq-lite/templates.html for why the "typename". 00275 typename std::map< IdType, ObjectPtr< ResourceType > >::iterator It; 00276 00277 for (It = ResourceMap.begin(); It != ResourceMap.end(); It++) 00278 { 00279 // ObjectPtr< ResourceType > CachedResource = (*It).second; 00280 // CachedResource->_cached = 0; 00281 // CachedResource.Release(); 00282 (*It).second->_cached = 0; 00283 (*It).second.Release(); 00284 } 00285 00286 // Erases all elements from the map. 00287 ResourceMap.clear(); 00288 } 00289 00290 void AddCachedResource (const IdType &Id, ObjectPtr< ResourceType > Resource) 00291 { 00292 typedef std::map< IdType, ObjectPtr< ResourceType > > MapType; 00293 ResourceMap.insert (typename MapType::value_type (Id, Resource) ); 00294 Resource->_cached = 1; 00295 } 00296 00297 ObjectPtr<ResourceType> FindCachedResourceById (const IdType &Id) 00298 { 00299 typedef std::map< IdType, ObjectPtr< ResourceType > > MapType; 00300 typename MapType::iterator it = ResourceMap.find (Id); 00301 00302 if (it != ResourceMap.end() ) 00303 return (*it).second; 00304 00305 return ObjectPtr<ResourceType> (0); 00306 } 00307 00312 void FlushResourceId(const IdType &Id) 00313 { 00314 ObjectPtr<ResourceType> CachedResource(0); 00315 00316 typedef std::map<IdType, ObjectPtr<ResourceType> > MapType; 00317 typename MapType::iterator it = ResourceMap.find(Id); 00318 00319 if(it != ResourceMap.end()) 00320 CachedResource = (*it).second; 00321 00322 if(CachedResource.IsValid()) 00323 { 00324 ResourceMap.erase(it); 00325 CachedResource->_cached = false; 00326 } 00327 } 00328 00329 virtual void FlushResource (CachedResourceData *Resource) 00330 { 00331 typedef std::map< IdType, ObjectPtr< ResourceType > > MapType; 00332 typename MapType::iterator it; 00333 00334 for (it = ResourceMap.begin(); it != ResourceMap.end(); it++) 00335 { 00336 ObjectPtr< ResourceType > CachedResource = (*it).second; 00337 00338 if (CachedResource == Resource) 00339 { 00340 ResourceMap.erase (it); 00341 CachedResource->_cached = 0; // Make sure that if the following line deletes the resource, it doesn't try to remove itself from the TDynamicMap we're iterating over. 00342 return; 00343 } 00344 } 00345 } 00346 00347 // Register CachedResourceData with the corresponding ResourceData 00348 virtual void InitializeResourceFactories() = 0; 00349 00350 std::vector<NResourceFactory *>& GetResourceFactories (void) 00351 { 00352 return (ResourceFactories); 00353 } 00354 std::vector<NResourceUpdater *>& GetResourceUpdaters (void) 00355 { 00356 return (ResourceUpdaters); 00357 } 00358 }; 00359 00360 class NResourceCache: public TResourceCache<int, CachedResourceData> 00361 { 00362 public: 00363 NResourceCache() 00364 : TResourceCache<int, CachedResourceData>() 00365 {} 00366 00367 ObjectPtr< CachedResourceData > GetCachedResource (ResourceData *Source); 00368 bool IsCachedResource (ResourceData *Source); 00369 00370 virtual void InitializeResourceFactories(); 00371 // virtual void FreeResource (ResourceData *Resource) 00372 // { 00373 // FlushResourceId(Resource->GetResourceIndex()); 00374 // } 00375 }; 00376 00377 00379 00380 } 00381 00382 #endif // GLRESOURCEMANAGER_H 00383