Compare commits
13 Commits
467f471390
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1846d42401 | ||
|
|
5c6ea6c485 | ||
|
|
92179df553 | ||
|
|
172d3ea720 | ||
|
|
2ccc5c364c | ||
|
|
e306a66956 | ||
|
|
4199582a52 | ||
|
|
2784d62ec9 | ||
|
|
d304c56898 | ||
|
|
8cc1719d1b | ||
|
|
cc2c36c75d | ||
|
|
cc91b8d3b9 | ||
|
|
841778fe2f |
39
examples/Assets/main.cpp
Normal file
39
examples/Assets/main.cpp
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#include <Nazara/Audio.hpp>
|
||||||
|
#include <Nazara/Core.hpp>
|
||||||
|
#include <Nazara/Platform.hpp>
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
std::filesystem::path resourceDir = "assets";
|
||||||
|
if (!std::filesystem::is_directory(resourceDir) && std::filesystem::is_directory("../.." / resourceDir))
|
||||||
|
resourceDir = "../.." / resourceDir;
|
||||||
|
|
||||||
|
Nz::Application<Nz::Audio> app(argc, argv);
|
||||||
|
|
||||||
|
auto& windowing = app.AddComponent<Nz::WindowingAppComponent>();
|
||||||
|
auto& fs = app.AddComponent<Nz::FilesystemAppComponent>();
|
||||||
|
fs.Mount("game:/", resourceDir);
|
||||||
|
|
||||||
|
auto& catalog = app.AddComponent<Nz::AssetCatalogAppComponent>();
|
||||||
|
catalog.AddFolder("game:/");
|
||||||
|
|
||||||
|
// Load an asset from its path
|
||||||
|
Nz::Asset<Nz::Music> music = Nz::Asset<Nz::Music>::LoadFromFile("game:/examples/Audio/file_example_MP3_700KB.nzasset");
|
||||||
|
|
||||||
|
// or by its name
|
||||||
|
music = catalog.Load<Nz::Music>("file_example_MP3_700KB");
|
||||||
|
music->Play();
|
||||||
|
|
||||||
|
Nz::Asset<Nz::Sound> sound = catalog.Load<Nz::Sound>("examples/Audio/siren");
|
||||||
|
sound->Play();
|
||||||
|
|
||||||
|
app.AddUpdaterFunc([&]
|
||||||
|
{
|
||||||
|
if (!music->IsPlaying())
|
||||||
|
app.Quit();
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
});
|
||||||
|
|
||||||
|
return app.Run();
|
||||||
|
}
|
||||||
3
examples/Assets/xmake.lua
Normal file
3
examples/Assets/xmake.lua
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
target("Assets")
|
||||||
|
add_deps("NazaraGraphics", "NazaraAudio")
|
||||||
|
add_files("main.cpp")
|
||||||
@@ -25,6 +25,8 @@ namespace Nz
|
|||||||
class NAZARA_AUDIO_API Music final : public Resource, public SoundEmitter
|
class NAZARA_AUDIO_API Music final : public Resource, public SoundEmitter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using Params = SoundStreamParams;
|
||||||
|
|
||||||
Music();
|
Music();
|
||||||
Music(AudioDevice& device);
|
Music(AudioDevice& device);
|
||||||
Music(const Music&) = delete;
|
Music(const Music&) = delete;
|
||||||
@@ -46,9 +48,9 @@ namespace Nz
|
|||||||
|
|
||||||
bool IsLooping() const override;
|
bool IsLooping() const override;
|
||||||
|
|
||||||
bool OpenFromFile(const std::filesystem::path& filePath, const SoundStreamParams& params = SoundStreamParams());
|
static std::shared_ptr<Music> OpenFromFile(const std::filesystem::path& filePath, const Params& params = Params());
|
||||||
bool OpenFromMemory(const void* data, std::size_t size, const SoundStreamParams& params = SoundStreamParams());
|
static std::shared_ptr<Music> OpenFromMemory(const void* data, std::size_t size, const Params& params = Params());
|
||||||
bool OpenFromStream(Stream& stream, const SoundStreamParams& params = SoundStreamParams());
|
static std::shared_ptr<Music> OpenFromStream(Stream& stream, const Params& params = Params());
|
||||||
|
|
||||||
void Pause() override;
|
void Pause() override;
|
||||||
void Play() override;
|
void Play() override;
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ namespace Nz
|
|||||||
class NAZARA_AUDIO_API Sound final : public SoundEmitter
|
class NAZARA_AUDIO_API Sound final : public SoundEmitter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using Params = SoundBufferParams;
|
||||||
|
|
||||||
using SoundEmitter::SoundEmitter;
|
using SoundEmitter::SoundEmitter;
|
||||||
Sound();
|
Sound();
|
||||||
Sound(AudioDevice& audioDevice, std::shared_ptr<SoundBuffer> soundBuffer);
|
Sound(AudioDevice& audioDevice, std::shared_ptr<SoundBuffer> soundBuffer);
|
||||||
@@ -36,9 +38,9 @@ namespace Nz
|
|||||||
bool IsLooping() const override;
|
bool IsLooping() const override;
|
||||||
bool IsPlayable() const;
|
bool IsPlayable() const;
|
||||||
|
|
||||||
bool LoadFromFile(const std::filesystem::path& filePath, const SoundBufferParams& params = SoundBufferParams());
|
static std::shared_ptr<Sound> LoadFromFile(const std::filesystem::path& filePath, const Params& params = {});
|
||||||
bool LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params = SoundBufferParams());
|
static std::shared_ptr<Sound> LoadFromMemory(const void* data, std::size_t size, const Params& params = {});
|
||||||
bool LoadFromStream(Stream& stream, const SoundBufferParams& params = SoundBufferParams());
|
static std::shared_ptr<Sound> LoadFromStream(Stream& stream, const Params& params = {});
|
||||||
|
|
||||||
void Pause() override;
|
void Pause() override;
|
||||||
void Play() override;
|
void Play() override;
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ namespace Nz
|
|||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NAZARA_AUDIO_API bool Serialize(SerializationContext& context, SoundBufferParams& params, TypeTag<SoundBufferParams>);
|
||||||
|
NAZARA_AUDIO_API bool Unserialize(SerializationContext& context, SoundBufferParams* params, TypeTag<SoundBufferParams>);
|
||||||
|
|
||||||
class AudioBuffer;
|
class AudioBuffer;
|
||||||
class AudioDevice;
|
class AudioDevice;
|
||||||
class Sound;
|
class Sound;
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ namespace Nz
|
|||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
NAZARA_CORE_API bool Serialize(SerializationContext& context, SoundStreamParams& params, TypeTag<SoundStreamParams>);
|
NAZARA_AUDIO_API bool Serialize(SerializationContext& context, SoundStreamParams& params, TypeTag<SoundStreamParams>);
|
||||||
NAZARA_CORE_API bool Unserialize(SerializationContext& context, SoundStreamParams* params, TypeTag<SoundStreamParams>);
|
NAZARA_AUDIO_API bool Unserialize(SerializationContext& context, SoundStreamParams* params, TypeTag<SoundStreamParams>);
|
||||||
|
|
||||||
class Mutex;
|
class Mutex;
|
||||||
class SoundStream;
|
class SoundStream;
|
||||||
|
|||||||
@@ -39,6 +39,9 @@
|
|||||||
#include <Nazara/Core/ApplicationBase.hpp>
|
#include <Nazara/Core/ApplicationBase.hpp>
|
||||||
#include <Nazara/Core/ApplicationComponent.hpp>
|
#include <Nazara/Core/ApplicationComponent.hpp>
|
||||||
#include <Nazara/Core/ApplicationUpdater.hpp>
|
#include <Nazara/Core/ApplicationUpdater.hpp>
|
||||||
|
#include <Nazara/Core/Asset.hpp>
|
||||||
|
#include <Nazara/Core/AssetDescriptor.hpp>
|
||||||
|
#include <Nazara/Core/AssetCatalogAppComponent.hpp>
|
||||||
#include <Nazara/Core/Buffer.hpp>
|
#include <Nazara/Core/Buffer.hpp>
|
||||||
#include <Nazara/Core/BufferMapper.hpp>
|
#include <Nazara/Core/BufferMapper.hpp>
|
||||||
#include <Nazara/Core/ByteArray.hpp>
|
#include <Nazara/Core/ByteArray.hpp>
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ namespace Nz
|
|||||||
constexpr UInt64 typeHash = FNV1a64(TypeName<T>());
|
constexpr UInt64 typeHash = FNV1a64(TypeName<T>());
|
||||||
|
|
||||||
auto it = m_components.find(typeHash);
|
auto it = m_components.find(typeHash);
|
||||||
if (it != m_components.end())
|
if (it == m_components.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return static_cast<T*>(it->second.get());
|
return static_cast<T*>(it->second.get());
|
||||||
@@ -109,7 +109,7 @@ namespace Nz
|
|||||||
constexpr UInt64 typeHash = FNV1a64(TypeName<T>());
|
constexpr UInt64 typeHash = FNV1a64(TypeName<T>());
|
||||||
|
|
||||||
auto it = m_components.find(typeHash);
|
auto it = m_components.find(typeHash);
|
||||||
if (it != m_components.end())
|
if (it == m_components.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return static_cast<const T*>(it->second.get());
|
return static_cast<const T*>(it->second.get());
|
||||||
|
|||||||
@@ -11,6 +11,13 @@ namespace Nz
|
|||||||
const std::shared_ptr<TResource>& Get() const { return m_resource; }
|
const std::shared_ptr<TResource>& Get() const { return m_resource; }
|
||||||
explicit operator bool() const noexcept { return !!m_resource; }
|
explicit operator bool() const noexcept { return !!m_resource; }
|
||||||
|
|
||||||
|
TResource& operator*() { return *m_resource.get(); }
|
||||||
|
const TResource& operator*() const { return *m_resource.get(); }
|
||||||
|
TResource* operator->() { return m_resource.get(); }
|
||||||
|
const TResource* operator->() const { return m_resource.get(); }
|
||||||
|
|
||||||
|
static Asset LoadFromFile(const std::filesystem::path& path);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AssetDescriptor<TResource> m_descriptor;
|
AssetDescriptor<TResource> m_descriptor;
|
||||||
std::shared_ptr<TResource> m_resource;
|
std::shared_ptr<TResource> m_resource;
|
||||||
@@ -18,3 +25,5 @@ namespace Nz
|
|||||||
friend class AssetCatalog;
|
friend class AssetCatalog;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Core/Asset.inl>
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
#include <Nazara/Core/ApplicationBase.hpp>
|
||||||
|
#include <Nazara/Core/FilesystemAppComponent.hpp>
|
||||||
|
#include <Nazara/Core/JsonSerialization.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
template <typename TResource>
|
||||||
|
concept IsStreamingResource = requires(TResource)
|
||||||
|
{
|
||||||
|
{ TResource::OpenFromFile({}) } -> std::same_as<std::shared_ptr<TResource>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TResource>
|
||||||
|
Asset<TResource> Asset<TResource>::LoadFromFile(const std::filesystem::path& path)
|
||||||
|
{
|
||||||
|
Asset<TResource> asset;
|
||||||
|
|
||||||
|
FilesystemAppComponent* fs = ApplicationBase::Instance()->TryGetComponent<FilesystemAppComponent>();
|
||||||
|
if (fs) // first try using a FileSystem component to load the asset
|
||||||
|
{
|
||||||
|
auto json = fs->Load<JsonSerializationContext>(std::string_view(path.string()));
|
||||||
|
if (json)
|
||||||
|
{
|
||||||
|
if (!Unserialize(*json, "", &asset.m_descriptor))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
std::string filepath = asset.m_descriptor.path.string();
|
||||||
|
if constexpr (IsStreamingResource<TResource>)
|
||||||
|
{
|
||||||
|
asset.m_resource = fs->Open<TResource>(std::string_view(filepath), asset.m_descriptor.parameters);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
asset.m_resource = fs->Load<TResource>(std::string_view(filepath), asset.m_descriptor.parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!asset) // if it fails, use the default loader
|
||||||
|
{
|
||||||
|
JsonSerializationContext json;
|
||||||
|
if (!json.Load(path))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if (!Unserialize(json, "", &asset.m_descriptor))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if constexpr (IsStreamingResource<TResource>)
|
||||||
|
{
|
||||||
|
asset.m_resource = TResource::OpenFromFile(asset.m_descriptor.path, asset.m_descriptor.parameters);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
asset.m_resource = TResource::LoadFromFile(asset.m_descriptor.path, asset.m_descriptor.parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return asset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <Nazara/Core/Asset.hpp>
|
|
||||||
#include <Nazara/Core/Export.hpp>
|
|
||||||
|
|
||||||
namespace Nz
|
|
||||||
{
|
|
||||||
class NAZARA_CORE_API AssetCatalog
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
template <typename TResource>
|
|
||||||
static Asset<TResource> LoadFromFile(const std::filesystem::path& path);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <Nazara/Core/AssetCatalog.inl>
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#include <Nazara/Core/ApplicationBase.hpp>
|
|
||||||
#include <Nazara/Core/FilesystemAppComponent.hpp>
|
|
||||||
#include <Nazara/Core/JsonSerialization.hpp>
|
|
||||||
|
|
||||||
namespace Nz
|
|
||||||
{
|
|
||||||
template <typename TResource>
|
|
||||||
Asset<TResource> AssetCatalog::LoadFromFile(const std::filesystem::path& path)
|
|
||||||
{
|
|
||||||
Asset<TResource> asset;
|
|
||||||
|
|
||||||
JsonSerializationContext json;
|
|
||||||
if (!json.Load(path))
|
|
||||||
return {};
|
|
||||||
|
|
||||||
if (!Unserialize(json, "", &asset.m_descriptor))
|
|
||||||
return {};
|
|
||||||
|
|
||||||
FilesystemAppComponent* fs = ApplicationBase::Instance()->TryGetComponent<FilesystemAppComponent>();
|
|
||||||
if (fs) // first try using a FileSystem component to load the asset
|
|
||||||
{
|
|
||||||
std::string filepath = asset.m_descriptor.path.string();
|
|
||||||
asset.m_resource = fs->Load<TResource>(std::string_view(filepath), asset.m_descriptor.parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!asset) // if it fails, use the default loader
|
|
||||||
asset.m_resource = TResource::LoadFromFile(asset.m_descriptor.path, asset.m_descriptor.parameters);
|
|
||||||
|
|
||||||
return asset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
45
include/Nazara/Core/AssetCatalogAppComponent.hpp
Normal file
45
include/Nazara/Core/AssetCatalogAppComponent.hpp
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Nazara/Core/Asset.hpp>
|
||||||
|
#include <Nazara/Core/ApplicationComponent.hpp>
|
||||||
|
#include <Nazara/Core/Export.hpp>
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
struct AssetHeaderLite
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
std::filesystem::path path;
|
||||||
|
|
||||||
|
friend auto operator<=>(const AssetHeaderLite& A, const AssetHeaderLite& B)
|
||||||
|
{
|
||||||
|
return A.name <=> B.name;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NAZARA_CORE_API bool Serialize(struct SerializationContext& context, const AssetHeaderLite& header, TypeTag<AssetHeaderLite>);
|
||||||
|
NAZARA_CORE_API bool Unserialize(struct SerializationContext& context, AssetHeaderLite* header, TypeTag<AssetHeaderLite>);
|
||||||
|
|
||||||
|
|
||||||
|
class NAZARA_CORE_API AssetCatalogAppComponent
|
||||||
|
: public ApplicationComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline AssetCatalogAppComponent(ApplicationBase& app);
|
||||||
|
AssetCatalogAppComponent(const AssetCatalogAppComponent&) = delete;
|
||||||
|
AssetCatalogAppComponent(AssetCatalogAppComponent&&) = delete;
|
||||||
|
~AssetCatalogAppComponent() = default;
|
||||||
|
|
||||||
|
void AddFolder(std::string_view folder);
|
||||||
|
|
||||||
|
template<typename TResource>
|
||||||
|
inline Asset<TResource> Load(std::string_view name) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::set<AssetHeaderLite> m_assets;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Core/AssetCatalogAppComponent.inl>
|
||||||
19
include/Nazara/Core/AssetCatalogAppComponent.inl
Normal file
19
include/Nazara/Core/AssetCatalogAppComponent.inl
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
inline AssetCatalogAppComponent::AssetCatalogAppComponent(ApplicationBase& app)
|
||||||
|
: ApplicationComponent(app)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TResource>
|
||||||
|
Asset<TResource> AssetCatalogAppComponent::Load(std::string_view name) const
|
||||||
|
{
|
||||||
|
AssetHeaderLite header{ std::string(name), "" };
|
||||||
|
auto it = m_assets.find(header);
|
||||||
|
if (it == m_assets.end())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return Asset<TResource>::LoadFromFile(it->path);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,10 +10,13 @@ namespace Nz
|
|||||||
: public SerializationContext
|
: public SerializationContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct Params {};
|
||||||
|
|
||||||
JsonSerializationContext();
|
JsonSerializationContext();
|
||||||
~JsonSerializationContext();
|
~JsonSerializationContext();
|
||||||
|
|
||||||
bool Load(const std::filesystem::path& path);
|
bool Load(const std::filesystem::path& path);
|
||||||
|
bool Load(Stream& stream);
|
||||||
|
|
||||||
EnumSerializationMode GetEnumSerializationMode() const override { return EnumSerializationMode::String; }
|
EnumSerializationMode GetEnumSerializationMode() const override { return EnumSerializationMode::String; }
|
||||||
bool PushObject(std::string_view name) override;
|
bool PushObject(std::string_view name) override;
|
||||||
@@ -47,6 +50,8 @@ namespace Nz
|
|||||||
bool Read(std::string_view name, double* value) override;
|
bool Read(std::string_view name, double* value) override;
|
||||||
bool Read(std::string_view name, std::string* value) override;
|
bool Read(std::string_view name, std::string* value) override;
|
||||||
|
|
||||||
|
static std::shared_ptr<JsonSerializationContext> LoadFromStream(Stream& stream, const Params& params = {});
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<struct JsonImpl> m_impl;
|
std::unique_ptr<struct JsonImpl> m_impl;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace Nz
|
|||||||
|
|
||||||
inline bool Exists(std::string_view path);
|
inline bool Exists(std::string_view path);
|
||||||
|
|
||||||
template<typename F> void Foreach(F&& callback, bool includeDots = false);
|
template<typename F> bool Foreach(F&& callback, bool recursive = false, bool includeDots = false);
|
||||||
|
|
||||||
template<typename F> bool GetDirectoryEntry(std::string_view path, F&& callback);
|
template<typename F> bool GetDirectoryEntry(std::string_view path, F&& callback);
|
||||||
template<typename F> bool GetEntry(std::string_view path, F&& callback);
|
template<typename F> bool GetEntry(std::string_view path, F&& callback);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace Nz
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
void VirtualDirectory::Foreach(F&& callback, bool includeDots)
|
bool VirtualDirectory::Foreach(F&& callback, bool recursive, bool includeDots)
|
||||||
{
|
{
|
||||||
if (includeDots)
|
if (includeDots)
|
||||||
{
|
{
|
||||||
@@ -46,16 +46,26 @@ namespace Nz
|
|||||||
{
|
{
|
||||||
Entry parentEntry = DirectoryEntry{ { parent } };
|
Entry parentEntry = DirectoryEntry{ { parent } };
|
||||||
if (!CallbackReturn(callback, std::string_view(".."), parentEntry))
|
if (!CallbackReturn(callback, std::string_view(".."), parentEntry))
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
else if (!CallbackReturn(callback, std::string_view(".."), ourselves))
|
else if (!CallbackReturn(callback, std::string_view(".."), ourselves))
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto&& entry : m_content)
|
for (auto&& entry : m_content)
|
||||||
{
|
{
|
||||||
if (!CallbackReturn(callback, std::string_view(entry.name), std::as_const(entry.entry)))
|
if (!CallbackReturn(callback, std::string_view(entry.name), std::as_const(entry.entry)))
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
|
if (recursive)
|
||||||
|
{
|
||||||
|
if (std::holds_alternative<DirectoryEntry>(entry.entry))
|
||||||
|
{
|
||||||
|
DirectoryEntry& child = std::get<DirectoryEntry>(entry.entry);
|
||||||
|
if (!child.directory->Foreach(callback, recursive, includeDots))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_resolver)
|
if (m_resolver)
|
||||||
@@ -70,9 +80,22 @@ namespace Nz
|
|||||||
if (it != m_content.end() && it->name == filename)
|
if (it != m_content.end() && it->name == filename)
|
||||||
return true; //< this was already returned
|
return true; //< this was already returned
|
||||||
|
|
||||||
return CallbackReturn(callback, filename, std::move(entry));
|
if (!CallbackReturn(callback, filename, entry))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (recursive)
|
||||||
|
{
|
||||||
|
if (std::holds_alternative<DirectoryEntry>(entry))
|
||||||
|
{
|
||||||
|
DirectoryEntry& child = std::get<DirectoryEntry>(entry);
|
||||||
|
if (!child.directory->Foreach(callback, recursive, includeDots))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
|
|||||||
@@ -240,12 +240,17 @@ namespace Nz
|
|||||||
* \param filePath Path to the file
|
* \param filePath Path to the file
|
||||||
* \param params Parameters for the music
|
* \param params Parameters for the music
|
||||||
*/
|
*/
|
||||||
bool Music::OpenFromFile(const std::filesystem::path& filePath, const SoundStreamParams& params)
|
std::shared_ptr<Music> Music::OpenFromFile(const std::filesystem::path& filePath, const Params& params)
|
||||||
{
|
{
|
||||||
|
std::shared_ptr<Music> music = std::make_shared<Music>();
|
||||||
if (std::shared_ptr<SoundStream> soundStream = SoundStream::OpenFromFile(filePath, params))
|
if (std::shared_ptr<SoundStream> soundStream = SoundStream::OpenFromFile(filePath, params))
|
||||||
return Create(std::move(soundStream));
|
{
|
||||||
else
|
std::shared_ptr<Music> music = std::make_shared<Music>();
|
||||||
return false;
|
if (music->Create(std::move(soundStream)))
|
||||||
|
return music;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -258,12 +263,16 @@ namespace Nz
|
|||||||
*
|
*
|
||||||
* \remark The memory pointer must stay valid (accessible) as long as the music is playing
|
* \remark The memory pointer must stay valid (accessible) as long as the music is playing
|
||||||
*/
|
*/
|
||||||
bool Music::OpenFromMemory(const void* data, std::size_t size, const SoundStreamParams& params)
|
std::shared_ptr<Music> Music::OpenFromMemory(const void* data, std::size_t size, const Params& params)
|
||||||
{
|
{
|
||||||
if (std::shared_ptr<SoundStream> soundStream = SoundStream::OpenFromMemory(data, size, params))
|
if (std::shared_ptr<SoundStream> soundStream = SoundStream::OpenFromMemory(data, size, params))
|
||||||
return Create(std::move(soundStream));
|
{
|
||||||
else
|
std::shared_ptr<Music> music = std::make_shared<Music>();
|
||||||
return false;
|
if (music->Create(std::move(soundStream)))
|
||||||
|
return music;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -275,12 +284,16 @@ namespace Nz
|
|||||||
*
|
*
|
||||||
* \remark The stream must stay valid as long as the music is playing
|
* \remark The stream must stay valid as long as the music is playing
|
||||||
*/
|
*/
|
||||||
bool Music::OpenFromStream(Stream& stream, const SoundStreamParams& params)
|
std::shared_ptr<Music> Music::OpenFromStream(Stream& stream, const Params& params)
|
||||||
{
|
{
|
||||||
if (std::shared_ptr<SoundStream> soundStream = SoundStream::OpenFromStream(stream, params))
|
if (std::shared_ptr<SoundStream> soundStream = SoundStream::OpenFromStream(stream, params))
|
||||||
return Create(std::move(soundStream));
|
{
|
||||||
else
|
std::shared_ptr<Music> music = std::make_shared<Music>();
|
||||||
return false;
|
if (music->Create(std::move(soundStream)))
|
||||||
|
return music;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -439,7 +452,7 @@ namespace Nz
|
|||||||
break; // We have reached the end of the stream, there is no use to add new buffers
|
break; // We have reached the end of the stream, there is no use to add new buffers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception&)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
err = std::current_exception();
|
err = std::current_exception();
|
||||||
|
|
||||||
|
|||||||
@@ -141,17 +141,18 @@ namespace Nz
|
|||||||
*
|
*
|
||||||
* \remark Produces a NazaraError if loading failed
|
* \remark Produces a NazaraError if loading failed
|
||||||
*/
|
*/
|
||||||
bool Sound::LoadFromFile(const std::filesystem::path& filePath, const SoundBufferParams& params)
|
std::shared_ptr<Sound> Sound::LoadFromFile(const std::filesystem::path& filePath, const Params& params)
|
||||||
{
|
{
|
||||||
std::shared_ptr<SoundBuffer> buffer = SoundBuffer::LoadFromFile(filePath, params);
|
std::shared_ptr<SoundBuffer> buffer = SoundBuffer::LoadFromFile(filePath, params);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
{
|
{
|
||||||
NazaraErrorFmt("failed to load buffer from file ({0})", filePath);
|
NazaraErrorFmt("failed to load buffer from file ({0})", filePath);
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
SetBuffer(std::move(buffer));
|
std::shared_ptr<Sound> sound = std::make_shared<Sound>();
|
||||||
return true;
|
sound->SetBuffer(std::move(buffer));
|
||||||
|
return sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -164,17 +165,18 @@ namespace Nz
|
|||||||
*
|
*
|
||||||
* \remark Produces a NazaraError if loading failed
|
* \remark Produces a NazaraError if loading failed
|
||||||
*/
|
*/
|
||||||
bool Sound::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params)
|
std::shared_ptr<Sound> Sound::LoadFromMemory(const void* data, std::size_t size, const Params& params)
|
||||||
{
|
{
|
||||||
std::shared_ptr<SoundBuffer> buffer = SoundBuffer::LoadFromMemory(data, size, params);
|
std::shared_ptr<SoundBuffer> buffer = SoundBuffer::LoadFromMemory(data, size, params);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
{
|
{
|
||||||
NazaraErrorFmt("failed to load buffer from memory ({0})", PointerToString(data));
|
NazaraErrorFmt("failed to load buffer from memory ({0})", PointerToString(data));
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
SetBuffer(std::move(buffer));
|
std::shared_ptr<Sound> sound = std::make_shared<Sound>();
|
||||||
return true;
|
sound->SetBuffer(std::move(buffer));
|
||||||
|
return sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -186,17 +188,18 @@ namespace Nz
|
|||||||
*
|
*
|
||||||
* \remark Produces a NazaraError if loading failed
|
* \remark Produces a NazaraError if loading failed
|
||||||
*/
|
*/
|
||||||
bool Sound::LoadFromStream(Stream& stream, const SoundBufferParams& params)
|
std::shared_ptr<Sound> Sound::LoadFromStream(Stream& stream, const Params& params)
|
||||||
{
|
{
|
||||||
std::shared_ptr<SoundBuffer> buffer = SoundBuffer::LoadFromStream(stream, params);
|
std::shared_ptr<SoundBuffer> buffer = SoundBuffer::LoadFromStream(stream, params);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
{
|
{
|
||||||
NazaraError("failed to load buffer from stream");
|
NazaraError("failed to load buffer from stream");
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
SetBuffer(std::move(buffer));
|
std::shared_ptr<Sound> sound = std::make_shared<Sound>();
|
||||||
return true;
|
sound->SetBuffer(std::move(buffer));
|
||||||
|
return sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -32,6 +32,20 @@ namespace Nz
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Serialize(SerializationContext& context, SoundBufferParams& params, TypeTag<SoundBufferParams>)
|
||||||
|
{
|
||||||
|
Serialize(context, params, TypeTag<ResourceParameters>());
|
||||||
|
Serialize(context, "forceMono", params.forceMono);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Unserialize(SerializationContext& context, SoundBufferParams* params, TypeTag<SoundBufferParams>)
|
||||||
|
{
|
||||||
|
Unserialize(context, params, TypeTag<ResourceParameters>());
|
||||||
|
Unserialize(context, "forceMono", ¶ms->forceMono);
|
||||||
|
return params->IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a SoundBuffer object
|
* \brief Constructs a SoundBuffer object
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace Nz
|
|||||||
{
|
{
|
||||||
Unserialize(context, params, TypeTag<ResourceParameters>());
|
Unserialize(context, params, TypeTag<ResourceParameters>());
|
||||||
Unserialize(context, "forceMono", ¶ms->forceMono);
|
Unserialize(context, "forceMono", ¶ms->forceMono);
|
||||||
return true;
|
return params->IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SoundStreamParams::IsValid() const
|
bool SoundStreamParams::IsValid() const
|
||||||
|
|||||||
52
src/Nazara/Core/AssetCatalogAppComponent.cpp
Normal file
52
src/Nazara/Core/AssetCatalogAppComponent.cpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
|
||||||
|
#include <Nazara/Core/AssetCatalogAppComponent.hpp>
|
||||||
|
#include <Nazara/Core/Serialization.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
bool Serialize(SerializationContext& context, const AssetHeaderLite& header, TypeTag<AssetHeaderLite>)
|
||||||
|
{
|
||||||
|
Serialize(context, "name", header.name);
|
||||||
|
Serialize(context, "path", header.path);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Unserialize(SerializationContext& context, AssetHeaderLite* header, TypeTag<AssetHeaderLite>)
|
||||||
|
{
|
||||||
|
Unserialize(context, "name", &header->name);
|
||||||
|
Unserialize(context, "path", &header->path);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddFile(std::set<AssetHeaderLite>& container, Nz::Stream& stream)
|
||||||
|
{
|
||||||
|
AssetHeaderLite header;
|
||||||
|
auto json = JsonSerializationContext::LoadFromStream(stream);
|
||||||
|
if (!json)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!Unserialize(*json, "", &header))
|
||||||
|
return;
|
||||||
|
|
||||||
|
header.path = stream.GetPath();
|
||||||
|
container.insert(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetCatalogAppComponent::AddFolder(std::string_view folder)
|
||||||
|
{
|
||||||
|
auto& fs = GetApp().GetComponent<FilesystemAppComponent>();
|
||||||
|
auto directory = fs.GetDirectory(folder);
|
||||||
|
if (!directory)
|
||||||
|
return;
|
||||||
|
|
||||||
|
directory->Foreach([&](std::string_view, const VirtualDirectory::Entry& entry) {
|
||||||
|
if (std::holds_alternative<VirtualDirectory::FileEntry>(entry))
|
||||||
|
{
|
||||||
|
auto& file = std::get<VirtualDirectory::FileEntry>(entry);
|
||||||
|
|
||||||
|
if (file.stream->GetPath().extension() == ".nzasset")
|
||||||
|
AddFile(m_assets, *file.stream.get());
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,11 +36,20 @@ namespace Nz
|
|||||||
|
|
||||||
bool JsonSerializationContext::Load(const std::filesystem::path& path)
|
bool JsonSerializationContext::Load(const std::filesystem::path& path)
|
||||||
{
|
{
|
||||||
std::ifstream file(path);
|
Nz::File file(path, Nz::OpenMode::Read);
|
||||||
if (!file || !file.is_open())
|
return Load(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JsonSerializationContext::Load(Stream& stream)
|
||||||
|
{
|
||||||
|
if (!stream.IsReadable())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_impl->json = nlohmann::json::parse(file);
|
auto size = stream.GetSize();
|
||||||
|
std::vector<char> content(size);
|
||||||
|
stream.Read(content.data(), content.size());
|
||||||
|
|
||||||
|
m_impl->json = nlohmann::json::parse(content.begin(), content.end());
|
||||||
m_impl->stack.push(&m_impl->json);
|
m_impl->stack.push(&m_impl->json);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -129,4 +138,12 @@ namespace Nz
|
|||||||
*value = m_impl->Top()[name].get<std::string>();
|
*value = m_impl->Top()[name].get<std::string>();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<JsonSerializationContext> JsonSerializationContext::LoadFromStream(Stream& stream, const JsonSerializationContext::Params&)
|
||||||
|
{
|
||||||
|
std::shared_ptr<JsonSerializationContext> context = std::make_shared<JsonSerializationContext>();
|
||||||
|
if (context->Load(stream))
|
||||||
|
return context;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ TEST_CASE("VirtualDirectory", "[Core][VirtualDirectory]")
|
|||||||
}
|
}
|
||||||
if (name != "." && name != "..")
|
if (name != "." && name != "..")
|
||||||
FAIL("Got file " << name);
|
FAIL("Got file " << name);
|
||||||
}, true);
|
}, false, true);
|
||||||
|
|
||||||
CHECK(dot);
|
CHECK(dot);
|
||||||
CHECK(dotDot);
|
CHECK(dotDot);
|
||||||
|
|||||||
Reference in New Issue
Block a user