Просмотр исходного кода

Initial implementation of the new ResourceManager

Daniele Bartolini 13 лет назад
Родитель
Сommit
4912ffa8ac
3 измененных файлов с 153 добавлено и 187 удалено
  1. 14 71
      src/Resource.h
  2. 90 40
      src/ResourceManager.cpp
  3. 49 76
      src/ResourceManager.h

+ 14 - 71
src/Resource.h

@@ -25,84 +25,27 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #pragma once
 
+#include "Types.h"
+
 namespace crown
 {
 
-/**
-	Enumerates the loading state of a resource.
-*/
-enum LoadState
+/// Enumerates the loading state of a resource
+enum ResourceState
 {
-	LS_UNLOADED		= 0,	//!< The resouce is not loaded
-	LS_LOADING		= 1,	//!< The resource is loading
-	LS_LOADED		= 2,	//!< The resource is loaded
-	LS_UNLOADING	= 3		//!< The resource is unloading
+	RS_UNLOADED		= 0,		//< The resource is not loaded, so it cannot be used
+	RS_LOADING		= 1,		//< The resource loader started to load the resource but it is yet not ready to use
+	RS_LOADED		= 2			//< The resource loader finished to load the texture meaning it can be used
 };
 
-class ResourceManager;
-
-/**
-	Abstracts a generic resource.
-
-	Each resource is uniquely identified by its name.
-	The name of a resource is simply the path to the
-	corresponding file on the disk relative to the root path.
-
-	More info about the root path in Filesystem.
-
-	"textures/grass.tga" is a texture resource located at
-	"ROOT_PATH/textures/grass.tga".
-
-	Paths to resources follow the same conventions used
-	for referring to files on disk covered in Filesystem.
-
-	In order to save space and keep high performances, resource
-	names are stored as 64-bit int64_t sting hashes.
-*/
-class Resource
+/// ResourceId uniquely identifies a resource by its name and type.
+/// In order to speed up the lookup by the manager, it also keeps
+/// the index to the resource list where it is stored.
+struct ResourceId
 {
-
-public:
-
-						/**
-							Constructor.
-						*/
-						Resource() : mIsReloadable(false), mLoadState(LS_UNLOADED), mSize(0) {}
-						/**
-							Destructor.
-						*/
-	virtual				~Resource() { }
-						/**
-							Loads the resource.
-						*/
-	virtual void		Load(const char* name) { (void)name; }
-						/**
-							Unloads the resource and then optionally reloads it.
-						@param reload
-							Whether to reload after unloading
-						*/
-	virtual void		Unload(const char* name, bool reload) { (void)name; (void)reload; }
-						/**
-							Returns whether the resource is reloadable.
-						@return Whether is reloadable
-						*/
-	inline bool			IsReloadable() { return mIsReloadable; }
-						/**
-							Returns the loading state of the resource.
-						@return The loading state
-						*/
-	inline LoadState	GetLoadState() { return mLoadState; }
-						/**
-							Returns the resource's size in bytes.
-						@return The size in bytes
-						*/
-	inline size_t		GetSize() { return mSize; }
-
-protected:
-
-	bool				mIsReloadable;	//!< Whether is reloadable
-	LoadState			mLoadState;		//!< The loading state
-	size_t				mSize;			//!< The size in bytes
+	StringId32		name;
+	StringId32		type;
+	uint32_t		index;
 };
 
 } // namespace crown

+ 90 - 40
src/ResourceManager.cpp

@@ -25,89 +25,139 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #include "Types.h"
 #include "ResourceManager.h"
-#include "Str.h"
+#include "ResourceLoader.h"
+#include "String.h"
+#include <algorithm>
 
 namespace crown
 {
 
-ResourceManager::ResourceManager()
+//-----------------------------------------------------------------------------
+ResourceManager::ResourceManager() :
+	m_resource_loader(this),
+	m_resources(m_allocator)
 {
 }
 
+//-----------------------------------------------------------------------------
 ResourceManager::~ResourceManager()
 {
 }
 
-Resource* ResourceManager::Create(const char* name, bool& created)
+//-----------------------------------------------------------------------------
+ResourceId ResourceManager::load(const char* name)
 {
-	Resource* resource = GetByName(name);
+	StringId32 name_hash = string::Hash32(name);
 
-	created = false;
+	return load(name_hash);
+}
+
+//-----------------------------------------------------------------------------
+ResourceId ResourceManager::load(StringId32 name)
+{
+	// Search for an already existent resource
+	ResourceEntry* entry = std::find(m_resources.begin(), m_resources.end(), name);
 
-	if (resource == NULL)
+	// If resource not found
+	if (entry == m_resources.end())
 	{
-		resource = CreateSpecific(name);
-		mNameToResourceDict[Str::Hash64(name)] = resource;
-		created = true;
+		ResourceId id;
+		id.name = name;
+		id.index = m_resources.size();
+
+		ResourceEntry entry;
+		entry.id = id;
+		entry.state = RS_UNLOADED;
+		entry.references = 1;
+		entry.resource = NULL;
+
+		m_resources.push_back(entry);
+
+		m_resource_loader.load(id);
+
+		return id;
 	}
 
-	return resource;
+	entry->references++;
+	return entry->id;
 }
 
-Resource* ResourceManager::Load(const char* name)
+//-----------------------------------------------------------------------------
+void ResourceManager::unload(ResourceId name)
 {
-	bool created;
-	Resource* resource = Create(name, created);
-
-	if (resource != NULL && created)
+	assert(has(name));
+	
+	ResourceEntry& entry = m_resources[name.index];
+	
+	entry.references--;
+	
+	if (entry.references == 0)
 	{
-		resource->Load(name);
-	}
+		entry.state = RS_UNLOADED;
+		entry.resource = NULL;
 
-	return resource;
+		m_resource_loader.unload(name);
+	}
 }
 
-void ResourceManager::Unload(const char* name, bool reload)
+//-----------------------------------------------------------------------------
+void ResourceManager::reload(ResourceId name)
 {
-	Resource* resource = GetByName(name);
-
-	if (resource != NULL)
+	assert(has(name));
+	
+	ResourceEntry& entry = m_resources[name.index];
+	
+	if (entry.state == RS_LOADED)
 	{
-		resource->Unload(name, reload);
+	
 	}
 }
 
-void ResourceManager::Destroy(const char* name)
+//-----------------------------------------------------------------------------
+bool ResourceManager::has(ResourceId name)
 {
-	Resource* resource = GetByName(name);
+	if (m_resources.size() <= name.index)
+	{
+		return false;
+	}
 
-	if (resource != NULL)
+	if (m_resources[name.index].id.name == name.name)
 	{
-		resource->Unload(name, false);
-		DestroySpecific(name);
+		return true;
 	}
+
+	return false;
 }
 
-Resource* ResourceManager::GetByName(const char* name)
+//-----------------------------------------------------------------------------
+bool ResourceManager::is_loaded(ResourceId name)
 {
-	uint64_t nameHash = Str::Hash64(name);
-
-	if (mNameToResourceDict.Contains(nameHash))
+	if (has(name))
 	{
-		return mNameToResourceDict[nameHash];
+		return m_resources[name.index].state == RS_LOADED;
 	}
 
-	return NULL;
+	return false;
 }
 
-void ResourceManager::DestroySpecific(const char* name)
+//-----------------------------------------------------------------------------
+void ResourceManager::loading(ResourceId name)
 {
-	Resource* resource = GetByName(name);
+	assert(has(name) == true);
 
-	if (resource != NULL)
-	{
-		mNameToResourceDict.Remove(Str::Hash64(name));
-	}
+	m_resources[name.index].state = RS_LOADING;
+}
+
+//-----------------------------------------------------------------------------
+void ResourceManager::online(ResourceId name, void* resource)
+{
+	assert(has(name) == true);
+	//assert(resource != NULL);
+
+	ResourceEntry& entry = m_resources[name.index];
+
+	entry.resource = resource;
+	entry.state = RS_LOADED;
 }
 
 } // namespace crown

+ 49 - 76
src/ResourceManager.h

@@ -26,93 +26,66 @@ OTHER DEALINGS IN THE SOFTWARE.
 #pragma once
 
 #include "Types.h"
-#include "Dictionary.h"
+#include "List.h"
 #include "Resource.h"
+#include "ResourceLoader.h"
+#include "MallocAllocator.h"
 
 namespace crown
 {
 
-/**
-	Resource manager.
+struct ResourceEntry
+{
+	ResourceId		id;
+	ResourceState	state;
 
-	Keeps track of loaded resources.
-*/
+	uint32_t		references;
+
+	void*			resource;
+
+	bool			operator==(const StringId32& name)
+					{
+						return id.name == name;
+					}
+
+	bool			operator==(const ResourceEntry& b)
+					{
+						return id.name == b.id.name;
+					}
+};
+
+class ResourceLoader;
+
+/// Resource manager.
 class ResourceManager
 {
+public:
 
-	// FIXME: replace with hashmap
-	typedef Dictionary<StrId64, Resource*> NameToResourceDict;
+							ResourceManager();
+							~ResourceManager();
 
-public:
+	ResourceId				load(const char* name);
+	ResourceId				load(StringId32 name);
+
+	void					unload(ResourceId name);
+	void					reload(ResourceId name);
+
+	bool					has(ResourceId name);
+	bool					is_loaded(ResourceId name);
+	void					flush() { m_resource_loader.flush(); }
+
+private:
+
+	void					loading(ResourceId name);
+	void					online(ResourceId name, void* resource);
+
+private:
 
-	Resource*	Create(const char* name, bool& created);
-	void		Destroy(const char* name);
-
-	Resource*	Load(const char* name);
-	void		Unload(const char* name, bool reload);
-
-	Resource*	GetByName(const char* name);
-	int32_t		GetResourceCount() const;
-
-	/**
-	 * Creates a generic resource with the given name.
-	 * If a resource with the same name already exists, the
-	 * already existent resource will be returned. In order
-	 * to distinguish between a newly created resource or a
-	 * point32_ter to an existing one, you have to check
-	 * at the value returned by 'created'.
-	 * @param name The name of the resource
-	 * @param created Returns true if newly created, false otherwise
-	 * @return A point32_ter to the created resource
-	 */
-
-	/**
-	 * Loads a generic resource from file.
-	 * The name of the file determines the name of the resource and vice-versa.
-	 * @param name Tha name of the resource
-	 * @return A point32_ter to the loaded resource
-	 */
-
-	/**
-		Unloads a generic resource with the given name.
-	@param name
-		The name of the resource
-	@param reload
-		Whether to reload after unloading
-	*/
-
-	/**
-	 * Destroys a generic resource with the given name.
-	 * Causes the manager to remove the resource from its
-	 * int32_ternal list.
-	 * @note Destroying here is a misleading term since the
-	 * resource is not destroyed if there are other references
-	 * to it.
-	 * @param name The name of the resource
-	 */
-
-	/**
-	 * Returns a resource by its name.
-	 * If the resource does not exists, returns a null point32_ter.
-	 * @param name The name of the resource
-	 * @return A point32_ter to the resource
-	 */
-
-	/**
-	 * Returns the number of resources managed by this resource manager.
-	 * @return The number of resources
-	 */
-
-protected:
-
-						ResourceManager();		//!< Constructor
-	virtual				~ResourceManager();		//!< Destructor
-
-	virtual Resource*	CreateSpecific(const char* name) = 0;
-	virtual void		DestroySpecific(const char* name);
-
-	// Resource name -> Resource point32_ter
-	NameToResourceDict	mNameToResourceDict;
+	ResourceLoader			m_resource_loader;
+	MallocAllocator			m_allocator;
+	List<ResourceEntry>		m_resources;
+	
+	friend class			ResourceLoader;
 };
 
 } // namespace crown