diff --git a/include/Nazara/Core/ResourceLoader.hpp b/include/Nazara/Core/ResourceLoader.hpp index a33341a18..be02238d3 100644 --- a/include/Nazara/Core/ResourceLoader.hpp +++ b/include/Nazara/Core/ResourceLoader.hpp @@ -9,7 +9,6 @@ #include #include -#include #include class NzInputStream; @@ -18,17 +17,21 @@ template class NzResourceLoader { public: - using CheckFunction = bool (*)(NzInputStream& stream, const Parameters& parameters); - using LoadFunction = bool (*)(Type* resource, NzInputStream& stream, const Parameters& parameters); + using ExtensionGetter = bool (*)(const NzString& extension); + using FileLoader = bool (*)(Type* resource, const NzString& filePath, const Parameters& parameters); + using StreamChecker = bool (*)(NzInputStream& stream, const Parameters& parameters); + using StreamLoader = bool (*)(Type* resource, NzInputStream& stream, const Parameters& parameters); + + static bool IsExtensionSupported(const NzString& extension); static bool LoadFromFile(Type* resource, const NzString& filePath, const Parameters& parameters = Parameters()); static bool LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters = Parameters()); static bool LoadFromStream(Type* resource, NzInputStream& stream, const Parameters& parameters = Parameters()); - static void RegisterLoader(const NzString& fileExtensions, CheckFunction checkFunc, LoadFunction loadfunc); - static void UnregisterLoader(const NzString& fileExtensions, CheckFunction checkFunc, LoadFunction loadfunc); + static void RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr); + static void UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr); - using Loader = std::tuple, CheckFunction, LoadFunction>; + using Loader = std::tuple; using LoaderList = std::list; }; diff --git a/include/Nazara/Core/ResourceLoader.inl b/include/Nazara/Core/ResourceLoader.inl index 7ff8b1200..1e6e7bcc5 100644 --- a/include/Nazara/Core/ResourceLoader.inl +++ b/include/Nazara/Core/ResourceLoader.inl @@ -9,6 +9,20 @@ #include #include +template +bool NzResourceLoader::IsExtensionSupported(const NzString& extension) +{ + for (auto loader = Type::s_loaders.begin(); loader != Type::s_loaders.end(); ++loader) + { + ExtensionGetter isExtensionSupported = std::get<0>(*loader); + + if (isExtensionSupported && isExtensionSupported(extension)) + return true; + } + + return false; +} + template bool NzResourceLoader::LoadFromFile(Type* resource, const NzString& filePath, const Parameters& parameters) { @@ -28,38 +42,54 @@ bool NzResourceLoader::LoadFromFile(Type* resource, const NzSt return false; } - NzFile file(path, NzFile::ReadOnly); - if (!file.IsOpen()) - { - NazaraError("Failed to open \"" + path + '"'); - return false; - } + NzFile file(path); // Ouvert seulement en cas de besoin for (auto loader = Type::s_loaders.begin(); loader != Type::s_loaders.end(); ++loader) { - for (const NzString& loaderExt : std::get<0>(*loader)) + ExtensionGetter isExtensionSupported = std::get<0>(*loader); + if (!isExtensionSupported || !isExtensionSupported(ext)) + continue; + + StreamChecker checkFunc = std::get<1>(*loader); + StreamLoader streamLoader = std::get<2>(*loader); + FileLoader fileLoader = std::get<3>(*loader); + + if (checkFunc && !file.IsOpen()) { - int cmp = NzString::Compare(loaderExt, ext); - if (cmp == 0) + if (!file.Open(NzFile::ReadOnly)) + { + NazaraError("Failed to load file: unable to open file"); + return false; + } + } + + if (fileLoader) + { + if (checkFunc) { file.SetCursorPos(0); - if (!std::get<1>(*loader)(file, parameters)) + if (!checkFunc(file, parameters)) continue; - - file.SetCursorPos(0); - - // Chargement de la ressource - if (std::get<2>(*loader)(resource, file, parameters)) - return true; - - NazaraWarning("Loader failed"); } - else if (cmp < 0) // S'il est encore possible que l'extension se situe après + + if (fileLoader(resource, filePath, parameters)) + return true; + } + else + { + file.SetCursorPos(0); + + if (!checkFunc(file, parameters)) continue; - break; + file.SetCursorPos(0); + + if (streamLoader(resource, file, parameters)) + return true; } + + NazaraWarning("Loader failed"); } NazaraError("Failed to load file: no loader"); @@ -95,17 +125,20 @@ bool NzResourceLoader::LoadFromStream(Type* resource, NzInputS nzUInt64 streamPos = stream.GetCursorPos(); for (auto loader = Type::s_loaders.begin(); loader != Type::s_loaders.end(); ++loader) { + StreamChecker checkFunc = std::get<1>(*loader); + StreamLoader streamLoader = std::get<2>(*loader); + stream.SetCursorPos(streamPos); // Le loader supporte-t-il les données ? - if (!std::get<1>(*loader)(stream, parameters)) + if (!checkFunc(stream, parameters)) continue; // On repositionne le stream à son ancienne position stream.SetCursorPos(streamPos); // Chargement de la ressource - if (std::get<2>(*loader)(resource, stream, parameters)) + if (streamLoader(resource, stream, parameters)) return true; NazaraWarning("Loader failed"); @@ -116,28 +149,31 @@ bool NzResourceLoader::LoadFromStream(Type* resource, NzInputS } template -void NzResourceLoader::RegisterLoader(const NzString& fileExtensions, CheckFunction checkFunc, LoadFunction loadFunc) +void NzResourceLoader::RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader) { - ///FIXME: Trouver une alternative à ce code monstrueux - std::vector exts; - fileExtensions.SplitAny(exts, " /\\.,;|-_"); + #if NAZARA_CORE_SAFE + if (streamLoader) + { + if (!checkFunc) + { + NazaraError("StreamLoader present without StreamChecker"); + return; + } + } + else if (!fileLoader) + { + NazaraError("Neither FileLoader nor StreamLoader were found"); + return; + } + #endif - std::set extensions; - std::copy(exts.begin(), exts.end(), std::inserter(extensions, extensions.begin())); - - Type::s_loaders.push_front(std::make_tuple(std::move(extensions), checkFunc, loadFunc)); + Type::s_loaders.push_front(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader)); } template -void NzResourceLoader::UnregisterLoader(const NzString& fileExtensions, CheckFunction checkFunc, LoadFunction loadFunc) +void NzResourceLoader::UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader) { - std::vector exts; - fileExtensions.SplitAny(exts, " /\\.,;|-_"); - - std::set extensions; - std::copy(exts.begin(), exts.end(), std::inserter(extensions, extensions.begin())); - - Type::s_loaders.remove(std::make_tuple(std::move(extensions), checkFunc, loadFunc)); + Type::s_loaders.remove(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader)); } #include diff --git a/src/Nazara/Renderer/Loaders/Texture/Loader.cpp b/src/Nazara/Renderer/Loaders/Texture/Loader.cpp index 353d01adb..655729805 100644 --- a/src/Nazara/Renderer/Loaders/Texture/Loader.cpp +++ b/src/Nazara/Renderer/Loaders/Texture/Loader.cpp @@ -38,11 +38,10 @@ namespace void NzLoaders_Texture_Register() { - ///FIXME: Pas bon - NzMaterialLoader::RegisterLoader("bmp,gif,hdr,jpg,jpeg,pic,png,psd,tga", Check, Load); + NzMaterialLoader::RegisterLoader(NzImageLoader::IsExtensionSupported, Check, Load); } void NzLoaders_Texture_Unregister() { - NzMaterialLoader::UnregisterLoader("bmp,gif,hdr,jpg,jpeg,pic,png,psd,tga", Check, Load); + NzMaterialLoader::UnregisterLoader(NzImageLoader::IsExtensionSupported, Check, Load); } diff --git a/src/Nazara/Utility/Loaders/MD2/Loader.cpp b/src/Nazara/Utility/Loaders/MD2/Loader.cpp index 3cd897aaf..da2e022b1 100644 --- a/src/Nazara/Utility/Loaders/MD2/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD2/Loader.cpp @@ -19,7 +19,11 @@ namespace { - /// Loader de mesh + bool IsSupported(const NzString& extension) + { + return (extension == "md2"); + } + bool Check(NzInputStream& stream, const NzMeshParams& parameters) { NazaraUnused(parameters); @@ -221,10 +225,10 @@ namespace void NzLoaders_MD2_Register() { - NzMeshLoader::RegisterLoader("md2", Check, Load); + NzMeshLoader::RegisterLoader(IsSupported, Check, Load); } void NzLoaders_MD2_Unregister() { - NzMeshLoader::UnregisterLoader("md2", Check, Load); + NzMeshLoader::UnregisterLoader(IsSupported, Check, Load); } diff --git a/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp b/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp index 2e7290fb0..42f2dd557 100644 --- a/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp @@ -8,6 +8,11 @@ namespace { + bool IsSupported(const NzString& extension) + { + return (extension == "md5anim"); + } + bool Check(NzInputStream& stream, const NzAnimationParams& parameters) { NzMD5AnimParser parser(stream, parameters); @@ -23,10 +28,10 @@ namespace void NzLoaders_MD5Anim_Register() { - NzAnimationLoader::RegisterLoader("md5anim", Check, Load); + NzAnimationLoader::RegisterLoader(IsSupported, Check, Load); } void NzLoaders_MD5Anim_Unregister() { - NzAnimationLoader::UnregisterLoader("md5anim", Check, Load); + NzAnimationLoader::UnregisterLoader(IsSupported, Check, Load); } diff --git a/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp b/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp index 9c937299d..661a52e6b 100644 --- a/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp @@ -8,6 +8,11 @@ namespace { + bool IsSupported(const NzString& extension) + { + return (extension == "md5mesh"); + } + bool Check(NzInputStream& stream, const NzMeshParams& parameters) { NzMD5MeshParser parser(stream, parameters); @@ -23,10 +28,10 @@ namespace void NzLoaders_MD5Mesh_Register() { - NzMeshLoader::RegisterLoader("md5mesh", Check, Load); + NzMeshLoader::RegisterLoader(IsSupported, Check, Load); } void NzLoaders_MD5Mesh_Unregister() { - NzMeshLoader::UnregisterLoader("md5mesh", Check, Load); + NzMeshLoader::UnregisterLoader(IsSupported, Check, Load); } diff --git a/src/Nazara/Utility/Loaders/PCX/Loader.cpp b/src/Nazara/Utility/Loaders/PCX/Loader.cpp index d812d3597..af488d96b 100644 --- a/src/Nazara/Utility/Loaders/PCX/Loader.cpp +++ b/src/Nazara/Utility/Loaders/PCX/Loader.cpp @@ -39,6 +39,11 @@ namespace //static_assert(sizeof(pcx_header) == 1024, "PCX header must be 1024 bytes sized"); + bool IsSupported(const NzString& extension) + { + return (extension == "pcx"); + } + bool Check(NzInputStream& stream, const NzImageParams& parameters) { NazaraUnused(parameters); @@ -339,10 +344,10 @@ namespace void NzLoaders_PCX_Register() { - NzImageLoader::RegisterLoader("pcx", Check, Load); + NzImageLoader::RegisterLoader(IsSupported, Check, Load); } void NzLoaders_PCX_Unregister() { - NzImageLoader::UnregisterLoader("pcx", Check, Load); + NzImageLoader::UnregisterLoader(IsSupported, Check, Load); } diff --git a/src/Nazara/Utility/Loaders/STB/Loader.cpp b/src/Nazara/Utility/Loaders/STB/Loader.cpp index 40607f4a7..52829c638 100644 --- a/src/Nazara/Utility/Loaders/STB/Loader.cpp +++ b/src/Nazara/Utility/Loaders/STB/Loader.cpp @@ -37,6 +37,12 @@ namespace static stbi_io_callbacks callbacks = {Read, Skip, Eof}; + bool IsSupported(const NzString& extension) + { + static std::set supportedExtensions = {"bmp", "gif", "hdr", "jpg", "jpeg", "pic", "png", "psd", "tga"}; + return supportedExtensions.find(extension) != supportedExtensions.end(); + } + bool Check(NzInputStream& stream, const NzImageParams& parameters) { NazaraUnused(parameters); @@ -117,10 +123,10 @@ namespace void NzLoaders_STB_Register() { - NzImageLoader::RegisterLoader("bmp,gif,hdr,jpg,jpeg,pic,png,psd,tga", Check, Load); + NzImageLoader::RegisterLoader(IsSupported, Check, Load); } void NzLoaders_STB_Unregister() { - NzImageLoader::UnregisterLoader("bmp,gif,hdr,jpg,jpeg,pic,png,psd,tga", Check, Load); + NzImageLoader::UnregisterLoader(IsSupported, Check, Load); }