mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-22 04:49:12 -06:00
Merge pull request #1187 from OpenSpace/feature/license
Feature/license
This commit is contained in:
@@ -18,3 +18,12 @@ end)
|
||||
asset.onDeinitialize(function ()
|
||||
openspace.removeInterestingNodes({ "Earth", "Mars", "Moon", "Sun" })
|
||||
end)
|
||||
|
||||
asset.meta = {
|
||||
Name = "Default scene",
|
||||
Version = "1.0",
|
||||
Description = [[ Bla bla, something something asteroids ]],
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
|
||||
@@ -22,3 +22,13 @@ asset.request('./planets/uranus/major_moons')
|
||||
|
||||
asset.request('./planets/neptune/neptune')
|
||||
asset.request('./planets/neptune/major_moons')
|
||||
|
||||
|
||||
asset.meta = {
|
||||
Name = "Planets",
|
||||
Version = "1.0",
|
||||
Description = [[ Collection of planets in the solar system ]],
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
|
||||
@@ -329,3 +329,13 @@ local EarthLabel = {
|
||||
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { Earth, EarthLabel })
|
||||
|
||||
|
||||
asset.meta = {
|
||||
Name = "Earth",
|
||||
Version = "1.0",
|
||||
Description = [[ Earth is a special planet with special needs ]],
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
|
||||
@@ -82,3 +82,13 @@ end
|
||||
|
||||
|
||||
asset.export("setCefRoute", setCefRoute)
|
||||
|
||||
|
||||
asset.meta = {
|
||||
Name = "WebGUI",
|
||||
Version = "0.1",
|
||||
Description = [[ insert CEF rant ]],
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
|
||||
@@ -3,14 +3,12 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<p>
|
||||
<a href="#{{urlify module}}" name="{{urlify module}}">
|
||||
<span class="documentation-key">{{module}}</span>
|
||||
</a>
|
||||
<p>{{name}}</p>
|
||||
<br />
|
||||
<p>{{attribution}}</p>
|
||||
<p>{{url}}</p>
|
||||
<p>{{licenseText}}</p>
|
||||
<h3>Asset - {{name}}</h3>
|
||||
<p>{{description}}</p>
|
||||
<p>Version - {{version}}</p>
|
||||
<p>Author - {{author}}</p>
|
||||
<p>Associated URL - <a href="{{url}}">{{url}}</a></p>
|
||||
<p>Filepath - {{path}}</p>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Submodule ext/ghoul updated: df1522a1fe...767fa3e42e
@@ -28,6 +28,7 @@
|
||||
#include <openspace/util/resourcesynchronization.h>
|
||||
#include <openspace/util/synchronizationwatcher.h>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -37,7 +38,7 @@ class AssetLoader;
|
||||
|
||||
class Asset : public std::enable_shared_from_this<Asset> {
|
||||
public:
|
||||
enum class State : unsigned int {
|
||||
enum class State {
|
||||
Unloaded,
|
||||
LoadingFailed,
|
||||
Loaded,
|
||||
@@ -48,8 +49,14 @@ public:
|
||||
InitializationFailed
|
||||
};
|
||||
|
||||
using StateChangeCallback = std::function<void(State)>;
|
||||
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
|
||||
@@ -69,10 +76,9 @@ public:
|
||||
AssetLoader* loader() const;
|
||||
State state() const;
|
||||
|
||||
void addSynchronization(std::shared_ptr<ResourceSynchronization> synchronization);
|
||||
void addSynchronization(std::unique_ptr<ResourceSynchronization> synchronization);
|
||||
void clearSynchronizations();
|
||||
const std::vector<std::shared_ptr<ResourceSynchronization>>&
|
||||
ownSynchronizations() const;
|
||||
std::vector<ResourceSynchronization*> ownSynchronizations() const;
|
||||
|
||||
void syncStateChanged(ResourceSynchronization* sync,
|
||||
ResourceSynchronization::State state);
|
||||
@@ -92,12 +98,6 @@ public:
|
||||
* its own synchronizations and required assets' synchronizations could start.
|
||||
*/
|
||||
bool startSynchronizations();
|
||||
bool hasSyncingOrResolvedParent() const;
|
||||
bool isSynchronized() const;
|
||||
bool isSyncingOrResolved() const;
|
||||
bool cancelAllSynchronizations();
|
||||
bool cancelUnwantedSynchronizations();
|
||||
bool restartAllSynchronizations();
|
||||
float requiredSynchronizationProgress() const;
|
||||
float requestedSynchronizationProgress();
|
||||
|
||||
@@ -120,21 +120,16 @@ public:
|
||||
void request(std::shared_ptr<Asset> child);
|
||||
void unrequest(Asset* child);
|
||||
|
||||
const std::vector<std::shared_ptr<Asset>>& requestedAssets() const;
|
||||
std::vector<std::shared_ptr<Asset>> requestingAssets() const;
|
||||
const std::vector<std::shared_ptr<Asset>>& requiredAssets() const;
|
||||
std::vector<std::shared_ptr<Asset>> requiringAssets() const;
|
||||
std::vector<Asset*> requestedAssets() const;
|
||||
std::vector<Asset*> requestingAssets() const;
|
||||
std::vector<Asset*> requiredAssets() const;
|
||||
std::vector<Asset*> requiringAssets() const;
|
||||
|
||||
std::vector<std::shared_ptr<const Asset>> requiredSubTreeAssets() const;
|
||||
std::vector<std::shared_ptr<const Asset>> subTreeAssets() const;
|
||||
std::vector<std::shared_ptr<Asset>> childAssets() const;
|
||||
std::vector<std::shared_ptr<Asset>> parentAssets() const;
|
||||
std::vector<const Asset*> subTreeAssets() const;
|
||||
std::vector<Asset*> childAssets() const;
|
||||
|
||||
bool isRequired() const;
|
||||
bool isRequested() const;
|
||||
bool shouldBeInitialized() const;
|
||||
|
||||
std::string resolveLocalResource(std::string resourceName);
|
||||
void setMetaInformation(MetaInformation metaInformation);
|
||||
std::optional<MetaInformation> metaInformation() const;
|
||||
|
||||
private:
|
||||
void setState(State state);
|
||||
@@ -142,7 +137,14 @@ private:
|
||||
void requiredAssetChangedState(Asset::State childState);
|
||||
void requestedAssetChangedState(Asset* child, Asset::State childState);
|
||||
|
||||
bool isSynchronized() const;
|
||||
bool isSyncingOrResolved() const;
|
||||
bool isSyncResolveReady();
|
||||
bool hasSyncingOrResolvedParent() const;
|
||||
bool cancelAllSynchronizations();
|
||||
bool cancelUnwantedSynchronizations();
|
||||
|
||||
std::vector<const Asset*> requiredSubTreeAssets() const;
|
||||
|
||||
std::atomic<State> _state;
|
||||
AssetLoader* _loader;
|
||||
@@ -157,6 +159,8 @@ private:
|
||||
// Absolute path to asset file
|
||||
std::string _assetPath;
|
||||
|
||||
std::optional<MetaInformation> _metaInformation;
|
||||
|
||||
// Required assets
|
||||
std::vector<std::shared_ptr<Asset>> _requiredAssets;
|
||||
|
||||
|
||||
@@ -32,12 +32,9 @@ namespace openspace {
|
||||
class AssetListener {
|
||||
public:
|
||||
virtual ~AssetListener() = default;
|
||||
virtual void assetStateChanged(std::shared_ptr<Asset> asset, Asset::State state) = 0;
|
||||
virtual void assetRequested(std::shared_ptr<Asset> parent,
|
||||
std::shared_ptr<Asset> child) = 0;
|
||||
|
||||
virtual void assetUnrequested(std::shared_ptr<Asset> parent,
|
||||
std::shared_ptr<Asset> child) = 0;
|
||||
virtual void assetStateChanged(Asset* asset, Asset::State state) = 0;
|
||||
virtual void assetRequested(Asset* parent, std::shared_ptr<Asset> child) = 0;
|
||||
virtual void assetUnrequested(Asset* parent, std::shared_ptr<Asset> child) = 0;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -49,15 +49,13 @@ int request(lua_State* state);
|
||||
int exists(lua_State* state);
|
||||
int localResource(lua_State* state);
|
||||
int syncedResource(lua_State* state);
|
||||
int noOperation(lua_State* state);
|
||||
int exportAsset(lua_State* state);
|
||||
|
||||
} // namespace assetloader
|
||||
|
||||
class Asset;
|
||||
class AssetListener;
|
||||
class ResourceSynchronization;
|
||||
class SynchronizationWatcher;
|
||||
class AssetListener;
|
||||
|
||||
class AssetLoader {
|
||||
public:
|
||||
@@ -87,30 +85,26 @@ public:
|
||||
void untrackAsset(Asset* asset);
|
||||
|
||||
/**
|
||||
* Return the asset identified by the identifier,
|
||||
* if the asset is tracked. Otherwise return nullptr.
|
||||
*/
|
||||
* Return the asset identified by the identifier,
|
||||
* if the asset is tracked. Otherwise return nullptr.
|
||||
*/
|
||||
std::shared_ptr<Asset> has(const std::string& identifier) const;
|
||||
|
||||
/**
|
||||
* Return the lua state
|
||||
*/
|
||||
ghoul::lua::LuaState* luaState();
|
||||
/// Return the root asset
|
||||
const Asset& rootAsset() const;
|
||||
|
||||
/// Return the root asset
|
||||
Asset& rootAsset();
|
||||
|
||||
/**
|
||||
* Return the root asset
|
||||
* Return the asset root directory
|
||||
*/
|
||||
std::shared_ptr<Asset> rootAsset() const;
|
||||
|
||||
/**
|
||||
* Return the asset root directory
|
||||
*/
|
||||
const std::string& assetRootDirectory() const;
|
||||
|
||||
/**
|
||||
* Load an asset
|
||||
*/
|
||||
bool loadAsset(std::shared_ptr<Asset> asset);
|
||||
bool loadAsset(Asset* asset);
|
||||
|
||||
/**
|
||||
* Unload an asset
|
||||
@@ -157,30 +151,29 @@ public:
|
||||
/**
|
||||
* Notify listeners about asset state change
|
||||
*/
|
||||
void assetStateChanged(std::shared_ptr<Asset> asset, Asset::State state);
|
||||
void assetStateChanged(Asset* asset, Asset::State state);
|
||||
|
||||
/**
|
||||
* Notify listeners about new requests
|
||||
*/
|
||||
void assetRequested(std::shared_ptr<Asset> parent, std::shared_ptr<Asset> child);
|
||||
void assetRequested(Asset* parent, std::shared_ptr<Asset> child);
|
||||
|
||||
/**
|
||||
* Notify listeners about removed requests
|
||||
*/
|
||||
void assetUnrequested(std::shared_ptr<Asset> parent, std::shared_ptr<Asset> child);
|
||||
void assetUnrequested(Asset* parent, std::shared_ptr<Asset> child);
|
||||
|
||||
private:
|
||||
std::shared_ptr<Asset> require(const std::string& identifier);
|
||||
std::shared_ptr<Asset> request(const std::string& identifier);
|
||||
void unrequest(const std::string& identifier);
|
||||
|
||||
void setUpAssetLuaTable(Asset* asset);
|
||||
void tearDownAssetLuaTable(Asset* asset);
|
||||
|
||||
std::shared_ptr<Asset> getAsset(std::string name);
|
||||
std::shared_ptr<Asset> getAsset(const std::string& name);
|
||||
ghoul::filesystem::Directory currentDirectory() const;
|
||||
|
||||
void setCurrentAsset(std::shared_ptr<Asset> asset);
|
||||
void setCurrentAsset(Asset* asset);
|
||||
void addLuaDependencyTable(Asset* dependant, Asset* dependency);
|
||||
|
||||
// Lua functions
|
||||
@@ -195,7 +188,7 @@ private:
|
||||
int syncedResourceLua(Asset* asset);
|
||||
int exportAssetLua(Asset* asset);
|
||||
|
||||
// Friend c closures (callable from lua, and maps to lua functions above)
|
||||
// Friend C closures (callable from Lua, and maps to Lua functions above)
|
||||
friend int assetloader::onInitialize(lua_State* state);
|
||||
friend int assetloader::onDeinitialize(lua_State* state);
|
||||
friend int assetloader::onInitializeDependency(lua_State* state);
|
||||
@@ -209,7 +202,7 @@ private:
|
||||
|
||||
// Member variables
|
||||
std::shared_ptr<Asset> _rootAsset;
|
||||
std::shared_ptr<Asset> _currentAsset;
|
||||
Asset* _currentAsset = nullptr;
|
||||
std::unordered_map<std::string, std::weak_ptr<Asset>> _trackedAssets;
|
||||
SynchronizationWatcher* _synchronizationWatcher;
|
||||
std::string _assetRootDirectory;
|
||||
@@ -218,14 +211,14 @@ private:
|
||||
// State change listeners
|
||||
std::vector<AssetListener*> _assetListeners;
|
||||
|
||||
// References to lua values
|
||||
// References to Lua values
|
||||
std::unordered_map<Asset*, std::vector<int>> _onInitializationFunctionRefs;
|
||||
std::unordered_map<Asset*, std::vector<int>> _onDeinitializationFunctionRefs;
|
||||
std::unordered_map<Asset*, std::map<Asset*, std::vector<int>>>
|
||||
_onDependencyInitializationFunctionRefs;
|
||||
std::unordered_map<Asset*, std::map<Asset*, std::vector<int>>>
|
||||
_onDependencyDeinitializationFunctionRefs;
|
||||
int _assetsTableRef;
|
||||
int _assetsTableRef = 0;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -27,9 +27,12 @@
|
||||
|
||||
#include <openspace/scene/assetlistener.h>
|
||||
|
||||
#include <openspace/scene/assetloader.h>
|
||||
#include <ghoul/lua/ghoul_lua.h>
|
||||
#include <ghoul/lua/luastate.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -41,18 +44,14 @@ class SynchronizationWatcher;
|
||||
|
||||
/**
|
||||
* Interface for managing assets.
|
||||
* The asset manager interface is only concerned with "top level" assets,
|
||||
* i.e. assets that are loaded using setTargetAssetState, and not their dependencies.
|
||||
* However, an asset is not considered synchronized before all its deps are
|
||||
* synchronized.
|
||||
* Also, setting a target state of an asset to Unloaded will only unload an asset
|
||||
* from the system if it is not a dependency of a loaded asset.
|
||||
* The asset manager interface is only concerned with "top level" assets, and not their
|
||||
* dependencies. However, an asset is not considered synchronized before all its deps are
|
||||
* synchronized. Also, setting a target state of an asset to Unloaded will only unload an
|
||||
* asset from the system if it is not a dependency of a loaded asset.
|
||||
*/
|
||||
|
||||
class AssetManager : AssetListener {
|
||||
public:
|
||||
AssetManager(std::unique_ptr<AssetLoader> loader,
|
||||
std::unique_ptr<SynchronizationWatcher> syncWatcher);
|
||||
AssetManager(ghoul::lua::LuaState* state, std::string assetRootDirectory);
|
||||
|
||||
virtual ~AssetManager() = default;
|
||||
|
||||
@@ -61,13 +60,12 @@ public:
|
||||
void add(const std::string& path);
|
||||
void remove(const std::string& path);
|
||||
void removeAll();
|
||||
std::shared_ptr<Asset> rootAsset();
|
||||
const Asset& rootAsset() const;
|
||||
Asset& rootAsset();
|
||||
|
||||
void assetStateChanged(std::shared_ptr<Asset> asset, Asset::State state) override;
|
||||
void assetRequested(std::shared_ptr<Asset> parent,
|
||||
std::shared_ptr<Asset> child) override;
|
||||
void assetUnrequested(std::shared_ptr<Asset> parent,
|
||||
std::shared_ptr<Asset> child) override;
|
||||
void assetStateChanged(Asset* asset, Asset::State state) override;
|
||||
void assetRequested(Asset* parent, std::shared_ptr<Asset> child) override;
|
||||
void assetUnrequested(Asset* parent, std::shared_ptr<Asset> child) override;
|
||||
|
||||
bool update();
|
||||
scripting::LuaLibrary luaLibrary();
|
||||
@@ -77,8 +75,8 @@ private:
|
||||
std::mutex _pendingInitializationsMutex;
|
||||
std::vector<std::shared_ptr<Asset>> _pendingInitializations;
|
||||
|
||||
std::unique_ptr<SynchronizationWatcher> _synchronizationWatcher;
|
||||
std::unique_ptr<AssetLoader> _assetLoader;
|
||||
SynchronizationWatcher _synchronizationWatcher;
|
||||
AssetLoader _assetLoader;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scene/scenelicense.h>
|
||||
#include <ghoul/misc/easing.h>
|
||||
#include <ghoul/misc/exception.h>
|
||||
#include <mutex>
|
||||
@@ -134,8 +133,6 @@ public:
|
||||
*/
|
||||
void unregisterNode(SceneGraphNode* node);
|
||||
|
||||
void addSceneLicense(SceneLicense license);
|
||||
|
||||
/**
|
||||
* Mark the node registry as dirty
|
||||
*/
|
||||
@@ -146,14 +143,6 @@ public:
|
||||
*/
|
||||
const std::vector<SceneGraphNode*>& allSceneGraphNodes() const;
|
||||
|
||||
/**
|
||||
* Generate JSON about the license information for the scenegraph nodes that are
|
||||
* contained in this scene
|
||||
* \param path The file path that will contain the documentation about the licenses
|
||||
* used in this scene
|
||||
*/
|
||||
std::string generateSceneLicenseDocumentationJson();
|
||||
|
||||
/**
|
||||
* Returns a map from identifier to scene graph node.
|
||||
*/
|
||||
@@ -261,8 +250,6 @@ private:
|
||||
|
||||
std::vector<InterestingTime> _interestingTimes;
|
||||
|
||||
std::vector<SceneLicense> _licenses;
|
||||
|
||||
std::mutex _programUpdateLock;
|
||||
std::set<ghoul::opengl::ProgramObject*> _programsToUpdate;
|
||||
std::vector<std::unique_ptr<ghoul::opengl::ProgramObject>> _programs;
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2020 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_CORE___SCENELICENSE___H__
|
||||
#define __OPENSPACE_CORE___SCENELICENSE___H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ghoul { class Dictionary; }
|
||||
|
||||
namespace openspace {
|
||||
|
||||
namespace documentation { struct Documentation; }
|
||||
|
||||
struct SceneLicense {
|
||||
// module must not be empty
|
||||
SceneLicense(const ghoul::Dictionary& dictionary, std::string m);
|
||||
|
||||
std::string module;
|
||||
|
||||
std::string name;
|
||||
std::string attribution;
|
||||
std::string url;
|
||||
std::string licenseText;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
};
|
||||
|
||||
void writeSceneLicenseDocumentation(const std::vector<SceneLicense>& licenses,
|
||||
const std::string& file, const std::string& type);
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_CORE___SCENELICENSE___H__
|
||||
@@ -31,15 +31,10 @@
|
||||
|
||||
namespace openspace {
|
||||
|
||||
struct SceneLicense;
|
||||
|
||||
class SceneLicenseWriter : public DocumentationGenerator {
|
||||
public:
|
||||
SceneLicenseWriter(std::vector<SceneLicense> licenses);
|
||||
SceneLicenseWriter();
|
||||
std::string generateJson() const override;
|
||||
|
||||
private:
|
||||
const std::vector<SceneLicense>& _licenses;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -68,9 +68,9 @@ public:
|
||||
|
||||
State state() const;
|
||||
const std::string& name() const;
|
||||
bool isResolved();
|
||||
bool isRejected();
|
||||
bool isSyncing();
|
||||
bool isResolved() const;
|
||||
bool isRejected() const;
|
||||
bool isSyncing() const;
|
||||
CallbackHandle addStateChangeCallback(StateChangeCallback cb);
|
||||
void removeStateChangeCallback(CallbackHandle id);
|
||||
|
||||
|
||||
@@ -53,12 +53,6 @@ public:
|
||||
ResourceSynchronization::StateChangeCallback callback;
|
||||
};
|
||||
|
||||
/*using SyncStateChangeCallback =
|
||||
std::function<void(
|
||||
std::shared_ptr<ResourceSynchronization>,
|
||||
ResourceSynchronization::State
|
||||
)>;*/
|
||||
|
||||
WatchHandle watchSynchronization(
|
||||
std::shared_ptr<ResourceSynchronization> synchronization,
|
||||
ResourceSynchronization::StateChangeCallback callback
|
||||
@@ -69,7 +63,6 @@ public:
|
||||
void notify();
|
||||
|
||||
private:
|
||||
WatchHandle generateWatchHandle();
|
||||
std::mutex _mutex;
|
||||
std::unordered_map<WatchHandle, WatchData> _watchedSyncs;
|
||||
std::vector<NotificationData> _pendingNotifications;
|
||||
|
||||
@@ -39,14 +39,14 @@ namespace {
|
||||
using State = openspace::Asset::State;
|
||||
|
||||
switch (state) {
|
||||
case State::Loaded: return "Loaded";
|
||||
case State::LoadingFailed: return "LoadingFailed";
|
||||
case State::Synchronizing: return "Synchronizing";
|
||||
case State::SyncRejected: return "SyncRejected";
|
||||
case State::SyncResolved: return "SyncResolved";
|
||||
case State::Initialized: return "Initialized";
|
||||
case State::InitializationFailed: return "InitializationFailed";
|
||||
default: return "Unknown";
|
||||
case State::Loaded: return "Loaded";
|
||||
case State::LoadingFailed: return "LoadingFailed";
|
||||
case State::Synchronizing: return "Synchronizing";
|
||||
case State::SyncRejected: return "SyncRejected";
|
||||
case State::SyncResolved: return "SyncResolved";
|
||||
case State::Initialized: return "Initialized";
|
||||
case State::InitializationFailed: return "InitializationFailed";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,14 +54,14 @@ namespace {
|
||||
using State = openspace::ResourceSynchronization::State;
|
||||
|
||||
switch (state) {
|
||||
case State::Unsynced: return "Unsynced";
|
||||
case State::Syncing: return "Syncing";
|
||||
case State::Resolved: return "Resolved";
|
||||
case State::Rejected: return "Rejected";
|
||||
default: return "Unknown";
|
||||
case State::Unsynced: return "Unsynced";
|
||||
case State::Syncing: return "Syncing";
|
||||
case State::Resolved: return "Resolved";
|
||||
case State::Rejected: return "Rejected";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace openspace::gui {
|
||||
|
||||
@@ -69,7 +69,6 @@ GuiAssetComponent::GuiAssetComponent()
|
||||
: GuiComponent("Assets")
|
||||
{}
|
||||
|
||||
|
||||
void GuiAssetComponent::render() {
|
||||
bool e = _isEnabled;
|
||||
ImGui::Begin("Assets", &e);
|
||||
@@ -79,7 +78,7 @@ void GuiAssetComponent::render() {
|
||||
|
||||
std::string rootPath;
|
||||
|
||||
for (const std::shared_ptr<Asset>& a : assetManager.rootAsset()->childAssets()) {
|
||||
for (Asset* a : assetManager.rootAsset().childAssets()) {
|
||||
renderTree(*a, rootPath);
|
||||
}
|
||||
|
||||
@@ -104,29 +103,29 @@ void GuiAssetComponent::renderTree(const Asset& asset, const std::string& relati
|
||||
assetText += " (" + std::to_string(prog) + "%)";
|
||||
}
|
||||
|
||||
const std::vector<std::shared_ptr<Asset>>& requested = asset.requestedAssets();
|
||||
const std::vector<std::shared_ptr<Asset>>& required = asset.requiredAssets();
|
||||
std::vector<Asset*> requested = asset.requestedAssets();
|
||||
std::vector<Asset*> required = asset.requiredAssets();
|
||||
|
||||
const std::vector<std::shared_ptr<ResourceSynchronization>>& resourceSyncs =
|
||||
const std::vector<ResourceSynchronization*>& resourceSyncs =
|
||||
asset.ownSynchronizations();
|
||||
|
||||
if (requested.empty() && required.empty() && resourceSyncs.empty()) {
|
||||
ImGui::Text("%s", assetText.c_str());
|
||||
}
|
||||
else if (ImGui::TreeNode(assetPath.c_str(), "%s", assetText.c_str())) {
|
||||
for (const std::shared_ptr<Asset>& child : required) {
|
||||
for (const Asset* child : required) {
|
||||
renderTree(*child, assetDirectory);
|
||||
}
|
||||
|
||||
if (!requested.empty() && ImGui::TreeNode("Requested assets")) {
|
||||
for (const std::shared_ptr<Asset>& child : requested) {
|
||||
for (const Asset* child : requested) {
|
||||
renderTree(*child, assetDirectory);
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
if (!resourceSyncs.empty() && ImGui::TreeNode("Resource Synchronizations")) {
|
||||
for (const std::shared_ptr<ResourceSynchronization>& sync : resourceSyncs) {
|
||||
for (ResourceSynchronization* sync : resourceSyncs) {
|
||||
std::string resourceText = sync->directory() +
|
||||
" " + syncStateToString(sync->state());
|
||||
if (sync->state() == ResourceSynchronization::State::Syncing) {
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/scene/assetlistener.h>
|
||||
#include <openspace/scene/assetloader.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/util/openspacemodule.h>
|
||||
@@ -74,21 +73,6 @@ documentation::Documentation SyncAssetTask::documentation() {
|
||||
};
|
||||
}
|
||||
|
||||
class RequestListener : public AssetListener {
|
||||
public:
|
||||
virtual ~RequestListener() = default;
|
||||
void assetStateChanged(std::shared_ptr<Asset> asset, Asset::State state) override {
|
||||
if (state == Asset::State::LoadingFailed) {
|
||||
LERROR(fmt::format("Failed to load asset: {}", asset->id()));
|
||||
}
|
||||
if (state == Asset::State::SyncRejected) {
|
||||
LERROR(fmt::format("Failed to sync asset: {}", asset->id()));
|
||||
}
|
||||
}
|
||||
void assetRequested(std::shared_ptr<Asset>, std::shared_ptr<Asset>) override {};
|
||||
void assetUnrequested(std::shared_ptr<Asset>, std::shared_ptr<Asset>) override {};
|
||||
};
|
||||
|
||||
SyncAssetTask::SyncAssetTask(const ghoul::Dictionary& dictionary) {
|
||||
documentation::testSpecificationAndThrow(
|
||||
documentation(),
|
||||
@@ -125,18 +109,14 @@ void SyncAssetTask::perform(const Task::ProgressCallback& progressCallback) {
|
||||
|
||||
AssetLoader loader(&luaState, &watcher, "${ASSETS}");
|
||||
|
||||
RequestListener listener;
|
||||
loader.addAssetListener(&listener);
|
||||
|
||||
loader.add(_asset);
|
||||
loader.rootAsset()->startSynchronizations();
|
||||
loader.rootAsset().startSynchronizations();
|
||||
|
||||
std::vector<std::shared_ptr<const Asset>> allAssets =
|
||||
loader.rootAsset()->subTreeAssets();
|
||||
std::vector<const Asset*> allAssets = loader.rootAsset().subTreeAssets();
|
||||
|
||||
while (true) {
|
||||
bool inProgress = false;
|
||||
for (const std::shared_ptr<const Asset>& asset : allAssets) {
|
||||
for (const Asset* asset : allAssets) {
|
||||
Asset::State state = asset->state();
|
||||
if (state == Asset::State::Unloaded ||
|
||||
state == Asset::State::Loaded ||
|
||||
@@ -145,7 +125,7 @@ void SyncAssetTask::perform(const Task::ProgressCallback& progressCallback) {
|
||||
inProgress = true;
|
||||
}
|
||||
}
|
||||
progressCallback(loader.rootAsset()->requestedSynchronizationProgress());
|
||||
progressCallback(loader.rootAsset().requestedSynchronizationProgress());
|
||||
std::this_thread::sleep_for(ProgressPollInterval);
|
||||
watcher.notify();
|
||||
if (!inProgress) {
|
||||
|
||||
@@ -157,7 +157,6 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/scene/scene.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/scene/scene_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/scene/sceneinitializer.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/scene/scenelicense.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/scene/scenelicensewriter.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/scene/scenegraphnode.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/scene/scenegraphnode_doc.inl
|
||||
@@ -346,7 +345,6 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/scale.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/scene.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/sceneinitializer.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/scenelicense.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/scenelicensewriter.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/scenegraphnode.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/timeframe.h
|
||||
|
||||
@@ -341,17 +341,9 @@ void OpenSpaceEngine::initialize() {
|
||||
}
|
||||
|
||||
// Set up asset loader
|
||||
std::unique_ptr<SynchronizationWatcher> w =
|
||||
std::make_unique<SynchronizationWatcher>();
|
||||
SynchronizationWatcher* rawWatcher = w.get();
|
||||
|
||||
global::openSpaceEngine._assetManager = std::make_unique<AssetManager>(
|
||||
std::make_unique<AssetLoader>(
|
||||
global::scriptEngine.luaState(),
|
||||
rawWatcher,
|
||||
FileSys.absPath("${ASSETS}")
|
||||
),
|
||||
std::move(w)
|
||||
global::scriptEngine.luaState(),
|
||||
FileSys.absPath("${ASSETS}")
|
||||
);
|
||||
|
||||
global::scriptEngine.addLibrary(global::openSpaceEngine._assetManager->luaLibrary());
|
||||
@@ -754,15 +746,13 @@ void OpenSpaceEngine::loadSingleAsset(const std::string& assetPath) {
|
||||
_loadingScreen->setPhase(LoadingScreen::Phase::Synchronization);
|
||||
_loadingScreen->postMessage("Synchronizing assets");
|
||||
|
||||
std::vector<std::shared_ptr<const Asset>> allAssets =
|
||||
_assetManager->rootAsset()->subTreeAssets();
|
||||
std::vector<const Asset*> allAssets = _assetManager->rootAsset().subTreeAssets();
|
||||
|
||||
std::unordered_set<std::shared_ptr<ResourceSynchronization>> resourceSyncs;
|
||||
for (const std::shared_ptr<const Asset>& a : allAssets) {
|
||||
std::vector<std::shared_ptr<ResourceSynchronization>> syncs =
|
||||
a->ownSynchronizations();
|
||||
std::unordered_set<ResourceSynchronization*> resourceSyncs;
|
||||
for (const Asset* a : allAssets) {
|
||||
std::vector<ResourceSynchronization*> syncs = a->ownSynchronizations();
|
||||
|
||||
for (const std::shared_ptr<ResourceSynchronization>& s : syncs) {
|
||||
for (ResourceSynchronization* s : syncs) {
|
||||
ZoneScopedN("Update resource synchronization")
|
||||
|
||||
if (s->state() == ResourceSynchronization::State::Syncing) {
|
||||
@@ -1030,7 +1020,7 @@ void OpenSpaceEngine::writeSceneDocumentation() {
|
||||
_documentationJson += "{\"name\":\"Scene License Information\",";
|
||||
_documentationJson += "\"identifier\":\"sceneLicense";
|
||||
_documentationJson += "\",\"data\":";
|
||||
_documentationJson += _scene->generateSceneLicenseDocumentationJson();
|
||||
_documentationJson += SceneLicenseWriter().generateJson();
|
||||
_documentationJson += "},";
|
||||
_documentationJson += "{\"name\":\"Scene Properties\",";
|
||||
_documentationJson += "\"identifier\":\"propertylist";// + _scene->jsonName();
|
||||
@@ -1045,8 +1035,7 @@ void OpenSpaceEngine::writeSceneDocumentation() {
|
||||
DocEng.addHandlebarTemplates(global::keybindingManager.templatesToRegister());
|
||||
//TODO this is in efficaiant, here i am just instaning the class to get
|
||||
//at a member variable which is staticly defined. How do i just get that
|
||||
const std::vector<SceneLicense> licenses;
|
||||
SceneLicenseWriter writer(licenses);
|
||||
SceneLicenseWriter writer;
|
||||
DocEng.addHandlebarTemplates(writer.templatesToRegister());
|
||||
DocEng.addHandlebarTemplates(global::rootPropertyOwner.templatesToRegister());
|
||||
|
||||
|
||||
@@ -33,19 +33,19 @@
|
||||
#include <algorithm>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace {
|
||||
const constexpr char* _loggerCat = "Asset";
|
||||
namespace openspace {
|
||||
|
||||
float syncProgress(const std::vector<std::shared_ptr<const openspace::Asset>>& assets)
|
||||
{
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "Asset";
|
||||
|
||||
float syncProgress(const std::vector<const Asset*>& assets) {
|
||||
size_t nTotalBytes = 0;
|
||||
size_t nSyncedBytes = 0;
|
||||
|
||||
for (const std::shared_ptr<const openspace::Asset>& a : assets) {
|
||||
const std::vector<std::shared_ptr<openspace::ResourceSynchronization>>& s =
|
||||
a->ownSynchronizations();
|
||||
for (const Asset* a : assets) {
|
||||
std::vector<ResourceSynchronization*> s = a->ownSynchronizations();
|
||||
|
||||
for (const std::shared_ptr<openspace::ResourceSynchronization>& sync : s) {
|
||||
for (ResourceSynchronization* sync : s) {
|
||||
if (sync->nTotalBytesIsKnown()) {
|
||||
nTotalBytes += sync->nTotalBytes();
|
||||
nSyncedBytes += sync->nSynchronizedBytes();
|
||||
@@ -62,9 +62,8 @@ namespace {
|
||||
}
|
||||
return static_cast<float>(nSyncedBytes) / static_cast<float>(nTotalBytes);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
Asset::Asset(AssetLoader* loader, SynchronizationWatcher* watcher)
|
||||
: _state(State::SyncResolved)
|
||||
@@ -74,9 +73,7 @@ Asset::Asset(AssetLoader* loader, SynchronizationWatcher* watcher)
|
||||
, _assetName("Root Asset")
|
||||
{}
|
||||
|
||||
Asset::Asset(AssetLoader* loader, SynchronizationWatcher* watcher,
|
||||
std::string assetPath
|
||||
)
|
||||
Asset::Asset(AssetLoader* loader, SynchronizationWatcher* watcher, std::string assetPath)
|
||||
: _state(State::Unloaded)
|
||||
, _loader(loader)
|
||||
, _synchronizationWatcher(watcher)
|
||||
@@ -84,10 +81,12 @@ Asset::Asset(AssetLoader* loader, SynchronizationWatcher* watcher,
|
||||
, _assetPath(std::move(assetPath))
|
||||
{}
|
||||
|
||||
std::string Asset::resolveLocalResource(std::string resourceName) {
|
||||
std::string assetDir = assetDirectory();
|
||||
return assetDir + ghoul::filesystem::FileSystem::PathSeparator +
|
||||
std::move(resourceName);
|
||||
void Asset::setMetaInformation(MetaInformation metaInformation) {
|
||||
_metaInformation = std::move(metaInformation);
|
||||
}
|
||||
|
||||
std::optional<Asset::MetaInformation> Asset::metaInformation() const {
|
||||
return _metaInformation;
|
||||
}
|
||||
|
||||
Asset::State Asset::state() const {
|
||||
@@ -108,8 +107,7 @@ void Asset::setState(Asset::State state) {
|
||||
}
|
||||
_state = state;
|
||||
|
||||
std::shared_ptr<Asset> thisAsset = shared_from_this();
|
||||
_loader->assetStateChanged(thisAsset, state);
|
||||
_loader->assetStateChanged(this, state);
|
||||
|
||||
for (const std::weak_ptr<Asset>& requiringAsset : _requiringAssets) {
|
||||
if (std::shared_ptr<Asset> a = requiringAsset.lock()) {
|
||||
@@ -127,18 +125,17 @@ void Asset::setState(Asset::State state) {
|
||||
void Asset::requiredAssetChangedState(Asset::State childState) {
|
||||
if (!isLoaded()) {
|
||||
// Prohibit state change to SyncResolved if additional requirements
|
||||
// may still be added.
|
||||
// may still be added
|
||||
return;
|
||||
}
|
||||
if (isInitialized()) {
|
||||
// Do not do anything if this asset was already initialized.
|
||||
// This may happen if there are multiple requirement paths from
|
||||
// this asset to the same child, which causes this method to be
|
||||
// called more than once.
|
||||
// Do not do anything if this asset was already initialized. This may happen if
|
||||
// there are multiple requirement paths from this asset to the same child, which
|
||||
// causes this method to be called more than once
|
||||
return;
|
||||
}
|
||||
if (state() == State::InitializationFailed) {
|
||||
// Do not do anything if the asset failed to initialize.
|
||||
if (_state == State::InitializationFailed) {
|
||||
// Do not do anything if the asset failed to initialize
|
||||
return;
|
||||
}
|
||||
if (childState == State::SyncResolved) {
|
||||
@@ -153,21 +150,19 @@ void Asset::requiredAssetChangedState(Asset::State childState) {
|
||||
|
||||
void Asset::requestedAssetChangedState(Asset* child, Asset::State childState) {
|
||||
if (child->hasInitializedParent()) {
|
||||
if (childState == State::Loaded &&
|
||||
child->state() == State::Loaded)
|
||||
{
|
||||
if (childState == State::Loaded && child->state() == State::Loaded) {
|
||||
child->startSynchronizations();
|
||||
}
|
||||
if (childState == State::SyncResolved &&
|
||||
child->state() == State::SyncResolved)
|
||||
{
|
||||
if (childState == State::SyncResolved && child->state() == State::SyncResolved) {
|
||||
child->initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Asset::addSynchronization(std::shared_ptr<ResourceSynchronization> synchronization) {
|
||||
_synchronizations.push_back(synchronization);
|
||||
void Asset::addSynchronization(std::unique_ptr<ResourceSynchronization> synchronization) {
|
||||
std::shared_ptr<ResourceSynchronization> sync = std::move(synchronization);
|
||||
|
||||
_synchronizations.push_back(sync);
|
||||
|
||||
// Set up callback for synchronization state change
|
||||
// The synchronization watcher will make sure that callbacks
|
||||
@@ -175,9 +170,9 @@ void Asset::addSynchronization(std::shared_ptr<ResourceSynchronization> synchron
|
||||
|
||||
SynchronizationWatcher::WatchHandle watch =
|
||||
_synchronizationWatcher->watchSynchronization(
|
||||
synchronization,
|
||||
[this, synchronization](ResourceSynchronization::State state) {
|
||||
syncStateChanged(synchronization.get(), state);
|
||||
sync,
|
||||
[this, sync](ResourceSynchronization::State state) {
|
||||
syncStateChanged(sync.get(), state);
|
||||
}
|
||||
);
|
||||
_syncWatches.push_back(watch);
|
||||
@@ -201,7 +196,7 @@ void Asset::syncStateChanged(ResourceSynchronization* sync,
|
||||
}
|
||||
else if (state == ResourceSynchronization::State::Rejected) {
|
||||
LERROR(fmt::format(
|
||||
"Failed to synchronize resource '{}'' in asset '{}'", sync->name(), id()
|
||||
"Failed to synchronize resource '{}' in asset '{}'", sync->name(), id()
|
||||
));
|
||||
|
||||
setState(State::SyncRejected);
|
||||
@@ -209,93 +204,84 @@ void Asset::syncStateChanged(ResourceSynchronization* sync,
|
||||
}
|
||||
|
||||
bool Asset::isSyncResolveReady() {
|
||||
std::vector<std::shared_ptr<Asset>> requiredAssets = this->requiredAssets();
|
||||
std::vector<Asset*> requiredAssets = this->requiredAssets();
|
||||
|
||||
auto unsynchronizedAsset = std::find_if(
|
||||
requiredAssets.begin(),
|
||||
requiredAssets.end(),
|
||||
[](std::shared_ptr<Asset>& a) {
|
||||
return !a->isSynchronized();
|
||||
}
|
||||
const auto unsynchronizedAsset = std::find_if(
|
||||
requiredAssets.cbegin(),
|
||||
requiredAssets.cend(),
|
||||
[](Asset* a) { return !a->isSynchronized(); }
|
||||
);
|
||||
|
||||
if (unsynchronizedAsset != requiredAssets.end()) {
|
||||
if (unsynchronizedAsset != requiredAssets.cend()) {
|
||||
// Not considered resolved if there is one or more unresolved children
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::vector<std::shared_ptr<ResourceSynchronization>>& syncs =
|
||||
ownSynchronizations();
|
||||
|
||||
auto unresolvedOwnSynchronization = std::find_if(
|
||||
syncs.begin(),
|
||||
syncs.end(),
|
||||
[](const std::shared_ptr<ResourceSynchronization>& s) {
|
||||
return !s->isResolved();
|
||||
}
|
||||
const auto unresolvedOwnSynchronization = std::find_if(
|
||||
_synchronizations.cbegin(),
|
||||
_synchronizations.cend(),
|
||||
[](const std::shared_ptr<ResourceSynchronization>& s) { return !s->isResolved(); }
|
||||
);
|
||||
|
||||
// To be considered resolved, all own synchronizations need to be resolved
|
||||
return unresolvedOwnSynchronization == syncs.end();
|
||||
return unresolvedOwnSynchronization == _synchronizations.cend();
|
||||
}
|
||||
|
||||
const std::vector<std::shared_ptr<ResourceSynchronization>>&
|
||||
Asset::ownSynchronizations() const
|
||||
{
|
||||
return _synchronizations;
|
||||
std::vector<ResourceSynchronization*> Asset::ownSynchronizations() const {
|
||||
std::vector<ResourceSynchronization*> res;
|
||||
res.reserve(_synchronizations.size());
|
||||
std::transform(
|
||||
_synchronizations.begin(), _synchronizations.end(),
|
||||
std::back_inserter(res),
|
||||
std::mem_fn(&std::shared_ptr<ResourceSynchronization>::get)
|
||||
);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<const Asset>> Asset::subTreeAssets() const {
|
||||
std::unordered_set<std::shared_ptr<const Asset>> assets({ shared_from_this() });
|
||||
for (const std::shared_ptr<Asset>& c : childAssets()) {
|
||||
if (c.get() == this) {
|
||||
std::vector<const Asset*> Asset::subTreeAssets() const {
|
||||
std::unordered_set<const Asset*> assets({ this });
|
||||
for (Asset* c : childAssets()) {
|
||||
if (c == this) {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
"Detected cycle in asset inclusion for {} at {}", _assetName, _assetPath
|
||||
));
|
||||
}
|
||||
|
||||
const std::vector<std::shared_ptr<const Asset>>& subTree = c->subTreeAssets();
|
||||
std::vector<const Asset*> subTree = c->subTreeAssets();
|
||||
std::copy(subTree.begin(), subTree.end(), std::inserter(assets, assets.end()));
|
||||
}
|
||||
std::vector<std::shared_ptr<const Asset>> assetVector(assets.begin(), assets.end());
|
||||
std::vector<const Asset*> assetVector(assets.begin(), assets.end());
|
||||
return assetVector;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<const Asset>> Asset::requiredSubTreeAssets() const {
|
||||
std::unordered_set<std::shared_ptr<const Asset>> assets({ shared_from_this() });
|
||||
std::vector<const Asset*> Asset::requiredSubTreeAssets() const {
|
||||
std::unordered_set<const Asset*> assets({ this });
|
||||
for (const std::shared_ptr<Asset>& dep : _requiredAssets) {
|
||||
const std::vector<std::shared_ptr<const Asset>>& subTree =
|
||||
dep->requiredSubTreeAssets();
|
||||
|
||||
std::vector<const Asset*> subTree = dep->requiredSubTreeAssets();
|
||||
std::copy(subTree.begin(), subTree.end(), std::inserter(assets, assets.end()));
|
||||
}
|
||||
std::vector<std::shared_ptr<const Asset>> assetVector(assets.begin(), assets.end());
|
||||
std::vector<const Asset*> assetVector(assets.begin(), assets.end());
|
||||
return assetVector;
|
||||
}
|
||||
|
||||
bool Asset::isLoaded() const {
|
||||
State s = state();
|
||||
return s != State::Unloaded && s != State::LoadingFailed;
|
||||
return _state != State::Unloaded && _state != State::LoadingFailed;
|
||||
}
|
||||
|
||||
bool Asset::isSynchronized() const {
|
||||
State s = state();
|
||||
return s == State::SyncResolved ||
|
||||
s == State::Initialized ||
|
||||
s == State::InitializationFailed;
|
||||
return _state == State::SyncResolved || _state == State::Initialized ||
|
||||
_state == State::InitializationFailed;
|
||||
}
|
||||
|
||||
bool Asset::isSyncingOrResolved() const {
|
||||
State s = state();
|
||||
return s == State::Synchronizing ||
|
||||
s == State::SyncResolved ||
|
||||
s == State::Initialized ||
|
||||
s == State::InitializationFailed;
|
||||
return _state == State::Synchronizing || _state == State::SyncResolved ||
|
||||
_state == State::Initialized || _state == State::InitializationFailed;
|
||||
}
|
||||
|
||||
bool Asset::hasLoadedParent() {
|
||||
{
|
||||
std::vector<std::weak_ptr<Asset>>::iterator it = _requiringAssets.begin();
|
||||
auto it = _requiringAssets.begin();
|
||||
while (it != _requiringAssets.end()) {
|
||||
std::shared_ptr<Asset> parent = it->lock();
|
||||
if (!parent) {
|
||||
@@ -309,7 +295,7 @@ bool Asset::hasLoadedParent() {
|
||||
}
|
||||
}
|
||||
{
|
||||
std::vector<std::weak_ptr<Asset>>::iterator it = _requestingAssets.begin();
|
||||
auto it = _requestingAssets.begin();
|
||||
while (it != _requestingAssets.end()) {
|
||||
std::shared_ptr<Asset> parent = it->lock();
|
||||
if (!parent) {
|
||||
@@ -371,8 +357,7 @@ bool Asset::hasInitializedParent() const {
|
||||
}
|
||||
|
||||
bool Asset::isInitialized() const {
|
||||
State s = state();
|
||||
return s == State::Initialized;
|
||||
return _state == State::Initialized;
|
||||
}
|
||||
|
||||
bool Asset::startSynchronizations() {
|
||||
@@ -380,33 +365,33 @@ bool Asset::startSynchronizations() {
|
||||
LWARNING(fmt::format("Cannot start synchronizations of unloaded asset {}", id()));
|
||||
return false;
|
||||
}
|
||||
for (const std::shared_ptr<Asset>& child : requestedAssets()) {
|
||||
for (Asset* child : requestedAssets()) {
|
||||
child->startSynchronizations();
|
||||
}
|
||||
|
||||
// Do not attempt to resync if this is already done
|
||||
if (isSyncingOrResolved()) {
|
||||
return state() != State::SyncResolved;
|
||||
return _state != State::SyncResolved;
|
||||
}
|
||||
|
||||
setState(State::Synchronizing);
|
||||
|
||||
bool childFailed = false;
|
||||
|
||||
// Start synchronization of all children first.
|
||||
for (const std::shared_ptr<Asset>& child : requiredAssets()) {
|
||||
// Start synchronization of all children first
|
||||
for (Asset* child : requiredAssets()) {
|
||||
if (!child->startSynchronizations()) {
|
||||
childFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Now synchronize its own synchronizations.
|
||||
for (const std::shared_ptr<ResourceSynchronization>& s : ownSynchronizations()) {
|
||||
// Now synchronize its own synchronizations
|
||||
for (const std::shared_ptr<ResourceSynchronization>& s : _synchronizations) {
|
||||
if (!s->isResolved()) {
|
||||
s->start();
|
||||
}
|
||||
}
|
||||
// If all syncs are resolved (or no syncs exist), mark as resolved.
|
||||
// If all syncs are resolved (or no syncs exist), mark as resolved
|
||||
if (!isInitialized() && isSyncResolveReady()) {
|
||||
setState(State::SyncResolved);
|
||||
}
|
||||
@@ -414,14 +399,14 @@ bool Asset::startSynchronizations() {
|
||||
}
|
||||
|
||||
bool Asset::cancelAllSynchronizations() {
|
||||
bool cancelledAnySync = false;
|
||||
for (const std::shared_ptr<Asset>& child : childAssets()) {
|
||||
const bool cancelled = child->cancelAllSynchronizations();
|
||||
if (cancelled) {
|
||||
cancelledAnySync = true;
|
||||
}
|
||||
}
|
||||
for (const std::shared_ptr<ResourceSynchronization>& s : ownSynchronizations()) {
|
||||
std::vector<Asset*> children = childAssets();
|
||||
bool cancelledAnySync = std::any_of(
|
||||
children.cbegin(),
|
||||
children.cend(),
|
||||
std::mem_fn(&Asset::cancelAllSynchronizations)
|
||||
);
|
||||
|
||||
for (const std::shared_ptr<ResourceSynchronization>& s : _synchronizations) {
|
||||
if (s->isSyncing()) {
|
||||
cancelledAnySync = true;
|
||||
s->cancel();
|
||||
@@ -438,14 +423,15 @@ bool Asset::cancelUnwantedSynchronizations() {
|
||||
if (hasSyncingOrResolvedParent()) {
|
||||
return false;
|
||||
}
|
||||
bool cancelledAnySync = false;
|
||||
for (const std::shared_ptr<Asset>& child : childAssets()) {
|
||||
bool cancelled = child->cancelUnwantedSynchronizations();
|
||||
if (cancelled) {
|
||||
cancelledAnySync = true;
|
||||
}
|
||||
}
|
||||
for (const std::shared_ptr<ResourceSynchronization>& s : ownSynchronizations()) {
|
||||
|
||||
const std::vector<Asset*>& children = childAssets();
|
||||
bool cancelledAnySync = std::any_of(
|
||||
children.begin(),
|
||||
children.end(),
|
||||
std::mem_fn(&Asset::cancelUnwantedSynchronizations)
|
||||
);
|
||||
|
||||
for (const std::shared_ptr<ResourceSynchronization>& s : _synchronizations) {
|
||||
if (s->isSyncing()) {
|
||||
cancelledAnySync = true;
|
||||
s->cancel();
|
||||
@@ -458,18 +444,13 @@ bool Asset::cancelUnwantedSynchronizations() {
|
||||
return cancelledAnySync;
|
||||
}
|
||||
|
||||
bool Asset::restartAllSynchronizations() {
|
||||
cancelAllSynchronizations();
|
||||
return startSynchronizations();
|
||||
}
|
||||
|
||||
float Asset::requiredSynchronizationProgress() const {
|
||||
const std::vector<std::shared_ptr<const Asset>>& assets = requiredSubTreeAssets();
|
||||
std::vector<const Asset*> assets = requiredSubTreeAssets();
|
||||
return syncProgress(assets);
|
||||
}
|
||||
|
||||
float Asset::requestedSynchronizationProgress() {
|
||||
const std::vector<std::shared_ptr<const Asset>>& assets = subTreeAssets();
|
||||
std::vector<const Asset*> assets = subTreeAssets();
|
||||
return syncProgress(assets);
|
||||
}
|
||||
|
||||
@@ -478,7 +459,7 @@ bool Asset::load() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool loaded = loader()->loadAsset(shared_from_this());
|
||||
const bool loaded = loader()->loadAsset(this);
|
||||
setState(loaded ? State::Loaded : State::LoadingFailed);
|
||||
return loaded;
|
||||
}
|
||||
@@ -491,11 +472,11 @@ void Asset::unload() {
|
||||
setState(State::Unloaded);
|
||||
loader()->unloadAsset(this);
|
||||
|
||||
for (const std::shared_ptr<Asset>& child : requiredAssets()) {
|
||||
unrequire(child.get());
|
||||
for (Asset* child : requiredAssets()) {
|
||||
unrequire(child);
|
||||
}
|
||||
for (const std::shared_ptr<Asset>& child : requestedAssets()) {
|
||||
unrequest(child.get());
|
||||
for (Asset* child : requestedAssets()) {
|
||||
unrequest(child);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,12 +518,12 @@ bool Asset::initialize() {
|
||||
"Failed to initialize asset {}; {}: {}", id(), e.component, e.message
|
||||
));
|
||||
// TODO: rollback;
|
||||
setState(Asset::State::InitializationFailed);
|
||||
setState(State::InitializationFailed);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 4. Update state
|
||||
setState(Asset::State::Initialized);
|
||||
setState(State::Initialized);
|
||||
|
||||
// 5. Call dependency lua onInitialize of this and requirements
|
||||
for (const std::shared_ptr<Asset>& child : _requiredAssets) {
|
||||
@@ -552,13 +533,10 @@ bool Asset::initialize() {
|
||||
catch (const ghoul::lua::LuaRuntimeException& e) {
|
||||
LERROR(fmt::format(
|
||||
"Failed to initialize required asset {} of {}; {}: {}",
|
||||
child->id(),
|
||||
id(),
|
||||
e.component,
|
||||
e.message
|
||||
child->id(), id(), e.component, e.message
|
||||
));
|
||||
// TODO: rollback;
|
||||
setState(Asset::State::InitializationFailed);
|
||||
setState(State::InitializationFailed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -572,10 +550,7 @@ bool Asset::initialize() {
|
||||
catch (const ghoul::lua::LuaRuntimeException& e) {
|
||||
LERROR(fmt::format(
|
||||
"Failed to initialize requested asset {} of {}; {}: {}",
|
||||
child->id(),
|
||||
id(),
|
||||
e.component,
|
||||
e.message
|
||||
child->id(), id(), e.component, e.message
|
||||
));
|
||||
// TODO: rollback;
|
||||
}
|
||||
@@ -592,10 +567,7 @@ bool Asset::initialize() {
|
||||
catch (const ghoul::lua::LuaRuntimeException& e) {
|
||||
LERROR(fmt::format(
|
||||
"Failed to initialize required asset {} of {}; {}: {}",
|
||||
id(),
|
||||
p->id(),
|
||||
e.component,
|
||||
e.message
|
||||
id(), p->id(), e.component, e.message
|
||||
));
|
||||
// TODO: rollback;
|
||||
}
|
||||
@@ -678,7 +650,7 @@ void Asset::deinitialize() {
|
||||
}
|
||||
|
||||
// 2 and 1. Deinitialize unwanted requirements and requests
|
||||
for (const std::shared_ptr<Asset>& dependency : childAssets()) {
|
||||
for (Asset* dependency : childAssets()) {
|
||||
dependency->deinitializeIfUnwanted();
|
||||
}
|
||||
}
|
||||
@@ -709,13 +681,11 @@ AssetLoader* Asset::loader() const {
|
||||
|
||||
bool Asset::requires(const Asset* asset) const {
|
||||
const auto it = std::find_if(
|
||||
_requiredAssets.begin(),
|
||||
_requiredAssets.end(),
|
||||
[asset](std::shared_ptr<Asset> dep) {
|
||||
return dep.get() == asset;
|
||||
}
|
||||
_requiredAssets.cbegin(),
|
||||
_requiredAssets.cend(),
|
||||
[asset](const std::shared_ptr<Asset> dep) { return dep.get() == asset; }
|
||||
);
|
||||
return it != _requiredAssets.end();
|
||||
return it != _requiredAssets.cend();
|
||||
}
|
||||
|
||||
void Asset::require(std::shared_ptr<Asset> child) {
|
||||
@@ -723,12 +693,12 @@ void Asset::require(std::shared_ptr<Asset> child) {
|
||||
throw ghoul::RuntimeError("Cannot require child asset when already loaded");
|
||||
}
|
||||
|
||||
const auto it = std::find(_requiredAssets.begin(), _requiredAssets.end(), child);
|
||||
|
||||
if (it != _requiredAssets.end()) {
|
||||
const auto it = std::find(_requiredAssets.cbegin(), _requiredAssets.cend(), child);
|
||||
if (it != _requiredAssets.cend()) {
|
||||
// Do nothing if the requirement already exists.
|
||||
return;
|
||||
}
|
||||
|
||||
_requiredAssets.push_back(child);
|
||||
child->_requiringAssets.push_back(shared_from_this());
|
||||
|
||||
@@ -761,12 +731,12 @@ void Asset::unrequire(Asset* child) {
|
||||
}
|
||||
|
||||
const auto childIt = std::find_if(
|
||||
_requiredAssets.begin(),
|
||||
_requiredAssets.end(),
|
||||
_requiredAssets.cbegin(),
|
||||
_requiredAssets.cend(),
|
||||
[child](const std::shared_ptr<Asset>& asset) { return asset.get() == child; }
|
||||
);
|
||||
|
||||
if (childIt == _requiredAssets.end()) {
|
||||
if (childIt == _requiredAssets.cend()) {
|
||||
// Do nothing if the request node not exist.
|
||||
return;
|
||||
}
|
||||
@@ -774,14 +744,11 @@ void Asset::unrequire(Asset* child) {
|
||||
_requiredAssets.erase(childIt);
|
||||
|
||||
const auto parentIt = std::find_if(
|
||||
child->_requiringAssets.begin(),
|
||||
child->_requiringAssets.end(),
|
||||
[this](std::weak_ptr<Asset> a) {
|
||||
return a.lock().get() == this;
|
||||
}
|
||||
child->_requiringAssets.cbegin(),
|
||||
child->_requiringAssets.cend(),
|
||||
[this](const std::weak_ptr<Asset> a) { return a.lock().get() == this; }
|
||||
);
|
||||
|
||||
if (parentIt == child->_requiringAssets.end()) {
|
||||
if (parentIt == child->_requiringAssets.cend()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -793,12 +760,12 @@ void Asset::unrequire(Asset* child) {
|
||||
}
|
||||
|
||||
void Asset::request(std::shared_ptr<Asset> child) {
|
||||
const auto it = std::find(_requestedAssets.begin(), _requestedAssets.end(), child);
|
||||
|
||||
if (it != _requestedAssets.end()) {
|
||||
const auto it = std::find(_requestedAssets.cbegin(), _requestedAssets.cend(), child);
|
||||
if (it != _requestedAssets.cend()) {
|
||||
// Do nothing if the request already exists.
|
||||
return;
|
||||
}
|
||||
|
||||
_requestedAssets.push_back(child);
|
||||
child->_requestingAssets.push_back(shared_from_this());
|
||||
|
||||
@@ -817,12 +784,11 @@ void Asset::request(std::shared_ptr<Asset> child) {
|
||||
|
||||
void Asset::unrequest(Asset* child) {
|
||||
const auto childIt = std::find_if(
|
||||
_requestedAssets.begin(),
|
||||
_requestedAssets.end(),
|
||||
_requestedAssets.cbegin(),
|
||||
_requestedAssets.cend(),
|
||||
[child](const std::shared_ptr<Asset>& asset) { return asset.get() == child; }
|
||||
);
|
||||
|
||||
if (childIt == _requestedAssets.end()) {
|
||||
if (childIt == _requestedAssets.cend()) {
|
||||
// Do nothing if the request node not exist.
|
||||
return;
|
||||
}
|
||||
@@ -830,14 +796,11 @@ void Asset::unrequest(Asset* child) {
|
||||
_requestedAssets.erase(childIt);
|
||||
|
||||
const auto parentIt = std::find_if(
|
||||
child->_requestingAssets.begin(),
|
||||
child->_requestingAssets.end(),
|
||||
[this](std::weak_ptr<Asset> a) {
|
||||
return a.lock().get() == this;
|
||||
}
|
||||
child->_requestingAssets.cbegin(),
|
||||
child->_requestingAssets.cend(),
|
||||
[this](const std::weak_ptr<Asset> a) { return a.lock().get() == this; }
|
||||
);
|
||||
|
||||
if (parentIt == child->_requestingAssets.end()) {
|
||||
if (parentIt == child->_requestingAssets.cend()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -850,83 +813,64 @@ void Asset::unrequest(Asset* child) {
|
||||
|
||||
bool Asset::requests(Asset* asset) const {
|
||||
const auto it = std::find_if(
|
||||
_requestedAssets.begin(),
|
||||
_requestedAssets.end(),
|
||||
[asset](const std::shared_ptr<Asset>& dep) {
|
||||
return dep.get() == asset;
|
||||
}
|
||||
_requestedAssets.cbegin(),
|
||||
_requestedAssets.cend(),
|
||||
[asset](const std::shared_ptr<Asset>& dep) { return dep.get() == asset; }
|
||||
);
|
||||
return it != _requiredAssets.end();
|
||||
return it != _requiredAssets.cend();
|
||||
}
|
||||
|
||||
const std::vector<std::shared_ptr<Asset>>& Asset::requiredAssets() const {
|
||||
return _requiredAssets;
|
||||
std::vector<Asset*> Asset::requiredAssets() const {
|
||||
std::vector<Asset*> res;
|
||||
res.reserve(_requiredAssets.size());
|
||||
for (const std::shared_ptr<Asset>& a : _requiredAssets) {
|
||||
res.push_back(a.get());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Asset>> Asset::requiringAssets() const {
|
||||
std::vector<std::shared_ptr<Asset>> assets;
|
||||
assets.reserve(_requiringAssets.size());
|
||||
std::vector<Asset*> Asset::requiringAssets() const {
|
||||
std::vector<Asset*> res;
|
||||
res.reserve(_requiringAssets.size());
|
||||
for (const std::weak_ptr<Asset>& a : _requiringAssets) {
|
||||
std::shared_ptr<Asset> shared = a.lock();
|
||||
if (shared) {
|
||||
assets.push_back(shared);
|
||||
if (std::shared_ptr<Asset> shared = a.lock(); shared) {
|
||||
res.push_back(shared.get());
|
||||
}
|
||||
}
|
||||
return assets;
|
||||
return res;
|
||||
}
|
||||
|
||||
const std::vector<std::shared_ptr<Asset>>& Asset::requestedAssets() const {
|
||||
return _requestedAssets;
|
||||
std::vector<Asset*> Asset::requestedAssets() const {
|
||||
std::vector<Asset*> res;
|
||||
res.reserve(_requestedAssets.size());
|
||||
for (const std::shared_ptr<Asset>& a : _requestedAssets) {
|
||||
res.push_back(a.get());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Asset>> Asset::requestingAssets() const {
|
||||
std::vector<std::shared_ptr<Asset>> assets;
|
||||
assets.reserve(_requestingAssets.size());
|
||||
std::vector<Asset*> Asset::requestingAssets() const {
|
||||
std::vector<Asset*> res;
|
||||
res.reserve(_requestingAssets.size());
|
||||
for (const std::weak_ptr<Asset>& a : _requestingAssets) {
|
||||
std::shared_ptr<Asset> shared = a.lock();
|
||||
if (shared) {
|
||||
assets.push_back(shared);
|
||||
if (std::shared_ptr<Asset> shared = a.lock(); shared) {
|
||||
res.push_back(shared.get());
|
||||
}
|
||||
}
|
||||
return assets;
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Asset>> Asset::childAssets() const {
|
||||
std::vector<std::shared_ptr<Asset>> children;
|
||||
std::vector<Asset*> Asset::childAssets() const {
|
||||
std::vector<Asset*> children;
|
||||
children.reserve(_requiredAssets.size() + _requestedAssets.size());
|
||||
children.insert(children.end(), _requiredAssets.begin(), _requiredAssets.end());
|
||||
children.insert(children.end(), _requestedAssets.begin(), _requestedAssets.end());
|
||||
|
||||
for (const std::shared_ptr<Asset>& a : _requiredAssets) {
|
||||
children.push_back(a.get());
|
||||
}
|
||||
for (const std::shared_ptr<Asset>& a : _requestedAssets) {
|
||||
children.push_back(a.get());
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Asset>> Asset::parentAssets() const {
|
||||
std::vector<std::shared_ptr<Asset>> parents;
|
||||
std::vector<std::shared_ptr<Asset>> requiring = requiringAssets();
|
||||
std::vector<std::shared_ptr<Asset>> requesting = requestingAssets();
|
||||
parents.reserve(requiring.size() + requesting.size());
|
||||
parents.insert(parents.end(), requiring.begin(), requiring.end());
|
||||
parents.insert(parents.end(), requesting.begin(), requesting.end());
|
||||
return parents;
|
||||
}
|
||||
|
||||
bool Asset::isRequired() const {
|
||||
return !_requiringAssets.empty();
|
||||
}
|
||||
|
||||
bool Asset::isRequested() const {
|
||||
return !_requestingAssets.empty();
|
||||
}
|
||||
|
||||
bool Asset::shouldBeInitialized() const {
|
||||
std::vector<std::shared_ptr<Asset>> parents = parentAssets();
|
||||
const auto initializedAsset = std::find_if(
|
||||
parents.begin(),
|
||||
parents.end(),
|
||||
[](const std::shared_ptr<Asset>& a) {
|
||||
return a->state() == State::Initialized;
|
||||
}
|
||||
);
|
||||
return initializedAsset != parents.end();
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
#include <ghoul/lua/luastate.h>
|
||||
#include <ghoul/lua/lua_helper.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <ghoul/misc/defer.h>
|
||||
|
||||
|
||||
#include "assetloader_lua.inl"
|
||||
|
||||
namespace {
|
||||
@@ -55,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";
|
||||
@@ -64,7 +72,7 @@ namespace {
|
||||
constexpr const char* AssetFileSuffix = "asset";
|
||||
constexpr const char* SceneFileSuffix = "scene";
|
||||
|
||||
enum class PathType : int {
|
||||
enum class PathType {
|
||||
RelativeToAsset = 0,
|
||||
RelativeToAssetRoot,
|
||||
Absolute
|
||||
@@ -85,7 +93,7 @@ namespace {
|
||||
}
|
||||
return PathType::RelativeToAssetRoot;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -97,9 +105,9 @@ AssetLoader::AssetLoader(ghoul::lua::LuaState* luaState,
|
||||
, _assetRootDirectory(std::move(assetRootDirectory))
|
||||
, _luaState(luaState)
|
||||
{
|
||||
setCurrentAsset(_rootAsset);
|
||||
setCurrentAsset(_rootAsset.get());
|
||||
|
||||
// Create _assets table.
|
||||
// Create _assets table
|
||||
lua_newtable(*_luaState);
|
||||
_assetsTableRef = luaL_ref(*_luaState, LUA_REGISTRYINDEX);
|
||||
}
|
||||
@@ -124,37 +132,35 @@ void AssetLoader::untrackAsset(Asset* asset) {
|
||||
}
|
||||
|
||||
void AssetLoader::setUpAssetLuaTable(Asset* asset) {
|
||||
/*
|
||||
Set up lua table:
|
||||
AssetInfo
|
||||
|- Exports (table<name, exported data>)
|
||||
|- Asset
|
||||
| |- localResource
|
||||
| |- syncedResource
|
||||
| |- require
|
||||
| |- request
|
||||
| |- exists
|
||||
| |- export
|
||||
| |- onInitialize
|
||||
| |- onDeinitialize
|
||||
| |- directory
|
||||
|- Dependants (table<dependant, Dependency dep>)
|
||||
// Set up lua table:
|
||||
// AssetInfo
|
||||
// |- Exports (table<name, exported data>)
|
||||
// |- Asset
|
||||
// | |- localResource
|
||||
// | |- syncedResource
|
||||
// | |- require
|
||||
// | |- request
|
||||
// | |- exists
|
||||
// | |- export
|
||||
// | |- onInitialize
|
||||
// | |- onDeinitialize
|
||||
// | |- directory
|
||||
// |- Dependants (table<dependant, Dependency dep>)
|
||||
//
|
||||
// where Dependency is a table:
|
||||
// Dependency
|
||||
// |- onInitialize
|
||||
// |- onDeinitialize
|
||||
|
||||
where Dependency is a table:
|
||||
Dependency
|
||||
|- onInitialize
|
||||
|- onDeinitialize
|
||||
*/
|
||||
|
||||
int top = lua_gettop(*_luaState);
|
||||
const int top = lua_gettop(*_luaState);
|
||||
|
||||
// Push the global table of AssetInfos to the lua stack.
|
||||
lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef);
|
||||
int globalTableIndex = lua_gettop(*_luaState);
|
||||
const int globalTableIndex = lua_gettop(*_luaState);
|
||||
|
||||
// Create a AssetInfo table for the current asset.
|
||||
lua_newtable(*_luaState);
|
||||
int assetInfoTableIndex = lua_gettop(*_luaState);
|
||||
const int assetInfoTableIndex = lua_gettop(*_luaState);
|
||||
|
||||
// Register empty Exports table for the current asset.
|
||||
// (string => exported object)
|
||||
@@ -164,7 +170,7 @@ void AssetLoader::setUpAssetLuaTable(Asset* asset) {
|
||||
// Create Asset table
|
||||
// (string => lua functions)
|
||||
lua_newtable(*_luaState);
|
||||
int assetTableIndex = lua_gettop(*_luaState);
|
||||
const int assetTableIndex = lua_gettop(*_luaState);
|
||||
|
||||
// Register local resource function
|
||||
// string localResource(string path)
|
||||
@@ -191,7 +197,7 @@ void AssetLoader::setUpAssetLuaTable(Asset* asset) {
|
||||
lua_setfield(*_luaState, assetTableIndex, RequestFunctionName);
|
||||
|
||||
// Register exists function
|
||||
// bool exsists(string path)
|
||||
// bool exists(string path)
|
||||
lua_pushlightuserdata(*_luaState, asset);
|
||||
lua_pushcclosure(*_luaState, &assetloader::exists, 1);
|
||||
lua_setfield(*_luaState, assetTableIndex, ExistsFunctionName);
|
||||
@@ -239,10 +245,10 @@ void AssetLoader::setUpAssetLuaTable(Asset* asset) {
|
||||
}
|
||||
|
||||
void AssetLoader::tearDownAssetLuaTable(Asset* asset) {
|
||||
int top = lua_gettop(*_luaState);
|
||||
const int top = lua_gettop(*_luaState);
|
||||
// Push the global table of AssetInfos to the lua stack.
|
||||
lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef);
|
||||
int globalTableIndex = lua_gettop(*_luaState);
|
||||
const int globalTableIndex = lua_gettop(*_luaState);
|
||||
|
||||
lua_pushnil(*_luaState);
|
||||
|
||||
@@ -251,9 +257,9 @@ void AssetLoader::tearDownAssetLuaTable(Asset* asset) {
|
||||
lua_settop(*_luaState, top);
|
||||
}
|
||||
|
||||
bool AssetLoader::loadAsset(std::shared_ptr<Asset> asset) {
|
||||
int top = lua_gettop(*_luaState);
|
||||
std::shared_ptr<Asset> parentAsset = _currentAsset;
|
||||
bool AssetLoader::loadAsset(Asset* asset) {
|
||||
const int top = lua_gettop(*_luaState);
|
||||
Asset* parentAsset = _currentAsset;
|
||||
|
||||
setCurrentAsset(asset);
|
||||
defer {
|
||||
@@ -270,7 +276,8 @@ bool AssetLoader::loadAsset(std::shared_ptr<Asset> asset) {
|
||||
|
||||
try {
|
||||
ghoul::lua::runScriptFile(*_luaState, asset->assetFilePath());
|
||||
} catch (const ghoul::lua::LuaRuntimeException& e) {
|
||||
}
|
||||
catch (const ghoul::lua::LuaRuntimeException& e) {
|
||||
LERROR(fmt::format(
|
||||
"Could not load asset '{}': {}", asset->assetFilePath(), e.message)
|
||||
);
|
||||
@@ -278,6 +285,35 @@ bool AssetLoader::loadAsset(std::shared_ptr<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;
|
||||
}
|
||||
@@ -293,14 +329,18 @@ void AssetLoader::unloadAsset(Asset* asset) {
|
||||
}
|
||||
_onDeinitializationFunctionRefs[asset].clear();
|
||||
|
||||
for (const auto& it : _onDependencyInitializationFunctionRefs[asset]) {
|
||||
for (const std::pair<const Asset*, std::vector<int>>& it :
|
||||
_onDependencyInitializationFunctionRefs[asset])
|
||||
{
|
||||
for (int ref : it.second) {
|
||||
luaL_unref(*_luaState, LUA_REGISTRYINDEX, ref);
|
||||
}
|
||||
}
|
||||
_onDependencyInitializationFunctionRefs.erase(asset);
|
||||
|
||||
for (const auto& it : _onDependencyDeinitializationFunctionRefs[asset]) {
|
||||
for (const std::pair<Asset*, std::vector<int>>& it :
|
||||
_onDependencyDeinitializationFunctionRefs[asset])
|
||||
{
|
||||
for (int ref : it.second) {
|
||||
luaL_unref(*_luaState, LUA_REGISTRYINDEX, ref);
|
||||
}
|
||||
@@ -330,60 +370,54 @@ std::string AssetLoader::generateAssetPath(const std::string& baseDirectory,
|
||||
|
||||
// Construct the full path including the .asset extension
|
||||
std::string assetSuffix = std::string(".") + AssetFileSuffix;
|
||||
bool hasAssetSuffix =
|
||||
const bool hasAssetSuffix =
|
||||
(assetPath.size() > assetSuffix.size()) &&
|
||||
(assetPath.substr(assetPath.size() - assetSuffix.size()) == assetSuffix);
|
||||
std::string fullAssetPath =
|
||||
const std::string fullAssetPath =
|
||||
hasAssetSuffix ?
|
||||
prefix + assetPath :
|
||||
prefix + assetPath + assetSuffix;
|
||||
bool fullAssetPathExists = FileSys.fileExists(FileSys.absPath(fullAssetPath));
|
||||
|
||||
// Construct the full path including the .scene extension
|
||||
std::string sceneSuffix = std::string(".") + SceneFileSuffix;
|
||||
bool hasSceneSuffix =
|
||||
const std::string sceneSuffix = std::string(".") + SceneFileSuffix;
|
||||
const bool hasSceneSuffix =
|
||||
(assetPath.size() > sceneSuffix.size()) &&
|
||||
(assetPath.substr(assetPath.size() - sceneSuffix.size()) == sceneSuffix);
|
||||
std::string fullScenePath =
|
||||
const std::string fullScenePath =
|
||||
hasSceneSuffix ?
|
||||
prefix + assetPath :
|
||||
prefix + assetPath + sceneSuffix;
|
||||
bool fullScenePathExists = FileSys.fileExists(FileSys.absPath(fullScenePath));
|
||||
const bool fullScenePathExists = FileSys.fileExists(FileSys.absPath(fullScenePath));
|
||||
|
||||
if (fullAssetPathExists && fullScenePathExists) {
|
||||
LWARNING(
|
||||
fmt::format(
|
||||
"'{}' and '{}' file found with non-specific request '{}'. Loading '{}'. "
|
||||
"Explicitly add extension to suppress this warning.",
|
||||
fullAssetPath,
|
||||
fullScenePath,
|
||||
prefix + assetPath,
|
||||
fullAssetPath
|
||||
)
|
||||
);
|
||||
LWARNING(fmt::format(
|
||||
"'{}' and '{}' file found with non-specific request '{}'. Loading '{}'. "
|
||||
"Explicitly add extension to suppress this warning.",
|
||||
fullAssetPath, fullScenePath, prefix + assetPath, fullAssetPath
|
||||
));
|
||||
|
||||
return ghoul::filesystem::File(FileSys.absPath(fullAssetPath));
|
||||
return FileSys.absPath(fullAssetPath);
|
||||
}
|
||||
|
||||
if (fullScenePathExists) {
|
||||
return ghoul::filesystem::File(FileSys.absPath(fullScenePath));
|
||||
return FileSys.absPath(fullScenePath);
|
||||
}
|
||||
|
||||
// We don't check whether the file exists here as the error will be more
|
||||
// comprehensively logged by Lua either way
|
||||
return ghoul::filesystem::File(FileSys.absPath(fullAssetPath));
|
||||
return FileSys.absPath(fullAssetPath);
|
||||
}
|
||||
|
||||
std::shared_ptr<Asset> AssetLoader::getAsset(std::string name) {
|
||||
std::shared_ptr<Asset> AssetLoader::getAsset(const std::string& name) {
|
||||
ghoul::filesystem::Directory directory = currentDirectory();
|
||||
std::string path = generateAssetPath(directory, std::move(name));
|
||||
const std::string path = generateAssetPath(directory, name);
|
||||
|
||||
// Check if asset is already loaded.
|
||||
const auto it = _trackedAssets.find(path);
|
||||
|
||||
if (it != _trackedAssets.end()) {
|
||||
std::shared_ptr<Asset> a = it->second.lock();
|
||||
if (a != nullptr) {
|
||||
if (std::shared_ptr<Asset> a = it->second.lock(); a != nullptr) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
@@ -401,7 +435,7 @@ std::shared_ptr<Asset> AssetLoader::getAsset(std::string name) {
|
||||
int AssetLoader::onInitializeLua(Asset* asset) {
|
||||
ghoul::lua::checkArgumentsAndThrow(*_luaState, 1, "lua::onInitialize");
|
||||
|
||||
int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX);
|
||||
const int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX);
|
||||
_onInitializationFunctionRefs[asset].push_back(referenceIndex);
|
||||
|
||||
lua_settop(*_luaState, 0);
|
||||
@@ -411,7 +445,7 @@ int AssetLoader::onInitializeLua(Asset* asset) {
|
||||
int AssetLoader::onDeinitializeLua(Asset* asset) {
|
||||
ghoul::lua::checkArgumentsAndThrow(*_luaState, 1, "lua::onDeinitialize");
|
||||
|
||||
int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX);
|
||||
const int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX);
|
||||
_onDeinitializationFunctionRefs[asset].push_back(referenceIndex);
|
||||
|
||||
lua_settop(*_luaState, 0);
|
||||
@@ -421,9 +455,8 @@ int AssetLoader::onDeinitializeLua(Asset* asset) {
|
||||
int AssetLoader::onInitializeDependencyLua(Asset* dependant, Asset* dependency) {
|
||||
ghoul::lua::checkArgumentsAndThrow(*_luaState, 1, "lua::onInitializeDependency");
|
||||
|
||||
int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX);
|
||||
_onDependencyInitializationFunctionRefs[dependant][dependency]
|
||||
.push_back(referenceIndex);
|
||||
const int refIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX);
|
||||
_onDependencyInitializationFunctionRefs[dependant][dependency].push_back(refIndex);
|
||||
|
||||
lua_settop(*_luaState, 0);
|
||||
return 0;
|
||||
@@ -432,24 +465,16 @@ int AssetLoader::onInitializeDependencyLua(Asset* dependant, Asset* dependency)
|
||||
int AssetLoader::onDeinitializeDependencyLua(Asset* dependant, Asset* dependency) {
|
||||
ghoul::lua::checkArgumentsAndThrow(*_luaState, 1, "lua::onDeinitializeDependency");
|
||||
|
||||
int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX);
|
||||
_onDependencyDeinitializationFunctionRefs[dependant][dependency]
|
||||
.push_back(referenceIndex);
|
||||
const int refIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX);
|
||||
_onDependencyDeinitializationFunctionRefs[dependant][dependency].push_back(refIndex);
|
||||
|
||||
lua_settop(*_luaState, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::shared_ptr<Asset> AssetLoader::require(const std::string& identifier) {
|
||||
std::shared_ptr<Asset> asset = getAsset(identifier);
|
||||
std::shared_ptr<Asset> dependant = _currentAsset;
|
||||
dependant->require(asset);
|
||||
return asset;
|
||||
}
|
||||
|
||||
std::shared_ptr<Asset> AssetLoader::request(const std::string& identifier) {
|
||||
std::shared_ptr<Asset> asset = getAsset(identifier);
|
||||
std::shared_ptr<Asset> parent = _currentAsset;
|
||||
Asset* parent = _currentAsset;
|
||||
parent->request(asset);
|
||||
assetRequested(parent, asset);
|
||||
return asset;
|
||||
@@ -457,7 +482,7 @@ std::shared_ptr<Asset> AssetLoader::request(const std::string& identifier) {
|
||||
|
||||
void AssetLoader::unrequest(const std::string& identifier) {
|
||||
std::shared_ptr<Asset> asset = has(identifier);
|
||||
std::shared_ptr<Asset> parent = _currentAsset;
|
||||
Asset* parent = _currentAsset;
|
||||
parent->unrequest(asset.get());
|
||||
assetUnrequested(parent, asset);
|
||||
}
|
||||
@@ -472,13 +497,12 @@ ghoul::filesystem::Directory AssetLoader::currentDirectory() const {
|
||||
}
|
||||
|
||||
std::shared_ptr<Asset> AssetLoader::add(const std::string& identifier) {
|
||||
setCurrentAsset(_rootAsset);
|
||||
setCurrentAsset(_rootAsset.get());
|
||||
return request(identifier);
|
||||
}
|
||||
|
||||
|
||||
void AssetLoader::remove(const std::string& identifier) {
|
||||
setCurrentAsset(_rootAsset);
|
||||
setCurrentAsset(_rootAsset.get());
|
||||
unrequest(identifier);
|
||||
}
|
||||
|
||||
@@ -493,12 +517,12 @@ std::shared_ptr<Asset> AssetLoader::has(const std::string& identifier) const {
|
||||
return it->second.lock();
|
||||
}
|
||||
|
||||
ghoul::lua::LuaState* AssetLoader::luaState() {
|
||||
return _luaState;
|
||||
const Asset& AssetLoader::rootAsset() const {
|
||||
return *_rootAsset;
|
||||
}
|
||||
|
||||
std::shared_ptr<Asset> AssetLoader::rootAsset() const {
|
||||
return _rootAsset;
|
||||
Asset& AssetLoader::rootAsset() {
|
||||
return *_rootAsset;
|
||||
}
|
||||
|
||||
const std::string& AssetLoader::assetRootDirectory() const {
|
||||
@@ -520,7 +544,7 @@ void AssetLoader::callOnInitialize(Asset* asset) {
|
||||
}
|
||||
|
||||
void AssetLoader::callOnDeinitialize(Asset * asset) {
|
||||
std::vector<int>& funs = _onDeinitializationFunctionRefs[asset];
|
||||
const std::vector<int>& funs = _onDeinitializationFunctionRefs[asset];
|
||||
for (auto it = funs.rbegin(); it != funs.rend(); it++) {
|
||||
lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, *it);
|
||||
if (lua_pcall(*_luaState, 0, 0, 0) != LUA_OK) {
|
||||
@@ -553,7 +577,9 @@ void AssetLoader::callOnDependencyInitialize(Asset* asset, Asset* dependant) {
|
||||
}
|
||||
|
||||
void AssetLoader::callOnDependencyDeinitialize(Asset* asset, Asset* dependant) {
|
||||
std::vector<int>& funs = _onDependencyDeinitializationFunctionRefs[dependant][asset];
|
||||
const std::vector<int>& funs =
|
||||
_onDependencyDeinitializationFunctionRefs[dependant][asset];
|
||||
|
||||
for (auto it = funs.rbegin(); it != funs.rend(); it++) {
|
||||
lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, *it);
|
||||
if (lua_pcall(*_luaState, 0, 0, 0) != LUA_OK) {
|
||||
@@ -571,14 +597,16 @@ void AssetLoader::callOnDependencyDeinitialize(Asset* asset, Asset* dependant) {
|
||||
int AssetLoader::localResourceLua(Asset* asset) {
|
||||
ghoul::lua::checkArgumentsAndThrow(*_luaState, 1, "lua::localResourceLua");
|
||||
|
||||
std::string resourceName = ghoul::lua::value<std::string>(
|
||||
std::string name = ghoul::lua::value<std::string>(
|
||||
*_luaState,
|
||||
1,
|
||||
ghoul::lua::PopValue::Yes
|
||||
);
|
||||
std::string resolved = asset->resolveLocalResource(resourceName);
|
||||
|
||||
lua_pushstring(*_luaState, resolved.c_str());
|
||||
const std::string resolvedName =
|
||||
asset->assetDirectory() + ghoul::filesystem::FileSystem::PathSeparator + name;
|
||||
|
||||
lua_pushstring(*_luaState, resolvedName.c_str());
|
||||
|
||||
ghoul_assert(lua_gettop(*_luaState) == 1, "Incorrect number of items left on stack");
|
||||
return 1;
|
||||
@@ -590,12 +618,12 @@ int AssetLoader::syncedResourceLua(Asset* asset) {
|
||||
ghoul::Dictionary d;
|
||||
ghoul::lua::luaDictionaryFromState(*_luaState, d);
|
||||
|
||||
std::shared_ptr<ResourceSynchronization> sync =
|
||||
std::unique_ptr<ResourceSynchronization> sync =
|
||||
ResourceSynchronization::createFromDictionary(d);
|
||||
|
||||
std::string absolutePath = sync->directory();
|
||||
const std::string absolutePath = sync->directory();
|
||||
|
||||
asset->addSynchronization(sync);
|
||||
asset->addSynchronization(std::move(sync));
|
||||
|
||||
lua_settop(*_luaState, 0);
|
||||
lua_pushstring(*_luaState, absolutePath.c_str());
|
||||
@@ -604,13 +632,13 @@ int AssetLoader::syncedResourceLua(Asset* asset) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void AssetLoader::setCurrentAsset(std::shared_ptr<Asset> asset) {
|
||||
int top = lua_gettop(*_luaState);
|
||||
void AssetLoader::setCurrentAsset(Asset* asset) {
|
||||
const int top = lua_gettop(*_luaState);
|
||||
|
||||
_currentAsset = asset;
|
||||
// Set `asset` lua global to point to the current asset table
|
||||
|
||||
if (asset == _rootAsset) {
|
||||
if (asset == _rootAsset.get()) {
|
||||
lua_pushnil(*_luaState);
|
||||
lua_setglobal(*_luaState, AssetGlobalVariableName);
|
||||
lua_settop(*_luaState, top);
|
||||
@@ -631,7 +659,8 @@ int AssetLoader::requireLua(Asset* dependant) {
|
||||
std::string assetName = luaL_checkstring(*_luaState, 1);
|
||||
lua_settop(*_luaState, 0);
|
||||
|
||||
std::shared_ptr<Asset> dependency = require(assetName);
|
||||
std::shared_ptr<Asset> dependency = getAsset(assetName);
|
||||
_currentAsset->require(dependency);
|
||||
|
||||
if (!dependency) {
|
||||
return ghoul::lua::luaError(
|
||||
@@ -646,14 +675,14 @@ int AssetLoader::requireLua(Asset* dependant) {
|
||||
lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef);
|
||||
lua_getfield(*_luaState, -1, dependency->id().c_str());
|
||||
lua_getfield(*_luaState, -1, ExportsTableName);
|
||||
int exportsTableIndex = lua_gettop(*_luaState);
|
||||
const int exportsTableIndex = lua_gettop(*_luaState);
|
||||
|
||||
// Get the dependency table
|
||||
lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef);
|
||||
lua_getfield(*_luaState, -1, dependency->id().c_str());
|
||||
lua_getfield(*_luaState, -1, DependantsTableName);
|
||||
lua_getfield(*_luaState, -1, dependant->id().c_str());
|
||||
int dependencyTableIndex = lua_gettop(*_luaState);
|
||||
const int dependencyTableIndex = lua_gettop(*_luaState);
|
||||
|
||||
lua_pushvalue(*_luaState, exportsTableIndex);
|
||||
lua_pushvalue(*_luaState, dependencyTableIndex);
|
||||
@@ -669,7 +698,7 @@ int AssetLoader::requireLua(Asset* dependant) {
|
||||
int AssetLoader::requestLua(Asset* parent) {
|
||||
ghoul::lua::checkArgumentsAndThrow(*_luaState, 1, "lua::request");
|
||||
|
||||
std::string assetName = luaL_checkstring(*_luaState, 1);
|
||||
const std::string assetName = luaL_checkstring(*_luaState, 1);
|
||||
lua_settop(*_luaState, 0);
|
||||
|
||||
std::shared_ptr<Asset> child = request(assetName);
|
||||
@@ -681,7 +710,7 @@ int AssetLoader::requestLua(Asset* parent) {
|
||||
lua_getfield(*_luaState, -1, child->id().c_str());
|
||||
lua_getfield(*_luaState, -1, DependantsTableName);
|
||||
lua_getfield(*_luaState, -1, parent->id().c_str());
|
||||
int dependencyTableIndex = lua_gettop(*_luaState);
|
||||
const int dependencyTableIndex = lua_gettop(*_luaState);
|
||||
|
||||
lua_pushvalue(*_luaState, dependencyTableIndex);
|
||||
|
||||
@@ -695,10 +724,10 @@ int AssetLoader::requestLua(Asset* parent) {
|
||||
int AssetLoader::existsLua(Asset*) {
|
||||
ghoul::lua::checkArgumentsAndThrow(*_luaState, 1, "lua::exists");
|
||||
|
||||
std::string assetName = luaL_checkstring(*_luaState, 1);
|
||||
const std::string assetName = luaL_checkstring(*_luaState, 1);
|
||||
|
||||
ghoul::filesystem::Directory directory = currentDirectory();
|
||||
std::string path = generateAssetPath(directory, assetName);
|
||||
const ghoul::filesystem::Directory directory = currentDirectory();
|
||||
const std::string path = generateAssetPath(directory, assetName);
|
||||
|
||||
lua_settop(*_luaState, 0);
|
||||
lua_pushboolean(*_luaState, FileSys.fileExists(path));
|
||||
@@ -709,12 +738,12 @@ int AssetLoader::existsLua(Asset*) {
|
||||
int AssetLoader::exportAssetLua(Asset* asset) {
|
||||
ghoul::lua::checkArgumentsAndThrow(*_luaState, 2, "lua::exportAsset");
|
||||
|
||||
std::string exportName = luaL_checkstring(*_luaState, 1);
|
||||
const std::string exportName = luaL_checkstring(*_luaState, 1);
|
||||
|
||||
lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef);
|
||||
lua_getfield(*_luaState, -1, asset->id().c_str());
|
||||
lua_getfield(*_luaState, -1, ExportsTableName);
|
||||
int exportsTableIndex = lua_gettop(*_luaState);
|
||||
const int exportsTableIndex = lua_gettop(*_luaState);
|
||||
|
||||
// push the second argument
|
||||
lua_pushvalue(*_luaState, 2);
|
||||
@@ -726,7 +755,7 @@ int AssetLoader::exportAssetLua(Asset* asset) {
|
||||
}
|
||||
|
||||
void AssetLoader::addLuaDependencyTable(Asset* dependant, Asset* dependency) {
|
||||
int top = lua_gettop(*_luaState);
|
||||
const int top = lua_gettop(*_luaState);
|
||||
|
||||
const std::string dependantId = dependant->id();
|
||||
const std::string dependencyId = dependency->id();
|
||||
@@ -765,13 +794,9 @@ void AssetLoader::addLuaDependencyTable(Asset* dependant, Asset* dependency) {
|
||||
}
|
||||
|
||||
void AssetLoader::addAssetListener(AssetListener* listener) {
|
||||
auto it = std::find(
|
||||
_assetListeners.begin(),
|
||||
_assetListeners.end(),
|
||||
listener
|
||||
);
|
||||
const auto it = std::find(_assetListeners.cbegin(), _assetListeners.cend(), listener);
|
||||
|
||||
if (it == _assetListeners.end()) {
|
||||
if (it == _assetListeners.cend()) {
|
||||
_assetListeners.push_back(listener);
|
||||
}
|
||||
}
|
||||
@@ -784,23 +809,19 @@ void AssetLoader::removeAssetListener(AssetListener* listener) {
|
||||
));
|
||||
}
|
||||
|
||||
void AssetLoader::assetStateChanged(std::shared_ptr<Asset> asset, Asset::State state) {
|
||||
void AssetLoader::assetStateChanged(Asset* asset, Asset::State state) {
|
||||
for (AssetListener* listener : _assetListeners) {
|
||||
listener->assetStateChanged(asset, state);
|
||||
}
|
||||
}
|
||||
|
||||
void AssetLoader::assetRequested(std::shared_ptr<Asset> parent,
|
||||
std::shared_ptr<Asset> child)
|
||||
{
|
||||
void AssetLoader::assetRequested(Asset* parent, std::shared_ptr<Asset> child) {
|
||||
for (AssetListener* listener : _assetListeners) {
|
||||
listener->assetRequested(parent, child);
|
||||
}
|
||||
}
|
||||
|
||||
void AssetLoader::assetUnrequested(std::shared_ptr<Asset> parent,
|
||||
std::shared_ptr<Asset> child)
|
||||
{
|
||||
void AssetLoader::assetUnrequested(Asset* parent, std::shared_ptr<Asset> child) {
|
||||
for (AssetListener* listener : _assetListeners) {
|
||||
listener->assetUnrequested(parent, child);
|
||||
}
|
||||
|
||||
@@ -108,10 +108,6 @@ int syncedResource(lua_State* state) {
|
||||
return asset->loader()->syncedResourceLua(asset);
|
||||
}
|
||||
|
||||
int noOperation(lua_State*) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exportAsset(lua_State* state) {
|
||||
Asset* asset = reinterpret_cast<Asset*>(lua_touserdata(state, lua_upvalueindex(1)));
|
||||
return asset->loader()->exportAssetLua(asset);
|
||||
|
||||
@@ -36,23 +36,19 @@
|
||||
|
||||
namespace openspace {
|
||||
|
||||
AssetManager::AssetManager(std::unique_ptr<AssetLoader> loader,
|
||||
std::unique_ptr<SynchronizationWatcher> syncWatcher)
|
||||
: _synchronizationWatcher(std::move(syncWatcher))
|
||||
, _assetLoader(std::move(loader))
|
||||
AssetManager::AssetManager(ghoul::lua::LuaState* state, std::string assetRootDirectory)
|
||||
: _assetLoader(state, &_synchronizationWatcher, std::move(assetRootDirectory))
|
||||
{}
|
||||
|
||||
void AssetManager::initialize() {
|
||||
_assetLoader->addAssetListener(this);
|
||||
std::shared_ptr<Asset> rootAsset = _assetLoader->rootAsset();
|
||||
rootAsset->initialize();
|
||||
_assetLoader.addAssetListener(this);
|
||||
_assetLoader.rootAsset().initialize();
|
||||
}
|
||||
|
||||
void AssetManager::deinitialize() {
|
||||
_assetLoader->rootAsset()->deinitialize();
|
||||
_assetLoader->rootAsset()->unload();
|
||||
_assetLoader->removeAssetListener(this);
|
||||
_assetLoader = nullptr;
|
||||
_assetLoader.rootAsset().deinitialize();
|
||||
_assetLoader.rootAsset().unload();
|
||||
_assetLoader.removeAssetListener(this);
|
||||
}
|
||||
|
||||
bool AssetManager::update() {
|
||||
@@ -63,36 +59,36 @@ bool AssetManager::update() {
|
||||
const std::string& path = c.first;
|
||||
const bool add = c.second;
|
||||
if (add) {
|
||||
std::shared_ptr<Asset> asset = _assetLoader->add(path);
|
||||
_assetLoader.add(path);
|
||||
}
|
||||
}
|
||||
// Remove assets
|
||||
for (const std::pair<const std::string, bool>& c : _pendingStateChangeCommands) {
|
||||
const std::string& path = c.first;
|
||||
const bool remove = !c.second;
|
||||
if (remove && _assetLoader->has(path)) {
|
||||
_assetLoader->remove(path);
|
||||
if (remove && _assetLoader.has(path)) {
|
||||
_assetLoader.remove(path);
|
||||
}
|
||||
}
|
||||
_pendingStateChangeCommands.clear();
|
||||
|
||||
// Change state based on synchronizations
|
||||
_synchronizationWatcher->notify();
|
||||
_synchronizationWatcher.notify();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AssetManager::assetStateChanged(std::shared_ptr<Asset>, Asset::State) {
|
||||
void AssetManager::assetStateChanged(Asset*, Asset::State) {
|
||||
// Potential todo: notify user about asset stage change
|
||||
//LINFO(asset->id() << " changed state to " << static_cast<int>(state));
|
||||
}
|
||||
|
||||
void AssetManager::assetRequested(std::shared_ptr<Asset>, std::shared_ptr<Asset>) {
|
||||
void AssetManager::assetRequested(Asset*, std::shared_ptr<Asset>) {
|
||||
// Potential todo: notify user about asset request
|
||||
//LINFO(parent->id() << " requested " << child->id());
|
||||
}
|
||||
|
||||
void AssetManager::assetUnrequested(std::shared_ptr<Asset>, std::shared_ptr<Asset>) {
|
||||
void AssetManager::assetUnrequested(Asset*, std::shared_ptr<Asset>) {
|
||||
// Potential todo: notify user about asset unrequest
|
||||
//LINFO(parent->id() << " unrequested " << child->id());
|
||||
}
|
||||
@@ -109,16 +105,17 @@ void AssetManager::removeAll() {
|
||||
ZoneScoped
|
||||
|
||||
_pendingStateChangeCommands.clear();
|
||||
std::vector<std::shared_ptr<Asset>> allAssets =
|
||||
_assetLoader->rootAsset()->requestedAssets();
|
||||
|
||||
for (const std::shared_ptr<Asset>& a : allAssets) {
|
||||
for (const Asset* a : _assetLoader.rootAsset().requestedAssets()) {
|
||||
_pendingStateChangeCommands[a->assetFilePath()] = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Asset> AssetManager::rootAsset() {
|
||||
return _assetLoader->rootAsset();
|
||||
const Asset& AssetManager::rootAsset() const {
|
||||
return _assetLoader.rootAsset();
|
||||
}
|
||||
|
||||
Asset& AssetManager::rootAsset() {
|
||||
return _assetLoader.rootAsset();
|
||||
}
|
||||
|
||||
scripting::LuaLibrary AssetManager::luaLibrary() {
|
||||
@@ -144,4 +141,4 @@ scripting::LuaLibrary AssetManager::luaLibrary() {
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace openspace
|
||||
|
||||
@@ -146,10 +146,6 @@ void Scene::updateNodeRegistry() {
|
||||
_dirtyNodeRegistry = false;
|
||||
}
|
||||
|
||||
void Scene::addSceneLicense(SceneLicense license) {
|
||||
_licenses.push_back(std::move(license));
|
||||
}
|
||||
|
||||
void Scene::sortTopologically() {
|
||||
_topologicallySortedNodes.insert(
|
||||
_topologicallySortedNodes.end(),
|
||||
@@ -597,11 +593,6 @@ const std::vector<Scene::InterestingTime>& Scene::interestingTimes() const {
|
||||
return _interestingTimes;
|
||||
}
|
||||
|
||||
std::string Scene::generateSceneLicenseDocumentationJson() {
|
||||
SceneLicenseWriter writer(_licenses);
|
||||
return writer.generateJson();
|
||||
}
|
||||
|
||||
scripting::LuaLibrary Scene::luaLibrary() {
|
||||
return {
|
||||
"",
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2020 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/scene/scenelicense.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* LicenseKeyName = "Name";
|
||||
constexpr const char* LicenseKeyAttribution = "Attribution";
|
||||
constexpr const char* LicenseKeyUrl = "URL";
|
||||
constexpr const char* LicenseKeyLicenseText = "License";
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation SceneLicense::Documentation() {
|
||||
using namespace documentation;
|
||||
|
||||
return {
|
||||
"License Information",
|
||||
"core_license",
|
||||
{
|
||||
{
|
||||
LicenseKeyName,
|
||||
new StringVerifier,
|
||||
Optional::No,
|
||||
"A short, descriptive name for the license employed for this node."
|
||||
},
|
||||
{
|
||||
LicenseKeyAttribution,
|
||||
new StringVerifier,
|
||||
Optional::No,
|
||||
"The organization that shall be attributed to the licensed content."
|
||||
},
|
||||
{
|
||||
LicenseKeyUrl,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
"The URL pointing to the original license."
|
||||
},
|
||||
{
|
||||
LicenseKeyLicenseText,
|
||||
new StringVerifier,
|
||||
Optional::No,
|
||||
"The full text of the license agreements."
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
SceneLicense::SceneLicense(const ghoul::Dictionary& dictionary, std::string m)
|
||||
: module(std::move(m))
|
||||
{
|
||||
ghoul_assert(!module.empty(), "Module name must not be empty");
|
||||
|
||||
documentation::testSpecificationAndThrow(Documentation(), dictionary, "SceneLicense");
|
||||
|
||||
name = dictionary.value<std::string>(LicenseKeyName);
|
||||
attribution = dictionary.value<std::string>(LicenseKeyAttribution);
|
||||
dictionary.getValue(LicenseKeyUrl, url);
|
||||
licenseText = dictionary.value<std::string>(LicenseKeyLicenseText);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -24,13 +24,17 @@
|
||||
|
||||
#include <openspace/scene/scenelicensewriter.h>
|
||||
|
||||
#include <openspace/scene/scenelicense.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/scene/asset.h>
|
||||
#include <openspace/scene/assetmanager.h>
|
||||
|
||||
#include <ghoul/fmt.h>
|
||||
#include <sstream>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
SceneLicenseWriter::SceneLicenseWriter(std::vector<SceneLicense> licenses)
|
||||
SceneLicenseWriter::SceneLicenseWriter()
|
||||
: DocumentationGenerator(
|
||||
"Scene Licenses",
|
||||
"sceneLicense",
|
||||
@@ -38,24 +42,49 @@ SceneLicenseWriter::SceneLicenseWriter(std::vector<SceneLicense> licenses)
|
||||
{ "sceneLicenseTemplate", "${WEB}/documentation/scenelicense.hbs" }
|
||||
}
|
||||
)
|
||||
, _licenses(std::move(licenses))
|
||||
{}
|
||||
|
||||
std::string SceneLicenseWriter::generateJson() const {
|
||||
std::stringstream json;
|
||||
json << "[";
|
||||
for (const SceneLicense& license : _licenses) {
|
||||
|
||||
std::vector<const Asset*> assets =
|
||||
global::openSpaceEngine.assetManager().rootAsset().subTreeAssets();
|
||||
|
||||
int metaTotal = 0;
|
||||
for (const Asset* asset : assets) {
|
||||
std::optional<Asset::MetaInformation> meta = asset->metaInformation();
|
||||
if (!meta.has_value()) {
|
||||
continue;
|
||||
}
|
||||
metaTotal++;
|
||||
}
|
||||
|
||||
int metaCount = 0;
|
||||
for (const Asset* asset : assets) {
|
||||
std::optional<Asset::MetaInformation> meta = asset->metaInformation();
|
||||
|
||||
if (!meta.has_value()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
constexpr const char* replStr = R"("{}": "{}", )";
|
||||
constexpr const char* replStr2 = R"("{}": "{}")";
|
||||
json << "{";
|
||||
json << fmt::format(replStr, "module", escapedJson(license.module));
|
||||
json << fmt::format(replStr, "name", escapedJson(license.name));
|
||||
json << fmt::format(replStr, "attribution", escapedJson(license.attribution));
|
||||
json << fmt::format(replStr, "url", escapedJson(license.url));
|
||||
json << fmt::format(replStr2, "licenseText", escapedJson(license.licenseText));
|
||||
//json << fmt::format(replStr, "module", escapedJson(license.module));
|
||||
json << fmt::format(replStr, "name", escapedJson(meta->name));
|
||||
json << fmt::format(replStr, "version", escapedJson(meta->version));
|
||||
json << fmt::format(replStr, "description", escapedJson(meta->description));
|
||||
//json << fmt::format(replStr, "attribution", escapedJson(license.attribution));
|
||||
json << fmt::format(replStr, "author", escapedJson(meta->author));
|
||||
json << fmt::format(replStr, "url", escapedJson(meta->url));
|
||||
//json << fmt::format(replStr2, "licenseText", escapedJson(license.licenseText));
|
||||
json << fmt::format(replStr, "license", escapedJson(meta->license));
|
||||
json << fmt::format(replStr2, "path", escapedJson(asset->assetFilePath()));
|
||||
json << "}";
|
||||
|
||||
if (&license != &(_licenses.back())) {
|
||||
metaCount++;
|
||||
if (metaCount != metaTotal) {
|
||||
json << ",";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,15 +95,15 @@ ResourceSynchronization::State ResourceSynchronization::state() const {
|
||||
return _state;
|
||||
}
|
||||
|
||||
bool ResourceSynchronization::isResolved() {
|
||||
bool ResourceSynchronization::isResolved() const {
|
||||
return _state == State::Resolved;
|
||||
}
|
||||
|
||||
bool ResourceSynchronization::isRejected() {
|
||||
bool ResourceSynchronization::isRejected() const {
|
||||
return _state == State::Rejected;
|
||||
}
|
||||
|
||||
bool ResourceSynchronization::isSyncing() {
|
||||
bool ResourceSynchronization::isSyncing() const {
|
||||
return _state == State::Syncing;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,21 +32,16 @@ SynchronizationWatcher::WatchHandle SynchronizationWatcher::watchSynchronization
|
||||
std::shared_ptr<ResourceSynchronization> synchronization,
|
||||
ResourceSynchronization::StateChangeCallback callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
std::lock_guard guard(_mutex);
|
||||
|
||||
WatchHandle watchHandle = generateWatchHandle();
|
||||
WatchHandle watchHandle = nextWatchHandle++;
|
||||
|
||||
ResourceSynchronization::CallbackHandle cbh = synchronization->addStateChangeCallback(
|
||||
[this, synchronization, watchHandle, cb = std::move(callback)]
|
||||
(ResourceSynchronization::State state)
|
||||
{
|
||||
std::lock_guard<std::mutex> g(_mutex);
|
||||
_pendingNotifications.push_back({
|
||||
synchronization,
|
||||
state,
|
||||
watchHandle,
|
||||
cb
|
||||
});
|
||||
_pendingNotifications.push_back({ synchronization, state, watchHandle, cb });
|
||||
}
|
||||
);
|
||||
|
||||
@@ -56,7 +51,7 @@ SynchronizationWatcher::WatchHandle SynchronizationWatcher::watchSynchronization
|
||||
}
|
||||
|
||||
void SynchronizationWatcher::unwatchSynchronization(WatchHandle watchHandle) {
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
std::lock_guard guard(_mutex);
|
||||
|
||||
const auto it = _watchedSyncs.find(watchHandle);
|
||||
if (it == _watchedSyncs.end()) {
|
||||
@@ -84,7 +79,7 @@ void SynchronizationWatcher::unwatchSynchronization(WatchHandle watchHandle) {
|
||||
void SynchronizationWatcher::notify() {
|
||||
std::vector<NotificationData> notifications;
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
std::lock_guard guard(_mutex);
|
||||
notifications = _pendingNotifications;
|
||||
_pendingNotifications.clear();
|
||||
}
|
||||
@@ -98,8 +93,4 @@ void SynchronizationWatcher::notify() {
|
||||
}
|
||||
}
|
||||
|
||||
SynchronizationWatcher::WatchHandle SynchronizationWatcher::generateWatchHandle() {
|
||||
return nextWatchHandle++;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
Reference in New Issue
Block a user