Refactor the way resources are loaded (#191)
* WIP * WIP * Font works * WIP: Only Music remains * Looks like it's working * Fix oopsie * Core/ObjectRef: Add cast functions * Update ChangeLog.md * Audio/SoundStream: Make sound stream thread-safe
This commit is contained in:
@@ -68,6 +68,10 @@ namespace Nz
|
||||
template<typename T> bool operator>=(const T& lhs, const ObjectRef<T>& rhs);
|
||||
template<typename T> bool operator>=(const ObjectRef<T>& lhs, const T& rhs);
|
||||
|
||||
template<typename T, typename U> ObjectRef<T> ConstRefCast(const ObjectRef<U>& ref);
|
||||
template<typename T, typename U> ObjectRef<T> DynamicRefCast(const ObjectRef<U>& ref);
|
||||
template<typename T, typename U> ObjectRef<T> ReinterpretRefCast(const ObjectRef<U>& ref);
|
||||
template<typename T, typename U> ObjectRef<T> StaticRefCast(const ObjectRef<U>& ref);
|
||||
|
||||
template<typename T> struct PointedType<ObjectRef<T>> { using type = T; };
|
||||
template<typename T> struct PointedType<ObjectRef<T> const> { using type = T; };
|
||||
|
||||
@@ -480,6 +480,60 @@ namespace Nz
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Casts an ObjectRef from one type to another using static_cast
|
||||
* \return Reference to the casted object
|
||||
*
|
||||
* \param ref The reference to convert
|
||||
*
|
||||
* \remark It is an undefined behavior to cast between incompatible types
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
ObjectRef<T> ConstRefCast(const ObjectRef<U>& ref)
|
||||
{
|
||||
return ObjectRef<T>(const_cast<T*>(ref.Get()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Casts an ObjectRef from one type to another using static_cast
|
||||
* \return Reference to the casted object
|
||||
*
|
||||
* \param ref The reference to convert
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
ObjectRef<T> DynamicRefCast(const ObjectRef<U>& ref)
|
||||
{
|
||||
return ObjectRef<T>(dynamic_cast<T*>(ref.Get()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Casts an ObjectRef from one type to another using static_cast
|
||||
* \return Reference to the casted object
|
||||
*
|
||||
* \param ref The reference to convert
|
||||
*
|
||||
* \remark It is an undefined behavior to cast between incompatible types
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
ObjectRef<T> ReinterpretRefCast(const ObjectRef<U>& ref)
|
||||
{
|
||||
return ObjectRef<T>(static_cast<T*>(ref.Get()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Casts an ObjectRef from one type to another using static_cast
|
||||
* \return Reference to the casted object
|
||||
*
|
||||
* \param ref The reference to convert
|
||||
*
|
||||
* \remark It is an undefined behavior to cast between incompatible types
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
ObjectRef<T> StaticRefCast(const ObjectRef<U>& ref)
|
||||
{
|
||||
return ObjectRef<T>(static_cast<T*>(ref.Get()));
|
||||
}
|
||||
}
|
||||
|
||||
namespace std
|
||||
@@ -504,3 +558,4 @@ namespace std
|
||||
}
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
#include "ObjectRef.hpp"
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#define NAZARA_RESOURCELOADER_HPP
|
||||
|
||||
#include <Nazara/Core/Enums.hpp>
|
||||
#include <Nazara/Core/ObjectRef.hpp>
|
||||
#include <Nazara/Core/RefCounted.hpp>
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Core/ResourceParameters.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
@@ -28,19 +30,19 @@ namespace Nz
|
||||
|
||||
public:
|
||||
using ExtensionGetter = bool (*)(const String& extension);
|
||||
using FileLoader = bool (*)(Type* resource, const String& filePath, const Parameters& parameters);
|
||||
using MemoryLoader = bool (*)(Type* resource, const void* data, std::size_t size, const Parameters& parameters);
|
||||
using FileLoader = ObjectRef<Type> (*)(const String& filePath, const Parameters& parameters);
|
||||
using MemoryLoader = ObjectRef<Type> (*)(const void* data, std::size_t size, const Parameters& parameters);
|
||||
using StreamChecker = Ternary (*)(Stream& stream, const Parameters& parameters);
|
||||
using StreamLoader = bool (*)(Type* resource, Stream& stream, const Parameters& parameters);
|
||||
using StreamLoader = ObjectRef<Type> (*)(Stream& stream, const Parameters& parameters);
|
||||
|
||||
ResourceLoader() = delete;
|
||||
~ResourceLoader() = delete;
|
||||
|
||||
static bool IsExtensionSupported(const String& extension);
|
||||
|
||||
static bool LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters = Parameters());
|
||||
static bool LoadFromMemory(Type* resource, const void* data, std::size_t size, const Parameters& parameters = Parameters());
|
||||
static bool LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters = Parameters());
|
||||
static ObjectRef<Type> LoadFromFile(const String& filePath, const Parameters& parameters = Parameters());
|
||||
static ObjectRef<Type> LoadFromMemory(const void* data, std::size_t size, const Parameters& parameters = Parameters());
|
||||
static ObjectRef<Type> LoadFromStream(Stream& stream, const Parameters& parameters = Parameters());
|
||||
|
||||
static void RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr);
|
||||
static void UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr);
|
||||
|
||||
@@ -53,9 +53,8 @@ namespace Nz
|
||||
* \remark Produces a NazaraError if all loaders failed or no loader was found
|
||||
*/
|
||||
template<typename Type, typename Parameters>
|
||||
bool ResourceLoader<Type, Parameters>::LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters)
|
||||
ObjectRef<Type> ResourceLoader<Type, Parameters>::LoadFromFile(const String& filePath, const Parameters& parameters)
|
||||
{
|
||||
NazaraAssert(resource, "Invalid resource");
|
||||
NazaraAssert(parameters.IsValid(), "Invalid parameters");
|
||||
|
||||
String path = File::NormalizePath(filePath);
|
||||
@@ -63,7 +62,7 @@ namespace Nz
|
||||
if (ext.IsEmpty())
|
||||
{
|
||||
NazaraError("Failed to get file extension from \"" + filePath + '"');
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
File file(path); // Open only if needed
|
||||
@@ -84,7 +83,7 @@ namespace Nz
|
||||
if (!file.Open(OpenMode_ReadOnly))
|
||||
{
|
||||
NazaraError("Failed to load file: unable to open \"" + filePath + '"');
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,10 +106,11 @@ namespace Nz
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (fileLoader(resource, filePath, parameters))
|
||||
ObjectRef<Type> resource = fileLoader(filePath, parameters);
|
||||
if (resource)
|
||||
{
|
||||
resource->SetFilePath(filePath);
|
||||
return true;
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -125,10 +125,11 @@ namespace Nz
|
||||
|
||||
file.SetCursorPos(0);
|
||||
|
||||
if (streamLoader(resource, file, parameters))
|
||||
ObjectRef<Type> resource = streamLoader(file, parameters);
|
||||
if (resource)
|
||||
{
|
||||
resource->SetFilePath(filePath);
|
||||
return true;
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +142,7 @@ namespace Nz
|
||||
else
|
||||
NazaraError("Failed to load file: no loader found for extension \"" + ext + '"');
|
||||
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -160,9 +161,8 @@ namespace Nz
|
||||
* \remark Produces a NazaraError if all loaders failed or no loader was found
|
||||
*/
|
||||
template<typename Type, typename Parameters>
|
||||
bool ResourceLoader<Type, Parameters>::LoadFromMemory(Type* resource, const void* data, std::size_t size, const Parameters& parameters)
|
||||
ObjectRef<Type> ResourceLoader<Type, Parameters>::LoadFromMemory(const void* data, std::size_t size, const Parameters& parameters)
|
||||
{
|
||||
NazaraAssert(resource, "Invalid resource");
|
||||
NazaraAssert(data, "Invalid data pointer");
|
||||
NazaraAssert(size, "No data to load");
|
||||
NazaraAssert(parameters.IsValid(), "Invalid parameters");
|
||||
@@ -195,8 +195,9 @@ namespace Nz
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (memoryLoader(resource, data, size, parameters))
|
||||
return true;
|
||||
ObjectRef<Type> resource = memoryLoader(data, size, parameters);
|
||||
if (resource)
|
||||
return resource;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -210,8 +211,9 @@ namespace Nz
|
||||
|
||||
stream.SetCursorPos(0);
|
||||
|
||||
if (streamLoader(resource, stream, parameters))
|
||||
return true;
|
||||
ObjectRef<Type> resource = streamLoader(stream, parameters);
|
||||
if (resource)
|
||||
return resource;
|
||||
}
|
||||
|
||||
if (recognized == Ternary_True)
|
||||
@@ -223,7 +225,7 @@ namespace Nz
|
||||
else
|
||||
NazaraError("Failed to load file: no loader found");
|
||||
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -241,9 +243,8 @@ namespace Nz
|
||||
* \remark Produces a NazaraError if all loaders failed or no loader was found
|
||||
*/
|
||||
template<typename Type, typename Parameters>
|
||||
bool ResourceLoader<Type, Parameters>::LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters)
|
||||
ObjectRef<Type> ResourceLoader<Type, Parameters>::LoadFromStream(Stream& stream, const Parameters& parameters)
|
||||
{
|
||||
NazaraAssert(resource, "Invalid resource");
|
||||
NazaraAssert(stream.GetCursorPos() < stream.GetSize(), "No data to load");
|
||||
NazaraAssert(parameters.IsValid(), "Invalid parameters");
|
||||
|
||||
@@ -267,8 +268,9 @@ namespace Nz
|
||||
stream.SetCursorPos(streamPos);
|
||||
|
||||
// Load of the resource
|
||||
if (streamLoader(resource, stream, parameters))
|
||||
return true;
|
||||
ObjectRef<Type> resource = streamLoader(stream, parameters);
|
||||
if (resource)
|
||||
return resource;
|
||||
|
||||
if (recognized == Ternary_True)
|
||||
NazaraWarning("Loader failed");
|
||||
@@ -279,7 +281,7 @@ namespace Nz
|
||||
else
|
||||
NazaraError("Failed to load file: no loader found");
|
||||
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -37,14 +37,8 @@ namespace Nz
|
||||
auto it = Type::s_managerMap.find(absolutePath);
|
||||
if (it == Type::s_managerMap.end())
|
||||
{
|
||||
ObjectRef<Type> resource = Type::New();
|
||||
ObjectRef<Type> resource = Type::LoadFromFile(absolutePath, GetDefaultParameters());
|
||||
if (!resource)
|
||||
{
|
||||
NazaraError("Failed to create resource");
|
||||
return ObjectRef<Type>();
|
||||
}
|
||||
|
||||
if (!resource->LoadFromFile(absolutePath, GetDefaultParameters()))
|
||||
{
|
||||
NazaraError("Failed to load resource from file: " + absolutePath);
|
||||
return ObjectRef<Type>();
|
||||
|
||||
Reference in New Issue
Block a user