Skip to content

Commit

Permalink
gh-19: support asset loader implementation and auto registration usin…
Browse files Browse the repository at this point in the history
…g rtti
  • Loading branch information
EgorOrachyov committed Apr 23, 2024
1 parent 9034650 commit 12c7381
Show file tree
Hide file tree
Showing 86 changed files with 449 additions and 232 deletions.
10 changes: 10 additions & 0 deletions engine/asset/_rtti.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,23 @@
#pragma once

#include "asset/asset_import_data.hpp"
#include "asset/asset_loader.hpp"
#include "asset/asset_meta.hpp"
#include "asset/loaders/asset_loader_default.hpp"
#include "asset/loaders/asset_loader_texture.hpp"
#include "asset/loaders/asset_loader_wav.hpp"

namespace wmoge {

inline void rtti_asset() {
rtti_type<AssetImportData>();
rtti_type<AssetMetaFile>();
rtti_type<AssetMeta>();
rtti_type<AssetLoader>();
rtti_type<AssetLoaderDefault>();
rtti_type<AssetLoaderTexture2d>();
rtti_type<AssetLoaderTextureCube>();
rtti_type<AssetLoaderWav>();
}

}// namespace wmoge
2 changes: 1 addition & 1 deletion engine/asset/asset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

namespace wmoge {

Status yaml_read(const YamlConstNodeRef& node, AssetId& id) {
Status yaml_read(YamlConstNodeRef node, AssetId& id) {
WG_YAML_READ(node, id.m_name);
return StatusCode::Ok;
}
Expand Down
2 changes: 1 addition & 1 deletion engine/asset/asset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ namespace wmoge {
[[nodiscard]] bool is_empty() const { return m_name.empty(); }
[[nodiscard]] std::size_t hash() const { return m_name.hash(); }

friend Status yaml_read(const YamlConstNodeRef& node, AssetId& id);
friend Status yaml_read(YamlConstNodeRef node, AssetId& id);
friend Status yaml_write(YamlNodeRef node, const AssetId& id);
friend Status archive_read(Archive& archive, AssetId& id);
friend Status archive_write(Archive& archive, const AssetId& id);
Expand Down
2 changes: 1 addition & 1 deletion engine/asset/asset_import_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ namespace wmoge {
};

WG_RTTI_CLASS_BEGIN(AssetImportData) {
WG_RTTI_META_DATA({RttiUiName("Asset import data"), RttiUiHint("Asset manager assosiated data to import asset")});
WG_RTTI_META_DATA(RttiUiName("Asset import data"), RttiUiHint("Asset manager assosiated data to import asset"));
WG_RTTI_FACTORY();
WG_RTTI_FIELD(source_files, {RttiOptional});
}
Expand Down
18 changes: 14 additions & 4 deletions engine/asset/asset_loader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,28 @@
#include "asset/asset.hpp"
#include "asset/asset_meta.hpp"
#include "asset/asset_pak.hpp"
#include "rtti/traits.hpp"

namespace wmoge {

/**
* @class AssetLoader
* @brief Class responsible for loading or asset(s) in a specific format
*/
class AssetLoader {
class AssetLoader : public RttiObject {
public:
virtual ~AssetLoader() = default;
virtual Status load(const Strid& name, const AssetMeta& meta, Ref<Asset>& res) = 0;
virtual Strid get_name() = 0;
WG_RTTI_CLASS(AssetLoader, RttiObject);

AssetLoader() = default;
virtual ~AssetLoader() = default;

virtual Status load(const Strid& name, const AssetMeta& meta, Ref<Asset>& asset) { return StatusCode::NotImplemented; }
};

WG_RTTI_CLASS_BEGIN(AssetLoader) {
WG_RTTI_META_DATA(RttiUiHint("Interface for an asset loader to implement custom loading"));
// WG_RTTI_METHOD(load, {"name", "meta", "asset"}, {RttiUiHint("Instantiates and loads a particular asset type from meta info")});
}
WG_RTTI_END;

}// namespace wmoge
28 changes: 18 additions & 10 deletions engine/asset/asset_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,32 @@
#include "debug/profiler.hpp"
#include "event/event_asset.hpp"
#include "event/event_manager.hpp"
#include "platform/file_system.hpp"
#include "rtti/type_storage.hpp"
#include "system/engine.hpp"
#include "system/ioc_container.hpp"

#include "asset/paks/asset_pak_fs.hpp"

#include "asset/loaders/asset_loader_default.hpp"
#include "asset/loaders/asset_loader_texture.hpp"
#include "asset/loaders/asset_loader_wav.hpp"

#include <chrono>

namespace wmoge {

AssetManager::AssetManager() {
m_file_system = IocContainer::instance()->resolve_v<FileSystem>();
m_type_storage = IocContainer::instance()->resolve_v<RttiTypeStorage>();

std::vector<RttiClass*> loaders = m_type_storage->find_classes([](const Ref<RttiClass>& type) {
return type->is_subtype_of(AssetLoader::get_class_static()) && type->can_instantiate();
});

for (auto& loader : loaders) {
assert(loader);
assert(loader->can_instantiate());
add_loader(loader->instantiate().cast<AssetLoader>());
}

add_pak(std::make_shared<AssetPakFileSystem>());
add_loader(std::make_shared<AssetLoaderDefault>());
add_loader(std::make_shared<AssetLoaderTexture2d>());
add_loader(std::make_shared<AssetLoaderTextureCube>());
add_loader(std::make_shared<AssetLoaderWav>());
}

AsyncResult<Ref<Asset>> AssetManager::load_async(const AssetId& name, AssetCallback callback) {
Expand Down Expand Up @@ -180,9 +188,9 @@ namespace wmoge {
return {};
}

void AssetManager::add_loader(std::shared_ptr<AssetLoader> loader) {
void AssetManager::add_loader(Ref<AssetLoader> loader) {
std::lock_guard guard(m_mutex);
m_loaders[loader->get_name()] = std::move(loader);
m_loaders[loader->get_class_name()] = std::move(loader);
}

void AssetManager::add_pak(std::shared_ptr<AssetPak> pak) {
Expand Down
13 changes: 8 additions & 5 deletions engine/asset/asset_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "core/object.hpp"
#include "core/string_id.hpp"
#include "core/task.hpp"
#include "rtti/traits.hpp"

#include <filesystem>
#include <functional>
Expand Down Expand Up @@ -123,7 +124,7 @@ namespace wmoge {
Ref<Asset> find(const AssetId& name);

/** @brief Add specific format asset loader */
void add_loader(std::shared_ptr<AssetLoader> loader);
void add_loader(Ref<AssetLoader> loader);

/** @brief Add additional pak for assets loading */
void add_pak(std::shared_ptr<AssetPak> pak);
Expand Down Expand Up @@ -174,10 +175,12 @@ namespace wmoge {
};

private:
buffered_vector<std::shared_ptr<AssetPak>> m_paks;
flat_map<AssetId, WeakRef<Asset>> m_assets;
flat_map<AssetId, LoadState> m_loading;
flat_map<Strid, std::shared_ptr<AssetLoader>> m_loaders;
buffered_vector<std::shared_ptr<AssetPak>> m_paks;
flat_map<AssetId, WeakRef<Asset>> m_assets;
flat_map<AssetId, LoadState> m_loading;
flat_map<Strid, Ref<AssetLoader>> m_loaders;
class FileSystem* m_file_system = nullptr;
class RttiTypeStorage* m_type_storage = nullptr;

mutable std::recursive_mutex m_mutex;
};
Expand Down
11 changes: 11 additions & 0 deletions engine/asset/asset_meta.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ namespace wmoge {
* @brief Meta information of a particular asset
*/
struct AssetMeta {
WG_RTTI_STRUCT(AssetMeta);

UUID uuid = UUID();
class Class* cls = nullptr;
class AssetPak* pak = nullptr;
Expand All @@ -85,4 +87,13 @@ namespace wmoge {
Ref<AssetImportData> import_data;
};

WG_RTTI_STRUCT_BEGIN(AssetMeta) {
WG_RTTI_META_DATA();
WG_RTTI_FIELD(uuid, {RttiOptional});
WG_RTTI_FIELD(deps, {RttiOptional});
WG_RTTI_FIELD(path_on_disk, {RttiOptional});
WG_RTTI_FIELD(import_data, {RttiOptional});
}
WG_RTTI_END;

}// namespace wmoge
4 changes: 2 additions & 2 deletions engine/asset/asset_ref.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ namespace wmoge {
};

template<typename T>
Status yaml_read(const YamlConstNodeRef& node, AssetRef<T>& ref) {
Status yaml_read(YamlConstNodeRef node, AssetRef<T>& ref) {
AssetId id;
WG_YAML_READ(node, id);
Ref<T> ptr = Engine::instance()->asset_manager()->load(id).cast<T>();
Expand Down Expand Up @@ -111,7 +111,7 @@ namespace wmoge {
}

template<typename T>
Status yaml_read(const YamlConstNodeRef& node, AssetRefWeak<T>& ref) {
Status yaml_read(YamlConstNodeRef node, AssetRefWeak<T>& ref) {
AssetId id;
WG_YAML_READ(node, id);
ref = AssetRefWeak<T>(id);
Expand Down
2 changes: 1 addition & 1 deletion engine/asset/audio_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

namespace wmoge {

Status yaml_read(const YamlConstNodeRef& node, AudioImportOptions& options) {
Status yaml_read(YamlConstNodeRef node, AudioImportOptions& options) {
WG_YAML_READ_AS(node, "source_file", options.source_file);

return StatusCode::Ok;
Expand Down
2 changes: 1 addition & 1 deletion engine/asset/audio_stream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace wmoge {
struct AudioImportOptions {
std::string source_file;

friend Status yaml_read(const YamlConstNodeRef& node, AudioImportOptions& options);
friend Status yaml_read(YamlConstNodeRef node, AudioImportOptions& options);
friend Status yaml_write(YamlNodeRef node, const AudioImportOptions& options);
};

Expand Down
13 changes: 5 additions & 8 deletions engine/asset/loaders/asset_loader_default.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@

namespace wmoge {

Status AssetLoaderDefault::load(const Strid& name, const AssetMeta& meta, Ref<Asset>& res) {
Status AssetLoaderDefault::load(const Strid& name, const AssetMeta& meta, Ref<Asset>& asset) {
WG_AUTO_PROFILE_ASSET("AssetLoaderDefault::load");

res = meta.cls->instantiate().cast<Asset>();
asset = meta.cls->instantiate().cast<Asset>();

if (!res) {
if (!asset) {
WG_LOG_ERROR("failed to instantiate asset " << name);
return StatusCode::FailedInstantiate;
}
Expand All @@ -53,17 +53,14 @@ namespace wmoge {
return StatusCode::FailedParse;
};

res->set_name(name);
asset->set_name(name);

if (!res->read_from_yaml(asset_tree.crootref())) {
if (!asset->read_from_yaml(asset_tree.crootref())) {
WG_LOG_ERROR("failed to load asset from file " << meta.path_on_disk.value());
return StatusCode::FailedRead;
}

return StatusCode::Ok;
}
Strid AssetLoaderDefault::get_name() {
return SID("default");
}

}// namespace wmoge
13 changes: 11 additions & 2 deletions engine/asset/loaders/asset_loader_default.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,18 @@ namespace wmoge {
*/
class AssetLoaderDefault final : public AssetLoader {
public:
WG_RTTI_CLASS(AssetLoaderDefault, AssetLoader);

AssetLoaderDefault() = default;
~AssetLoaderDefault() override = default;
Status load(const Strid& name, const AssetMeta& meta, Ref<Asset>& res) override;
Strid get_name() override;

Status load(const Strid& name, const AssetMeta& meta, Ref<Asset>& asset) override;
};

WG_RTTI_CLASS_BEGIN(AssetLoaderDefault) {
WG_RTTI_META_DATA();
WG_RTTI_FACTORY();
}
WG_RTTI_END;

}// namespace wmoge
18 changes: 6 additions & 12 deletions engine/asset/loaders/asset_loader_texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

namespace wmoge {

Status AssetLoaderTexture2d::load(const Strid& name, const AssetMeta& meta, Ref<Asset>& res) {
Status AssetLoaderTexture2d::load(const Strid& name, const AssetMeta& meta, Ref<Asset>& asset) {
WG_AUTO_PROFILE_ASSET("AssetLoaderTexture2d::load");

if (!meta.import_options.has_value()) {
Expand Down Expand Up @@ -70,8 +70,8 @@ namespace wmoge {
return StatusCode::FailedInstantiate;
}

res = texture;
res->set_name(name);
asset = texture;
asset->set_name(name);

texture->set_source_images({source_image});
texture->set_sampler_from_desc(options.sampling);
Expand All @@ -96,11 +96,8 @@ namespace wmoge {

return StatusCode::Ok;
}
Strid AssetLoaderTexture2d::get_name() {
return SID("texture_2d");
}

Status AssetLoaderTextureCube::load(const Strid& name, const AssetMeta& meta, Ref<Asset>& res) {
Status AssetLoaderTextureCube::load(const Strid& name, const AssetMeta& meta, Ref<Asset>& asset) {
WG_AUTO_PROFILE_ASSET("AssetLoaderTextureCube::load");

if (!meta.import_options.has_value()) {
Expand Down Expand Up @@ -149,8 +146,8 @@ namespace wmoge {
return StatusCode::Error;
}

res = texture;
res->set_name(name);
asset = texture;
asset->set_name(name);

texture->set_source_images(source_images);
texture->set_sampler_from_desc(options.sampling);
Expand All @@ -175,8 +172,5 @@ namespace wmoge {

return StatusCode::Ok;
}
Strid AssetLoaderTextureCube::get_name() {
return SID("texture_cube");
}

}// namespace wmoge
26 changes: 22 additions & 4 deletions engine/asset/loaders/asset_loader_texture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,38 @@ namespace wmoge {
*/
class AssetLoaderTexture2d final : public AssetLoader {
public:
WG_RTTI_CLASS(AssetLoaderTexture2d, AssetLoader);

AssetLoaderTexture2d() = default;
~AssetLoaderTexture2d() override = default;
Status load(const Strid& name, const AssetMeta& meta, Ref<Asset>& res) override;
Strid get_name() override;

Status load(const Strid& name, const AssetMeta& meta, Ref<Asset>& asset) override;
};

WG_RTTI_CLASS_BEGIN(AssetLoaderTexture2d) {
WG_RTTI_META_DATA();
WG_RTTI_FACTORY();
}
WG_RTTI_END;

/**
* @class AssetLoaderTextureCube
* @brief Loader for cube-map textures through stb image library
*/
class AssetLoaderTextureCube final : public AssetLoader {
public:
WG_RTTI_CLASS(AssetLoaderTextureCube, AssetLoader);

AssetLoaderTextureCube() = default;
~AssetLoaderTextureCube() override = default;
Status load(const Strid& name, const AssetMeta& meta, Ref<Asset>& res) override;
Strid get_name() override;

Status load(const Strid& name, const AssetMeta& meta, Ref<Asset>& asset) override;
};

WG_RTTI_CLASS_BEGIN(AssetLoaderTextureCube) {
WG_RTTI_META_DATA();
WG_RTTI_FACTORY();
}
WG_RTTI_END;

}// namespace wmoge
Loading

0 comments on commit 12c7381

Please sign in to comment.