From 875404246fc38caba2d260862c17e9208867a7a8 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 5 May 2020 00:00:48 +0200 Subject: [PATCH] Add meta information to Asset class --- include/openspace/scene/asset.h | 13 +++++++ include/openspace/scene/assetlistener.h | 2 +- include/openspace/scene/assetloader.h | 2 +- include/openspace/scene/assetmanager.h | 2 +- modules/sync/tasks/syncassettask.cpp | 2 +- src/scene/asset.cpp | 7 ++-- src/scene/assetloader.cpp | 48 +++++++++++++++++++++---- src/scene/assetmanager.cpp | 2 +- 8 files changed, 64 insertions(+), 14 deletions(-) diff --git a/include/openspace/scene/asset.h b/include/openspace/scene/asset.h index 6df0769dcc..a063e71b01 100644 --- a/include/openspace/scene/asset.h +++ b/include/openspace/scene/asset.h @@ -51,6 +51,15 @@ public: using StateChangeCallback = std::function; using CallbackHandle = size_t; + struct MetaInformation { + std::string name; + std::string version; + std::string description; + std::string author; + std::string url; + std::string license; + }; + /** * Root asset constructor */ @@ -136,6 +145,8 @@ public: std::string resolveLocalResource(std::string resourceName) const; + void setMetaInformation(MetaInformation metaInformation); + private: void setState(State state); @@ -157,6 +168,8 @@ private: // Absolute path to asset file std::string _assetPath; + MetaInformation _metaInformation; + // Required assets std::vector> _requiredAssets; diff --git a/include/openspace/scene/assetlistener.h b/include/openspace/scene/assetlistener.h index a1adaade1e..b507c82f23 100644 --- a/include/openspace/scene/assetlistener.h +++ b/include/openspace/scene/assetlistener.h @@ -32,7 +32,7 @@ namespace openspace { class AssetListener { public: virtual ~AssetListener() = default; - virtual void assetStateChanged(std::shared_ptr asset, Asset::State state) = 0; + virtual void assetStateChanged(Asset* asset, Asset::State state) = 0; virtual void assetRequested(Asset* parent, std::shared_ptr child) = 0; diff --git a/include/openspace/scene/assetloader.h b/include/openspace/scene/assetloader.h index 0192441189..0f6ad9bbee 100644 --- a/include/openspace/scene/assetloader.h +++ b/include/openspace/scene/assetloader.h @@ -157,7 +157,7 @@ public: /** * Notify listeners about asset state change */ - void assetStateChanged(std::shared_ptr asset, Asset::State state); + void assetStateChanged(Asset* asset, Asset::State state); /** * Notify listeners about new requests diff --git a/include/openspace/scene/assetmanager.h b/include/openspace/scene/assetmanager.h index 282b8b1623..42d6b311c8 100644 --- a/include/openspace/scene/assetmanager.h +++ b/include/openspace/scene/assetmanager.h @@ -61,7 +61,7 @@ public: void removeAll(); std::shared_ptr rootAsset(); - void assetStateChanged(std::shared_ptr asset, Asset::State state) override; + void assetStateChanged(Asset* asset, Asset::State state) override; void assetRequested(Asset* parent, std::shared_ptr child) override; void assetUnrequested(Asset* parent, diff --git a/modules/sync/tasks/syncassettask.cpp b/modules/sync/tasks/syncassettask.cpp index f98301e120..2e23c5e61b 100644 --- a/modules/sync/tasks/syncassettask.cpp +++ b/modules/sync/tasks/syncassettask.cpp @@ -77,7 +77,7 @@ documentation::Documentation SyncAssetTask::documentation() { class RequestListener : public AssetListener { public: virtual ~RequestListener() = default; - void assetStateChanged(std::shared_ptr asset, Asset::State state) override { + void assetStateChanged(Asset* asset, Asset::State state) override { if (state == Asset::State::LoadingFailed) { LERROR(fmt::format("Failed to load asset: {}", asset->id())); } diff --git a/src/scene/asset.cpp b/src/scene/asset.cpp index 5bbd46a42f..9cd55f9b54 100644 --- a/src/scene/asset.cpp +++ b/src/scene/asset.cpp @@ -87,6 +87,10 @@ std::string Asset::resolveLocalResource(std::string resourceName) const { return dir + ghoul::filesystem::FileSystem::PathSeparator + std::move(resourceName); } +void Asset::setMetaInformation(MetaInformation metaInformation) { + _metaInformation = std::move(metaInformation); +} + Asset::State Asset::state() const { return _state; } @@ -105,8 +109,7 @@ void Asset::setState(Asset::State state) { } _state = state; - std::shared_ptr thisAsset = shared_from_this(); - _loader->assetStateChanged(thisAsset, state); + _loader->assetStateChanged(this, state); for (const std::weak_ptr& requiringAsset : _requiringAssets) { if (std::shared_ptr a = requiringAsset.lock()) { diff --git a/src/scene/assetloader.cpp b/src/scene/assetloader.cpp index 56fc0b824e..e360f20f5a 100644 --- a/src/scene/assetloader.cpp +++ b/src/scene/assetloader.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "assetloader_lua.inl" @@ -54,6 +55,14 @@ namespace { constexpr const char* DirectoryConstantName = "directory"; constexpr const char* FilePathConstantName = "filePath"; + constexpr const char* MetaInformationKey = "meta"; + constexpr const char* MetaInformationName = "Name"; + constexpr const char* MetaInformationVersion = "Version"; + constexpr const char* MetaInformationDescription = "Description"; + constexpr const char* MetaInformationAuthor = "Author"; + constexpr const char* MetaInformationURL = "URL"; + constexpr const char* MetaInformationLicense = "License"; + constexpr const char* ExportsTableName = "_exports"; constexpr const char* AssetTableName = "_asset"; constexpr const char* DependantsTableName = "_dependants"; @@ -278,6 +287,35 @@ bool AssetLoader::loadAsset(Asset* asset) { return false; } + // Extract meta information from the asset file if it was provided + // 1. Load the asset table + lua_getglobal(*_luaState, AssetGlobalVariableName); + ghoul_assert(lua_istable(*_luaState, -1), "Expected 'asset' table"); + lua_getfield(*_luaState, -1, MetaInformationKey); + if (!lua_isnil(*_luaState, -1)) { + // The 'meta' object exist; quick sanity check that it is a table + if (!lua_istable(*_luaState, -1)) { + LWARNING(fmt::format( + "When loading asset '{}', encountered a '{}' entry that was not a table", + asset->assetFilePath(), MetaInformationKey + )); + } + else { + // The 'meta' object exists and it is a table + ghoul::Dictionary metaDict; + ghoul::lua::luaDictionaryFromState(*_luaState, metaDict); + + Asset::MetaInformation meta; + metaDict.getValue(MetaInformationName, meta.name); + metaDict.getValue(MetaInformationVersion, meta.version); + metaDict.getValue(MetaInformationDescription, meta.description); + metaDict.getValue(MetaInformationAuthor, meta.author); + metaDict.getValue(MetaInformationURL, meta.url); + metaDict.getValue(MetaInformationLicense, meta.license); + asset->setMetaInformation(std::move(meta)); + } + } + lua_settop(*_luaState, top); return true; } @@ -784,23 +822,19 @@ void AssetLoader::removeAssetListener(AssetListener* listener) { )); } -void AssetLoader::assetStateChanged(std::shared_ptr asset, Asset::State state) { +void AssetLoader::assetStateChanged(Asset* asset, Asset::State state) { for (AssetListener* listener : _assetListeners) { listener->assetStateChanged(asset, state); } } -void AssetLoader::assetRequested(Asset* parent, - std::shared_ptr child) -{ +void AssetLoader::assetRequested(Asset* parent, std::shared_ptr child) { for (AssetListener* listener : _assetListeners) { listener->assetRequested(parent, child); } } -void AssetLoader::assetUnrequested(Asset* parent, - std::shared_ptr child) -{ +void AssetLoader::assetUnrequested(Asset* parent, std::shared_ptr child) { for (AssetListener* listener : _assetListeners) { listener->assetUnrequested(parent, child); } diff --git a/src/scene/assetmanager.cpp b/src/scene/assetmanager.cpp index 5fa07a3a27..18d9089a2f 100644 --- a/src/scene/assetmanager.cpp +++ b/src/scene/assetmanager.cpp @@ -82,7 +82,7 @@ bool AssetManager::update() { return false; } -void AssetManager::assetStateChanged(std::shared_ptr, Asset::State) { +void AssetManager::assetStateChanged(Asset*, Asset::State) { // Potential todo: notify user about asset stage change //LINFO(asset->id() << " changed state to " << static_cast(state)); }