Back to index

nux  3.0.0
GLResourceManager.h
Go to the documentation of this file.
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