NazaraEngine/include/Nazara/Utility/ResourceLoader.inl

192 lines
5.5 KiB
C++

// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/File.hpp>
#include <Nazara/Core/InputStream.hpp>
#include <Nazara/Utility/Config.hpp>
#include <Nazara/Utility/Debug.hpp>
template<typename Type, typename Parameters>
bool NzResourceLoader<Type, Parameters>::LoadResourceFromFile(Type* resource, const NzString& filePath, const Parameters& parameters)
{
#if NAZARA_UTILITY_SAFE
if (!parameters.IsValid())
{
NazaraError("Invalid Parameters");
return false;
}
#endif
NzString path = NzFile::NormalizePath(filePath);
NzString ext = path.SubstrFrom('.', -1, true);
if (ext.IsEmpty())
{
NazaraError("Failed to get file extension");
return false;
}
// Récupération de tous les loaders de cette extension
auto range = s_fileLoaders.equal_range(ext);
if (range.first == range.second)
{
NazaraError("No loader found for extension \"" + ext + '"');
return false;
}
// range.second est un itérateur vers l'élément après le dernier élémént du range
auto it = range.second;
do
{
it--;
// Chargement de la ressource
if (it->second(resource, filePath, parameters))
return true;
NazaraWarning("Loader failed");
}
while (it != range.first);
NazaraError("Failed to load file: all loaders failed");
return false;
}
template<typename Type, typename Parameters>
bool NzResourceLoader<Type, Parameters>::LoadResourceFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters)
{
#if NAZARA_UTILITY_SAFE
if (!parameters.IsValid())
{
NazaraError("Invalid Parameters");
return false;
}
if (!data || size == 0)
{
NazaraError("No data to load");
return false;
}
#endif
for (auto loader = s_memoryLoaders.rbegin(); loader != s_memoryLoaders.rend(); ++loader)
{
// Le loader supporte-t-il les données ?
if (!loader->first(data, size, parameters))
continue;
// Chargement de la ressource
if (loader->second(resource, data, size, parameters))
return true;
NazaraWarning("Loader failed");
}
NazaraError("Failed to load file: all loaders failed");
return false;
}
template<typename Type, typename Parameters>
bool NzResourceLoader<Type, Parameters>::LoadResourceFromStream(Type* resource, NzInputStream& stream, const Parameters& parameters)
{
#if NAZARA_UTILITY_SAFE
if (!parameters.IsValid())
{
NazaraError("Invalid Parameters");
return false;
}
if (stream.GetSize() == 0 || stream.GetCursorPos() >= stream.GetSize())
{
NazaraError("No data to load");
return false;
}
#endif
nzUInt64 streamPos = stream.GetCursorPos();
for (auto loader = s_streamLoaders.rbegin(); loader != s_streamLoaders.rend(); ++loader)
{
stream.SetCursorPos(streamPos);
// Le loader supporte-t-il les données ?
if (!loader->first(stream, parameters))
continue;
stream.SetCursorPos(streamPos);
// Chargement de la ressource
if (loader->second(resource, stream, parameters))
return true;
NazaraWarning("Loader failed");
}
NazaraError("Failed to load file: all loaders failed");
return false;
}
template<typename Type, typename Parameters>
void NzResourceLoader<Type, Parameters>::RegisterResourceFileLoader(const NzString& extensions, LoadFileFunction loadFile)
{
std::vector<NzString> exts;
extensions.SplitAny(exts, " /\\*.,;|-_");
for (const NzString& ext : exts)
s_fileLoaders.insert(std::make_pair(ext, loadFile));
}
template<typename Type, typename Parameters>
void NzResourceLoader<Type, Parameters>::RegisterResourceMemoryLoader(IsMemoryLoadingSupportedFunction isLoadingSupported, LoadMemoryFunction loadMemory)
{
s_memoryLoaders.push_back(std::make_pair(isLoadingSupported, loadMemory));
}
template<typename Type, typename Parameters>
void NzResourceLoader<Type, Parameters>::RegisterResourceStreamLoader(IsStreamLoadingSupportedFunction isLoadingSupported, LoadStreamFunction loadStream)
{
s_streamLoaders.push_back(std::make_pair(isLoadingSupported, loadStream));
}
template<typename Type, typename Parameters>
void NzResourceLoader<Type, Parameters>::UnregisterResourceFileLoader(const NzString& extensions, LoadFileFunction loadFile)
{
std::vector<NzString> exts;
extensions.SplitAny(exts, " /\\*.,;|-_");
for (const NzString& ext : exts)
{
// Récupération de tous les loaders de cette extension
auto range = s_fileLoaders.equal_range(ext);
for (auto it = range.first; it != range.second; ++it)
{
if (it->second == loadFile)
{
s_fileLoaders.erase(it);
break;
}
}
}
}
template<typename Type, typename Parameters>
void NzResourceLoader<Type, Parameters>::UnregisterResourceMemoryLoader(IsMemoryLoadingSupportedFunction isLoadingSupported, LoadMemoryFunction loadMemory)
{
s_memoryLoaders.remove(std::make_pair(isLoadingSupported, loadMemory));
}
template<typename Type, typename Parameters>
void NzResourceLoader<Type, Parameters>::UnregisterResourceStreamLoader(IsStreamLoadingSupportedFunction isLoadingSupported, LoadStreamFunction loadStream)
{
s_streamLoaders.remove(std::make_pair(isLoadingSupported, loadStream));
}
template<typename T, typename P> std::list<typename NzResourceLoader<T, P>::MemoryLoader> NzResourceLoader<T, P>::s_memoryLoaders;
template<typename T, typename P> std::list<typename NzResourceLoader<T, P>::StreamLoader> NzResourceLoader<T, P>::s_streamLoaders;
template<typename T, typename P> std::multimap<NzString, typename NzResourceLoader<T, P>::LoadFileFunction> NzResourceLoader<T, P>::s_fileLoaders;
#include <Nazara/Utility/DebugOff.hpp>