From 3cfb04c98046626a017a93232286079732d50bce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diogo=20Mendon=C3=A7a?= Date: Thu, 31 Aug 2023 23:02:27 +0100 Subject: [PATCH] feat(engine): allow getting the type of an asset --- engine/include/cubos/engine/assets/assets.hpp | 10 +++++++++ engine/include/cubos/engine/assets/bridge.hpp | 21 ++++++++++++++++++- .../cubos/engine/assets/bridges/binary.hpp | 3 ++- .../cubos/engine/assets/bridges/file.hpp | 8 +++++++ .../cubos/engine/assets/bridges/json.hpp | 3 ++- engine/include/cubos/engine/scene/bridge.hpp | 8 +++++++ engine/samples/assets/bridge/main.cpp | 5 +++++ engine/src/cubos/engine/assets/assets.cpp | 20 ++++++++++++++++++ 8 files changed, 75 insertions(+), 3 deletions(-) diff --git a/engine/include/cubos/engine/assets/assets.hpp b/engine/include/cubos/engine/assets/assets.hpp index 3a378605d..ec4b899f5 100644 --- a/engine/include/cubos/engine/assets/assets.hpp +++ b/engine/include/cubos/engine/assets/assets.hpp @@ -211,6 +211,16 @@ namespace cubos::engine /// @return Vector with all registered assets. std::vector listAll() const; + /// @brief Gets the type of an asset. + /// + /// If the asset is not loaded, its type is deduced from its bridge. + /// If there's also no associated bridge, aborts. + /// If the asset does not exist, aborts. + /// + /// @param handle Handle to check the type for. + /// @return Asset type. + std::type_index type(const AnyAsset& handle) const; + private: /// @brief Represents a known asset - may or may not be loaded. struct Entry diff --git a/engine/include/cubos/engine/assets/bridge.hpp b/engine/include/cubos/engine/assets/bridge.hpp index 0b586449f..313ea454f 100644 --- a/engine/include/cubos/engine/assets/bridge.hpp +++ b/engine/include/cubos/engine/assets/bridge.hpp @@ -7,6 +7,8 @@ #pragma once +#include + #include namespace cubos::engine @@ -26,7 +28,14 @@ namespace cubos::engine class AssetBridge { public: - AssetBridge() = default; + /// @brief Constructs a bridge. + /// + /// @param index Type of assets loaded by the bridge. + explicit AssetBridge(std::type_index index) + : mIndex(index) + { + } + virtual ~AssetBridge() = default; /// @brief Loads an asset. @@ -46,5 +55,15 @@ namespace cubos::engine /// @param handle Handle of the asset being saved. /// @return Whether the asset was successfully saved. virtual bool save(const Assets& assets, const AnyAsset& handle); + + /// @brief Gets the type of the assets the bridge loads. + /// @return Type of the asset. + inline std::type_index assetType() const + { + return mIndex; + } + + private: + std::type_index mIndex; ///< Type of assets loaded by the bridge }; } // namespace cubos::engine diff --git a/engine/include/cubos/engine/assets/bridges/binary.hpp b/engine/include/cubos/engine/assets/bridges/binary.hpp index 88288c03d..55f804591 100644 --- a/engine/include/cubos/engine/assets/bridges/binary.hpp +++ b/engine/include/cubos/engine/assets/bridges/binary.hpp @@ -27,7 +27,8 @@ namespace cubos::engine /// @brief Constructs a bridge. /// @param littleEndian Whether to use little endian byte order. BinaryBridge(bool littleEndian = true) - : mLittleEndian{littleEndian} + : FileBridge(typeid(T)) + , mLittleEndian{littleEndian} { } diff --git a/engine/include/cubos/engine/assets/bridges/file.hpp b/engine/include/cubos/engine/assets/bridges/file.hpp index 06c7281a2..97e44efda 100644 --- a/engine/include/cubos/engine/assets/bridges/file.hpp +++ b/engine/include/cubos/engine/assets/bridges/file.hpp @@ -21,6 +21,14 @@ namespace cubos::engine class FileBridge : public AssetBridge { public: + /// @brief Constructs a bridge. + /// + /// @param index Type of assets loaded by the bridge. + explicit FileBridge(std::type_index index) + : AssetBridge(index) + { + } + bool load(Assets& assets, const AnyAsset& handle) final; bool save(const Assets& assets, const AnyAsset& handle) final; diff --git a/engine/include/cubos/engine/assets/bridges/json.hpp b/engine/include/cubos/engine/assets/bridges/json.hpp index 4502d5e8f..1ce9752b9 100644 --- a/engine/include/cubos/engine/assets/bridges/json.hpp +++ b/engine/include/cubos/engine/assets/bridges/json.hpp @@ -30,7 +30,8 @@ namespace cubos::engine /// /// @param indentation Indentation level to use when saving the JSON file. JSONBridge(int indentation = 4) - : mIndentation{indentation} + : FileBridge(typeid(T)) + , mIndentation{indentation} { } diff --git a/engine/include/cubos/engine/scene/bridge.hpp b/engine/include/cubos/engine/scene/bridge.hpp index ba3b3f738..efb283296 100644 --- a/engine/include/cubos/engine/scene/bridge.hpp +++ b/engine/include/cubos/engine/scene/bridge.hpp @@ -5,6 +5,7 @@ #pragma once #include +#include namespace cubos::engine { @@ -45,6 +46,13 @@ namespace cubos::engine class SceneBridge : public AssetBridge { public: + /// @brief Constructs a bridge. + /// + SceneBridge() + : AssetBridge(typeid(Scene)) + { + } + bool load(Assets& assets, const AnyAsset& handle) override; bool save(const Assets& assets, const AnyAsset& handle) override; }; diff --git a/engine/samples/assets/bridge/main.cpp b/engine/samples/assets/bridge/main.cpp index 1cf2b741c..601ae8eac 100644 --- a/engine/samples/assets/bridge/main.cpp +++ b/engine/samples/assets/bridge/main.cpp @@ -21,6 +21,11 @@ using namespace cubos::engine; class TextBridge : public FileBridge { public: + TextBridge() + : FileBridge(typeid(std::string)) + { + } + bool loadFromFile(Assets& assets, const AnyAsset& handle, Stream& stream) override { // Dump the file's contents into a string. diff --git a/engine/src/cubos/engine/assets/assets.cpp b/engine/src/cubos/engine/assets/assets.cpp index 65c04647c..d505e6c40 100644 --- a/engine/src/cubos/engine/assets/assets.cpp +++ b/engine/src/cubos/engine/assets/assets.cpp @@ -589,6 +589,12 @@ void Assets::loader() assetEntry->status = Assets::Status::Unloaded; assetEntry->cond.notify_all(); } + else + { + auto assetEntry = this->entry(task.handle); + CUBOS_ASSERT(assetEntry != nullptr); + CUBOS_ASSERT(assetEntry->type == task.bridge->assetType()); + } } } @@ -600,4 +606,18 @@ std::vector Assets::listAll() const out.emplace_back(entry); } return out; +} + +std::type_index Assets::type(const AnyAsset& handle) const +{ + auto assetEntry = this->entry(handle); + CUBOS_ASSERT(assetEntry != nullptr, "Could not find asset's type"); + if (assetEntry->status == Status::Loaded) + { + return assetEntry->type; + } + + auto bridge = this->bridge(handle); + CUBOS_ASSERT(bridge != nullptr, "Could not find asset's type"); + return bridge->assetType(); } \ No newline at end of file