Fixed streaming loaders when used with memory streams
Former-commit-id: ce39ee03f40682c00c78b08ac285b9ea36240fa5
This commit is contained in:
parent
9f40fe12b1
commit
c02fe6c8ff
|
|
@ -20,6 +20,7 @@ class NzResourceLoader
|
||||||
public:
|
public:
|
||||||
using ExtensionGetter = bool (*)(const NzString& extension);
|
using ExtensionGetter = bool (*)(const NzString& extension);
|
||||||
using FileLoader = bool (*)(Type* resource, const NzString& filePath, const Parameters& parameters);
|
using FileLoader = bool (*)(Type* resource, const NzString& filePath, const Parameters& parameters);
|
||||||
|
using MemoryLoader = bool (*)(Type* resource, const void* data, std::size_t size, const Parameters& parameters);
|
||||||
using StreamChecker = nzTernary (*)(NzInputStream& stream, const Parameters& parameters);
|
using StreamChecker = nzTernary (*)(NzInputStream& stream, const Parameters& parameters);
|
||||||
using StreamLoader = bool (*)(Type* resource, NzInputStream& stream, const Parameters& parameters);
|
using StreamLoader = bool (*)(Type* resource, NzInputStream& stream, const Parameters& parameters);
|
||||||
|
|
||||||
|
|
@ -29,10 +30,10 @@ class NzResourceLoader
|
||||||
static bool LoadFromMemory(Type* resource, const void* data, unsigned int size, 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 bool LoadFromStream(Type* resource, NzInputStream& stream, const Parameters& parameters = Parameters());
|
||||||
|
|
||||||
static void RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr);
|
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);
|
static void UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr);
|
||||||
|
|
||||||
using Loader = std::tuple<ExtensionGetter, StreamChecker, StreamLoader, FileLoader>;
|
using Loader = std::tuple<ExtensionGetter, StreamChecker, StreamLoader, FileLoader, MemoryLoader>;
|
||||||
using LoaderList = std::list<Loader>;
|
using LoaderList = std::list<Loader>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -117,9 +117,77 @@ bool NzResourceLoader<Type, Parameters>::LoadFromFile(Type* resource, const NzSt
|
||||||
template<typename Type, typename Parameters>
|
template<typename Type, typename Parameters>
|
||||||
bool NzResourceLoader<Type, Parameters>::LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters)
|
bool NzResourceLoader<Type, Parameters>::LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters)
|
||||||
{
|
{
|
||||||
|
#if NAZARA_CORE_SAFE
|
||||||
|
if (!parameters.IsValid())
|
||||||
|
{
|
||||||
|
NazaraError("Invalid parameters");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
NazaraError("No data to load");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
NzMemoryStream stream(data, size);
|
NzMemoryStream stream(data, size);
|
||||||
|
|
||||||
return LoadFromStream(resource, stream, parameters);
|
bool found = false;
|
||||||
|
for (Loader& loader : Type::s_loaders)
|
||||||
|
{
|
||||||
|
StreamChecker checkFunc = std::get<1>(loader);
|
||||||
|
StreamLoader streamLoader = std::get<2>(loader);
|
||||||
|
MemoryLoader memoryLoader = std::get<4>(loader);
|
||||||
|
|
||||||
|
nzTernary recognized = nzTernary_Unknown;
|
||||||
|
if (memoryLoader)
|
||||||
|
{
|
||||||
|
if (checkFunc)
|
||||||
|
{
|
||||||
|
stream.SetCursorPos(0);
|
||||||
|
|
||||||
|
recognized = checkFunc(stream, parameters);
|
||||||
|
if (recognized == nzTernary_False)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
recognized = nzTernary_Unknown;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memoryLoader(resource, data, size, parameters))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stream.SetCursorPos(0);
|
||||||
|
|
||||||
|
recognized = checkFunc(stream, parameters);
|
||||||
|
if (recognized == nzTernary_False)
|
||||||
|
continue;
|
||||||
|
else if (recognized == nzTernary_True)
|
||||||
|
found = true;
|
||||||
|
|
||||||
|
stream.SetCursorPos(0);
|
||||||
|
|
||||||
|
if (streamLoader(resource, stream, parameters))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recognized == nzTernary_True)
|
||||||
|
NazaraWarning("Loader failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
NazaraError("Failed to load file: all loaders failed");
|
||||||
|
else
|
||||||
|
NazaraError("Failed to load file: no loader found");
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type, typename Parameters>
|
template<typename Type, typename Parameters>
|
||||||
|
|
@ -175,7 +243,7 @@ bool NzResourceLoader<Type, Parameters>::LoadFromStream(Type* resource, NzInputS
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type, typename Parameters>
|
template<typename Type, typename Parameters>
|
||||||
void NzResourceLoader<Type, Parameters>::RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader)
|
void NzResourceLoader<Type, Parameters>::RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader, MemoryLoader memoryLoader)
|
||||||
{
|
{
|
||||||
#if NAZARA_CORE_SAFE
|
#if NAZARA_CORE_SAFE
|
||||||
if (streamLoader)
|
if (streamLoader)
|
||||||
|
|
@ -186,20 +254,20 @@ void NzResourceLoader<Type, Parameters>::RegisterLoader(ExtensionGetter extensio
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!fileLoader)
|
else if (!fileLoader && !memoryLoader)
|
||||||
{
|
{
|
||||||
NazaraError("Neither FileLoader nor StreamLoader were present");
|
NazaraError("Neither FileLoader nor MemoryLoader nor StreamLoader were present");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Type::s_loaders.push_front(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader));
|
Type::s_loaders.push_front(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader, memoryLoader));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type, typename Parameters>
|
template<typename Type, typename Parameters>
|
||||||
void NzResourceLoader<Type, Parameters>::UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader)
|
void NzResourceLoader<Type, Parameters>::UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader, MemoryLoader memoryLoader)
|
||||||
{
|
{
|
||||||
Type::s_loaders.remove(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader));
|
Type::s_loaders.remove(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader, memoryLoader));
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Nazara/Core/DebugOff.hpp>
|
#include <Nazara/Core/DebugOff.hpp>
|
||||||
|
|
|
||||||
|
|
@ -106,13 +106,21 @@ namespace
|
||||||
|
|
||||||
bool Open(const NzString& filePath, bool forceMono)
|
bool Open(const NzString& filePath, bool forceMono)
|
||||||
{
|
{
|
||||||
if (!m_file.Open(filePath, NzFile::ReadOnly))
|
std::unique_ptr<NzFile> file(new NzFile);
|
||||||
|
if (!file->Open(filePath, NzFile::ReadOnly))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to open stream from file: " + NzError::GetLastError());
|
NazaraError("Failed to open stream from file: " + NzError::GetLastError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
m_ownedStream = std::move(file);
|
||||||
|
|
||||||
return Open(m_file, forceMono);
|
return Open(*m_ownedStream, forceMono);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Open(const void* data, std::size_t size, bool forceMono)
|
||||||
|
{
|
||||||
|
m_ownedStream.reset(new NzMemoryStream(data, size));
|
||||||
|
return Open(*m_ownedStream, forceMono);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Open(NzInputStream& stream, bool forceMono)
|
bool Open(NzInputStream& stream, bool forceMono)
|
||||||
|
|
@ -185,8 +193,8 @@ namespace
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<nzInt16> m_mixBuffer;
|
std::vector<nzInt16> m_mixBuffer;
|
||||||
|
std::unique_ptr<NzInputStream> m_ownedStream;
|
||||||
nzAudioFormat m_format;
|
nzAudioFormat m_format;
|
||||||
NzFile m_file;
|
|
||||||
SNDFILE* m_handle;
|
SNDFILE* m_handle;
|
||||||
bool m_mixToMono;
|
bool m_mixToMono;
|
||||||
unsigned int m_duration;
|
unsigned int m_duration;
|
||||||
|
|
@ -243,6 +251,28 @@ namespace
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LoadMusicMemory(NzMusic* music, const void* data, std::size_t size, const NzMusicParams& parameters)
|
||||||
|
{
|
||||||
|
NazaraUnused(parameters);
|
||||||
|
|
||||||
|
std::unique_ptr<sndfileStream> musicStream(new sndfileStream);
|
||||||
|
if (!musicStream->Open(data, size, parameters.forceMono))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to open music stream");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!music->Create(musicStream.get()))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to create music");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
musicStream.release();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool LoadMusicStream(NzMusic* music, NzInputStream& stream, const NzMusicParams& parameters)
|
bool LoadMusicStream(NzMusic* music, NzInputStream& stream, const NzMusicParams& parameters)
|
||||||
{
|
{
|
||||||
NazaraUnused(parameters);
|
NazaraUnused(parameters);
|
||||||
|
|
@ -342,12 +372,12 @@ namespace
|
||||||
|
|
||||||
void NzLoaders_sndfile_Register()
|
void NzLoaders_sndfile_Register()
|
||||||
{
|
{
|
||||||
NzMusicLoader::RegisterLoader(IsSupported, CheckMusic, LoadMusicStream, LoadMusicFile);
|
NzMusicLoader::RegisterLoader(IsSupported, CheckMusic, LoadMusicStream, LoadMusicFile, LoadMusicMemory);
|
||||||
NzSoundBufferLoader::RegisterLoader(IsSupported, CheckSoundBuffer, LoadSoundBuffer);
|
NzSoundBufferLoader::RegisterLoader(IsSupported, CheckSoundBuffer, LoadSoundBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzLoaders_sndfile_Unregister()
|
void NzLoaders_sndfile_Unregister()
|
||||||
{
|
{
|
||||||
NzMusicLoader::UnregisterLoader(IsSupported, CheckMusic, LoadMusicStream, LoadMusicFile);
|
NzMusicLoader::UnregisterLoader(IsSupported, CheckMusic, LoadMusicStream, LoadMusicFile, LoadMusicMemory);
|
||||||
NzSoundBufferLoader::UnregisterLoader(IsSupported, CheckSoundBuffer, LoadSoundBuffer);
|
NzSoundBufferLoader::UnregisterLoader(IsSupported, CheckSoundBuffer, LoadSoundBuffer);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include FT_OUTLINE_H
|
#include FT_OUTLINE_H
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Core/InputStream.hpp>
|
#include <Nazara/Core/InputStream.hpp>
|
||||||
|
#include <Nazara/Core/MemoryStream.hpp>
|
||||||
#include <Nazara/Utility/Font.hpp>
|
#include <Nazara/Utility/Font.hpp>
|
||||||
#include <Nazara/Utility/FontData.hpp>
|
#include <Nazara/Utility/FontData.hpp>
|
||||||
#include <Nazara/Utility/FontGlyph.hpp>
|
#include <Nazara/Utility/FontGlyph.hpp>
|
||||||
|
|
@ -260,16 +261,24 @@ namespace
|
||||||
|
|
||||||
bool SetFile(const NzString& filePath)
|
bool SetFile(const NzString& filePath)
|
||||||
{
|
{
|
||||||
if (!m_file.Open(filePath, NzFile::ReadOnly))
|
std::unique_ptr<NzFile> file(new NzFile);
|
||||||
|
if (!file->Open(filePath, NzFile::ReadOnly))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to open stream from file: " + NzError::GetLastError());
|
NazaraError("Failed to open stream from file: " + NzError::GetLastError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
m_ownedStream = std::move(file);
|
||||||
|
|
||||||
SetStream(m_file);
|
SetStream(*m_ownedStream);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetMemory(const void* data, std::size_t size)
|
||||||
|
{
|
||||||
|
m_ownedStream.reset(new NzMemoryStream(data, size));
|
||||||
|
SetStream(*m_ownedStream);
|
||||||
|
}
|
||||||
|
|
||||||
void SetStream(NzInputStream& stream)
|
void SetStream(NzInputStream& stream)
|
||||||
{
|
{
|
||||||
m_stream.base = nullptr;
|
m_stream.base = nullptr;
|
||||||
|
|
@ -303,7 +312,7 @@ namespace
|
||||||
FT_Open_Args m_args;
|
FT_Open_Args m_args;
|
||||||
FT_Face m_face;
|
FT_Face m_face;
|
||||||
FT_StreamRec m_stream;
|
FT_StreamRec m_stream;
|
||||||
NzFile m_file;
|
std::unique_ptr<NzInputStream> m_ownedStream;
|
||||||
mutable unsigned int m_characterSize;
|
mutable unsigned int m_characterSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -357,6 +366,28 @@ namespace
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LoadMemory(NzFont* font, const void* data, std::size_t size, const NzFontParams& parameters)
|
||||||
|
{
|
||||||
|
NazaraUnused(parameters);
|
||||||
|
|
||||||
|
std::unique_ptr<FreeTypeStream> face(new FreeTypeStream);
|
||||||
|
face->SetMemory(data, size);
|
||||||
|
|
||||||
|
if (!face->Open())
|
||||||
|
{
|
||||||
|
NazaraError("Failed to open face");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (font->Create(face.get()))
|
||||||
|
{
|
||||||
|
face.release();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool LoadStream(NzFont* font, NzInputStream& stream, const NzFontParams& parameters)
|
bool LoadStream(NzFont* font, NzInputStream& stream, const NzFontParams& parameters)
|
||||||
{
|
{
|
||||||
NazaraUnused(parameters);
|
NazaraUnused(parameters);
|
||||||
|
|
@ -383,7 +414,7 @@ namespace
|
||||||
void NzLoaders_FreeType_Register()
|
void NzLoaders_FreeType_Register()
|
||||||
{
|
{
|
||||||
if (FT_Init_FreeType(&s_library) == 0)
|
if (FT_Init_FreeType(&s_library) == 0)
|
||||||
NzFontLoader::RegisterLoader(IsSupported, Check, LoadStream, LoadFile);
|
NzFontLoader::RegisterLoader(IsSupported, Check, LoadStream, LoadFile, LoadMemory);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s_library = nullptr; // On s'assure que le pointeur ne pointe pas sur n'importe quoi
|
s_library = nullptr; // On s'assure que le pointeur ne pointe pas sur n'importe quoi
|
||||||
|
|
@ -395,7 +426,7 @@ void NzLoaders_FreeType_Unregister()
|
||||||
{
|
{
|
||||||
if (s_library)
|
if (s_library)
|
||||||
{
|
{
|
||||||
NzFontLoader::UnregisterLoader(IsSupported, Check, LoadStream, LoadFile);
|
NzFontLoader::UnregisterLoader(IsSupported, Check, LoadStream, LoadFile, LoadMemory);
|
||||||
|
|
||||||
FT_Done_FreeType(s_library);
|
FT_Done_FreeType(s_library);
|
||||||
s_library = nullptr;
|
s_library = nullptr;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue