ResourceCache.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. //
  2. // Copyright (c) 2008-2014 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "File.h"
  24. #include "HashSet.h"
  25. #include "Resource.h"
  26. namespace Urho3D
  27. {
  28. class FileWatcher;
  29. class PackageFile;
  30. /// Sets to priority so that a package or file is pushed to the end of the vector.
  31. static const unsigned int PRIORITY_LAST = -1;
  32. /// Container of resources with specific type.
  33. struct ResourceGroup
  34. {
  35. /// Construct with defaults.
  36. ResourceGroup() :
  37. memoryBudget_(0),
  38. memoryUse_(0)
  39. {
  40. }
  41. /// Memory budget.
  42. unsigned memoryBudget_;
  43. /// Current memory use.
  44. unsigned memoryUse_;
  45. /// Resources.
  46. HashMap<StringHash, SharedPtr<Resource> > resources_;
  47. };
  48. /// %Resource cache subsystem. Loads resources on demand and stores them for later access.
  49. class URHO3D_API ResourceCache : public Object
  50. {
  51. OBJECT(ResourceCache);
  52. public:
  53. /// Construct.
  54. ResourceCache(Context* context);
  55. /// Destruct. Free all resources.
  56. virtual ~ResourceCache();
  57. /// Add a resource load directory. Optional priority parameter which will control search order.
  58. bool AddResourceDir(const String& pathName, unsigned int priority = PRIORITY_LAST );
  59. /// Add a package file for loading resources from. Optional priority parameter which will control search order.
  60. void AddPackageFile(PackageFile* package, unsigned int priority = PRIORITY_LAST );
  61. /// Add a manually created resource. Must be uniquely named.
  62. bool AddManualResource(Resource* resource);
  63. /// Remove a resource load directory.
  64. void RemoveResourceDir(const String& pathName);
  65. /// Remove a package file. Optionally release the resources loaded from it.
  66. void RemovePackageFile(PackageFile* package, bool releaseResources = true, bool forceRelease = false);
  67. /// Remove a package file by name. Optionally release the resources loaded from it.
  68. void RemovePackageFile(const String& fileName, bool releaseResources = true, bool forceRelease = false);
  69. /// Release a resource by name.
  70. void ReleaseResource(ShortStringHash type, const String& name, bool force = false);
  71. /// Release all resources of a specific type.
  72. void ReleaseResources(ShortStringHash type, bool force = false);
  73. /// Release resources of a specific type and partial name.
  74. void ReleaseResources(ShortStringHash type, const String& partialName, bool force = false);
  75. /// Release resources of all types by partial name.
  76. void ReleaseResources(const String& partialName, bool force = false);
  77. /// Release all resources. When called with the force flag false, releases all currently unused resources.
  78. void ReleaseAllResources(bool force = false);
  79. /// Reload a resource. Return false and release it if fails.
  80. bool ReloadResource(Resource* resource);
  81. /// Set memory budget for a specific resource type, default 0 is unlimited.
  82. void SetMemoryBudget(ShortStringHash type, unsigned budget);
  83. /// Enable or disable automatic reloading of resources as files are modified. Default false.
  84. void SetAutoReloadResources(bool enable);
  85. /// Enable or disable returning resources that failed to load. Default false. This may be useful in editing to not lose resource ref attributes.
  86. void SetReturnFailedResources(bool enable);
  87. /// Define whether when getting resources should check package files or directories first. True for packages, false for directories.
  88. void SetSearchPackagesFirst(bool value) { searchPackagesFirst_ = value; }
  89. /// Open and return a file from the resource load paths or from inside a package file. If not found, use a fallback search with absolute path. Return null if fails.
  90. SharedPtr<File> GetFile(const String& name, bool sendEventOnFailure = true);
  91. /// Return a resource by type and name. Load if not loaded yet. Return null if not found or if fails, unless SetReturnFailedResources(true) has been called.
  92. Resource* GetResource(ShortStringHash type, const String& name, bool sendEventOnFailure = true);
  93. /// Return a resource by type and name. Load if not loaded yet. Return null if not found or if fails, unless SetReturnFailedResources(true) has been called.
  94. Resource* GetResource(ShortStringHash type, const char* name, bool sendEventOnFailure = true);
  95. /// Return all loaded resources of a specific type.
  96. void GetResources(PODVector<Resource*>& result, ShortStringHash type) const;
  97. /// Return all loaded resources.
  98. const HashMap<ShortStringHash, ResourceGroup>& GetAllResources() const { return resourceGroups_; }
  99. /// Return added resource load directories.
  100. const Vector<String>& GetResourceDirs() const { return resourceDirs_; }
  101. /// Return added package files.
  102. const Vector<SharedPtr<PackageFile> >& GetPackageFiles() const { return packages_; }
  103. /// Template version of returning a resource by name.
  104. template <class T> T* GetResource(const String& name, bool sendEventOnFailure = true);
  105. /// Template version of returning a resource by name.
  106. template <class T> T* GetResource(const char* name, bool sendEventOnFailure = true);
  107. /// Template version of returning loaded resources of a specific type.
  108. template <class T> void GetResources(PODVector<T*>& result) const;
  109. /// Return whether a file exists by name.
  110. bool Exists(const String& name) const;
  111. /// Return memory budget for a resource type.
  112. unsigned GetMemoryBudget(ShortStringHash type) const;
  113. /// Return total memory use for a resource type.
  114. unsigned GetMemoryUse(ShortStringHash type) const;
  115. /// Return total memory use for all resources.
  116. unsigned GetTotalMemoryUse() const;
  117. /// Return full absolute file name of resource if possible.
  118. String GetResourceFileName(const String& name) const;
  119. /// Return whether automatic resource reloading is enabled.
  120. bool GetAutoReloadResources() const { return autoReloadResources_; }
  121. /// Return whether resources that failed to load are returned.
  122. bool GetReturnFailedResources() const { return returnFailedResources_; }
  123. /// Define whether when getting resources should check package files or directories first.
  124. bool GetSearchPackagesFirst() const { return searchPackagesFirst_; }
  125. /// Return either the path itself or its parent, based on which of them has recognized resource subdirectories.
  126. String GetPreferredResourceDir(const String& path) const;
  127. /// Remove unsupported constructs from the resource name to prevent ambiguity, and normalize absolute filename to resource path relative if possible.
  128. String SanitateResourceName(const String& name) const;
  129. /// Remove unnecessary constructs from a resource directory name and ensure it to be an absolute path.
  130. String SanitateResourceDirName(const String& name) const;
  131. /// Store a dependency for a resource. If a dependency file changes, the resource will be reloaded.
  132. void StoreResourceDependency(Resource* resource, const String& dependency);
  133. /// Reset dependencies for a resource.
  134. void ResetDependencies(Resource* resource);
  135. private:
  136. /// Find a resource.
  137. const SharedPtr<Resource>& FindResource(ShortStringHash type, StringHash nameHash);
  138. /// Find a resource by name only. Searches all type groups.
  139. const SharedPtr<Resource>& FindResource(StringHash nameHash);
  140. /// Release resources loaded from a package file.
  141. void ReleasePackageResources(PackageFile* package, bool force = false);
  142. /// Update a resource group. Recalculate memory use and release resources if over memory budget.
  143. void UpdateResourceGroup(ShortStringHash type);
  144. /// Handle begin frame event. Automatic resource reloads are processed here.
  145. void HandleBeginFrame(StringHash eventType, VariantMap& eventData);
  146. /// Search FileSystem for File.
  147. File* SearchResourceDirs(const String& nameIn);
  148. /// Search Packages for File.
  149. File* SearchPackages(const String& nameIn);
  150. /// Resources by type.
  151. HashMap<ShortStringHash, ResourceGroup> resourceGroups_;
  152. /// Resource load directories.
  153. Vector<String> resourceDirs_;
  154. /// File watchers for resource directories, if automatic reloading enabled.
  155. Vector<SharedPtr<FileWatcher> > fileWatchers_;
  156. /// Package files.
  157. Vector<SharedPtr<PackageFile> > packages_;
  158. /// Dependent resources.
  159. HashMap<StringHash, HashSet<StringHash> > dependentResources_;
  160. /// Automatic resource reloading flag.
  161. bool autoReloadResources_;
  162. /// Return failed resources flag.
  163. bool returnFailedResources_;
  164. /// Search priority flag.
  165. bool searchPackagesFirst_;
  166. };
  167. template <class T> T* ResourceCache::GetResource(const String& name, bool sendEventOnFailure)
  168. {
  169. ShortStringHash type = T::GetTypeStatic();
  170. return static_cast<T*>(GetResource(type, name, sendEventOnFailure));
  171. }
  172. template <class T> T* ResourceCache::GetResource(const char* name, bool sendEventOnFailure)
  173. {
  174. ShortStringHash type = T::GetTypeStatic();
  175. return static_cast<T*>(GetResource(type, name, sendEventOnFailure));
  176. }
  177. template <class T> void ResourceCache::GetResources(PODVector<T*>& result) const
  178. {
  179. PODVector<Resource*>& resources = reinterpret_cast<PODVector<Resource*>&>(result);
  180. ShortStringHash type = T::GetTypeStatic();
  181. GetResources(resources, type);
  182. // Perform conversion of the returned pointers
  183. for (unsigned i = 0; i < result.Size(); ++i)
  184. {
  185. Resource* resource = resources[i];
  186. result[i] = static_cast<T*>(resource);
  187. }
  188. }
  189. /// Register Resource library subsystems and objects.
  190. void URHO3D_API RegisterResourceLibrary(Context* context);
  191. }