Compare commits
2 Commits
c1f429e916
...
467f471390
| Author | SHA1 | Date |
|---|---|---|
|
|
467f471390 | |
|
|
6a6ffb6779 |
|
|
@ -0,0 +1,20 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Nazara/Core/AssetDescriptor.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
template <typename TResource>
|
||||||
|
class Asset final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const std::shared_ptr<TResource>& Get() const { return m_resource; }
|
||||||
|
explicit operator bool() const noexcept { return !!m_resource; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AssetDescriptor<TResource> m_descriptor;
|
||||||
|
std::shared_ptr<TResource> m_resource;
|
||||||
|
|
||||||
|
friend class AssetCatalog;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#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>
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Nazara/Core/Serialization.hpp>
|
||||||
|
#include <NazaraUtils/TypeName.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
template <typename TResource>
|
||||||
|
struct AssetDescriptor
|
||||||
|
{
|
||||||
|
constexpr static std::string_view Type = TypeName<TResource>();
|
||||||
|
|
||||||
|
int version;
|
||||||
|
std::string type;
|
||||||
|
std::string name;
|
||||||
|
std::filesystem::path path;
|
||||||
|
TResource::Params parameters;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TResource> bool Serialize(SerializationContext& context, const AssetDescriptor<TResource>& descriptor, TypeTag<AssetDescriptor<TResource>>);
|
||||||
|
template <typename TResource> bool Unserialize(SerializationContext& context, AssetDescriptor<TResource>* descriptor, TypeTag<AssetDescriptor<TResource>>);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Core/AssetDescriptor.inl>
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
template <typename TResource>
|
||||||
|
bool Serialize(SerializationContext& context, const AssetDescriptor<TResource>& descriptor, TypeTag<AssetDescriptor<TResource>>)
|
||||||
|
{
|
||||||
|
Serialize(context, "version", descriptor.version);
|
||||||
|
Serialize(context, "type", descriptor.type);
|
||||||
|
Serialize(context, "name", descriptor.name);
|
||||||
|
Serialize(context, "path", descriptor.path);
|
||||||
|
Serialize(context, "parameters", descriptor.parameters);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TResource>
|
||||||
|
bool Unserialize(SerializationContext& context, AssetDescriptor<TResource>* descriptor, TypeTag<AssetDescriptor<TResource>>)
|
||||||
|
{
|
||||||
|
if (!Unserialize(context, "version", &descriptor->version))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!Unserialize(context, "type", &descriptor->type))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (AssetDescriptor<TResource>::Type != descriptor->type)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!Unserialize(context, "name", &descriptor->name))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!Unserialize(context, "path", &descriptor->path))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!Unserialize(context, "parameters", &descriptor->parameters))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Nazara/Core/Export.hpp>
|
||||||
|
#include <Nazara/Core/Serialization.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
class NAZARA_CORE_API JsonSerializationContext
|
||||||
|
: public SerializationContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
JsonSerializationContext();
|
||||||
|
~JsonSerializationContext();
|
||||||
|
|
||||||
|
bool Load(const std::filesystem::path& path);
|
||||||
|
|
||||||
|
EnumSerializationMode GetEnumSerializationMode() const override { return EnumSerializationMode::String; }
|
||||||
|
bool PushObject(std::string_view name) override;
|
||||||
|
bool PopObject() override;
|
||||||
|
bool PushArray(std::string_view name) override;
|
||||||
|
bool PopArray() override;
|
||||||
|
|
||||||
|
bool Write(std::string_view name, bool value) override;
|
||||||
|
bool Write(std::string_view name, Nz::Int8 value) override;
|
||||||
|
bool Write(std::string_view name, Nz::Int16 value) override;
|
||||||
|
bool Write(std::string_view name, Nz::Int32 value) override;
|
||||||
|
bool Write(std::string_view name, Nz::Int64 value) override;
|
||||||
|
bool Write(std::string_view name, Nz::UInt8 value) override;
|
||||||
|
bool Write(std::string_view name, Nz::UInt16 value) override;
|
||||||
|
bool Write(std::string_view name, Nz::UInt32 value) override;
|
||||||
|
bool Write(std::string_view name, Nz::UInt64 value) override;
|
||||||
|
bool Write(std::string_view name, float value) override;
|
||||||
|
bool Write(std::string_view name, double value) override;
|
||||||
|
bool Write(std::string_view name, const std::string& value) override;
|
||||||
|
|
||||||
|
bool Read(std::string_view name, bool* value) override;
|
||||||
|
bool Read(std::string_view name, Nz::Int8* value) override;
|
||||||
|
bool Read(std::string_view name, Nz::Int16* value) override;
|
||||||
|
bool Read(std::string_view name, Nz::Int32* value) override;
|
||||||
|
bool Read(std::string_view name, Nz::Int64* value) override;
|
||||||
|
bool Read(std::string_view name, Nz::UInt8* value) override;
|
||||||
|
bool Read(std::string_view name, Nz::UInt16* value) override;
|
||||||
|
bool Read(std::string_view name, Nz::UInt32* value) override;
|
||||||
|
bool Read(std::string_view name, Nz::UInt64* value) override;
|
||||||
|
bool Read(std::string_view name, float* value) override;
|
||||||
|
bool Read(std::string_view name, double* value) override;
|
||||||
|
bool Read(std::string_view name, std::string* value) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<struct JsonImpl> m_impl;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
#include <Nazara/Core/JsonSerialization.hpp>
|
||||||
|
#include <Nazara/Core/FilesystemAppComponent.hpp>
|
||||||
|
#include <Nazara/Core/ApplicationBase.hpp>
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
struct JsonImpl
|
||||||
|
{
|
||||||
|
|
||||||
|
nlohmann::json& Top() { return *stack.top(); }
|
||||||
|
|
||||||
|
bool Pop()
|
||||||
|
{
|
||||||
|
if (stack.empty())
|
||||||
|
{
|
||||||
|
NazaraAssert(stack.empty(), "Stack is empty");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
stack.pop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json json;
|
||||||
|
std::stack<nlohmann::json*> stack;
|
||||||
|
};
|
||||||
|
|
||||||
|
JsonSerializationContext::JsonSerializationContext()
|
||||||
|
: m_impl(std::make_unique<JsonImpl>())
|
||||||
|
{}
|
||||||
|
|
||||||
|
JsonSerializationContext::~JsonSerializationContext() {}
|
||||||
|
|
||||||
|
bool JsonSerializationContext::Load(const std::filesystem::path& path)
|
||||||
|
{
|
||||||
|
std::ifstream file(path);
|
||||||
|
if (!file || !file.is_open())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_impl->json = nlohmann::json::parse(file);
|
||||||
|
m_impl->stack.push(&m_impl->json);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JsonSerializationContext::PushObject(std::string_view name)
|
||||||
|
{
|
||||||
|
if (name.empty()) // special case if name is empty, don't push
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!m_impl->Top().contains(name))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!m_impl->Top()[name].is_object())
|
||||||
|
{
|
||||||
|
NazaraAssert(m_impl->Top()[name].is_object(), "Value is not an object");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_impl->stack.push(&m_impl->Top()[name]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JsonSerializationContext::PopObject()
|
||||||
|
{
|
||||||
|
return m_impl->Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JsonSerializationContext::PushArray(std::string_view name)
|
||||||
|
{
|
||||||
|
if (!m_impl->Top()[name].is_array())
|
||||||
|
{
|
||||||
|
NazaraAssert(m_impl->Top()[name].is_array(), "Value is not an array");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_impl->stack.push(&m_impl->Top()[name]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JsonSerializationContext::PopArray()
|
||||||
|
{
|
||||||
|
return m_impl->Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEF_SERIALIZE(Type, cond) \
|
||||||
|
bool JsonSerializationContext::Write(std::string_view name, Type value) \
|
||||||
|
{ \
|
||||||
|
m_impl->Top()[name] = value; \
|
||||||
|
return true; \
|
||||||
|
} \
|
||||||
|
bool JsonSerializationContext::Read(std::string_view name, Type* value) \
|
||||||
|
{ \
|
||||||
|
if (!m_impl->Top()[name].cond()) \
|
||||||
|
{ \
|
||||||
|
/*NazaraAssert(m_impl->Top()[name].cond(), "Value failed check: " #cond "()");*/\
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
*value = m_impl->Top()[name].get<Type>(); \
|
||||||
|
return true; \
|
||||||
|
} \
|
||||||
|
|
||||||
|
DEF_SERIALIZE(bool, is_boolean);
|
||||||
|
DEF_SERIALIZE(Nz::Int8, is_number);
|
||||||
|
DEF_SERIALIZE(Nz::Int16, is_number);
|
||||||
|
DEF_SERIALIZE(Nz::Int32, is_number);
|
||||||
|
DEF_SERIALIZE(Nz::Int64, is_number);
|
||||||
|
DEF_SERIALIZE(Nz::UInt8, is_number);
|
||||||
|
DEF_SERIALIZE(Nz::UInt16, is_number);
|
||||||
|
DEF_SERIALIZE(Nz::UInt32, is_number);
|
||||||
|
DEF_SERIALIZE(Nz::UInt64, is_number);
|
||||||
|
DEF_SERIALIZE(float, is_number);
|
||||||
|
DEF_SERIALIZE(double, is_number);
|
||||||
|
#undef DEF_SERIALIZE
|
||||||
|
|
||||||
|
bool JsonSerializationContext::Write(std::string_view name, const std::string& value)
|
||||||
|
{
|
||||||
|
m_impl->Top()[name] = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JsonSerializationContext::Read(std::string_view name, std::string* value)
|
||||||
|
{
|
||||||
|
if (!m_impl->Top()[name].is_string())
|
||||||
|
{
|
||||||
|
NazaraAssert(m_impl->Top()[name].is_string(), "Value failed check: is_string()");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*value = m_impl->Top()[name].get<std::string>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -107,7 +107,7 @@ local modules = {
|
||||||
remove_files("src/Nazara/Core/Posix/TimeImpl.cpp")
|
remove_files("src/Nazara/Core/Posix/TimeImpl.cpp")
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
Packages = { "concurrentqueue", "entt", "frozen", "ordered_map", "stb", "utfcpp" },
|
Packages = { "concurrentqueue", "entt", "frozen", "ordered_map", "stb", "utfcpp", "nlohmann_json" },
|
||||||
PublicPackages = { "nazarautils" }
|
PublicPackages = { "nazarautils" }
|
||||||
},
|
},
|
||||||
Graphics = {
|
Graphics = {
|
||||||
|
|
@ -284,7 +284,8 @@ add_requires(
|
||||||
"ordered_map",
|
"ordered_map",
|
||||||
"nazarautils >=2024.01.25",
|
"nazarautils >=2024.01.25",
|
||||||
"stb",
|
"stb",
|
||||||
"utfcpp"
|
"utfcpp",
|
||||||
|
"nlohmann_json"
|
||||||
)
|
)
|
||||||
|
|
||||||
-- Don't link with system-installed libs on CI
|
-- Don't link with system-installed libs on CI
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue