mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-05 19:19:39 -06:00
Callbacks for asset state changes
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
asset.import('keybindings')
|
||||
asset.import('solarsystem')
|
||||
asset.import('missions/newhorizons/spice/spice')
|
||||
asset.request('keybindings')
|
||||
asset.request('solarsystem')
|
||||
asset.request('missions/newhorizons/spice/spice')
|
||||
@@ -1,5 +1,5 @@
|
||||
local assetHelper = asset.import('assethelper')
|
||||
local sunTransforms = asset.import('sun/transforms')
|
||||
local assetHelper = asset.require('assethelper')
|
||||
local sunTransforms = asset.require('sun/transforms')
|
||||
|
||||
local EarthTrail = {
|
||||
Name = "EarthTrail",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
-- asset.import('./mercury/trail')
|
||||
-- asset.import('./venus/trail')
|
||||
asset.import('./earth/trail')
|
||||
-- asset.import('./mars/trail')
|
||||
-- asset.import('./jupiter/trail')
|
||||
-- asset.import('./saturn/trail')
|
||||
-- asset.import('./uranus/trail')
|
||||
-- asset.import('./neptune/trail')
|
||||
-- asset.request('./mercury/trail')
|
||||
-- asset.request('./venus/trail')
|
||||
asset.request('./earth/trail')
|
||||
-- asset.request('./mars/trail')
|
||||
-- asset.request('./jupiter/trail')
|
||||
-- asset.request('./saturn/trail')
|
||||
-- asset.request('./uranus/trail')
|
||||
-- asset.request('./neptune/trail')
|
||||
@@ -1,10 +1,10 @@
|
||||
asset.import("sun/sun")
|
||||
--asset.import("planets/planets")
|
||||
-- asset.import("planets/moons")
|
||||
asset.import("planets/trails")
|
||||
-- asset.import("dwarfplanets/pluto")
|
||||
asset.request("sun/sun")
|
||||
--asset.request("planets/planets")
|
||||
-- asset.request("planets/moons")
|
||||
asset.request("planets/trails")
|
||||
-- asset.request("dwarfplanets/pluto")
|
||||
|
||||
local sceneHelper = asset.import("scenehelper")
|
||||
local sceneHelper = asset.require("scenehelper")
|
||||
|
||||
asset.onInitialize(function ()
|
||||
dofile(openspace.absPath('${SCRIPTS}/bind_common_keys.lua'))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local AssetHelper = asset.import("assethelper")
|
||||
local AssetHelper = asset.require("assethelper")
|
||||
|
||||
local syncedDirectory = asset.syncedResource({
|
||||
Type = "HttpSynchronization",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local assetHelper = asset.import('assethelper')
|
||||
local transforms = asset.import('./transforms')
|
||||
local assetHelper = asset.require('assethelper')
|
||||
local transforms = asset.require('./transforms')
|
||||
|
||||
local sunParentName = transforms.SunIau.Name;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local assetHelper = asset.import("assethelper")
|
||||
asset.import("spice/base")
|
||||
local assetHelper = asset.require("assethelper")
|
||||
asset.require("spice/base")
|
||||
|
||||
-- Barycenter of the solar system, expressed in the Galactic frame
|
||||
local SolarSystemBarycenter = {
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
#include <iterator>
|
||||
|
||||
namespace openspace {
|
||||
@@ -42,8 +42,6 @@ class AssetLoader;
|
||||
|
||||
class Asset : public std::enable_shared_from_this<Asset> {
|
||||
public:
|
||||
using Optional = std::pair<std::shared_ptr<Asset>, bool>;
|
||||
|
||||
enum class State : unsigned int {
|
||||
Unloaded,
|
||||
LoadingFailed,
|
||||
@@ -54,6 +52,9 @@ public:
|
||||
Initialized,
|
||||
InitializationFailed
|
||||
};
|
||||
|
||||
using StateChangeCallback = std::function<void(State)>;
|
||||
using CallbackHandle = size_t;
|
||||
|
||||
/**
|
||||
* Root asset constructor
|
||||
@@ -61,9 +62,11 @@ public:
|
||||
Asset(AssetLoader* loader);
|
||||
|
||||
/**
|
||||
* Dependency or Optional constructor
|
||||
* Regular asset constructor
|
||||
*/
|
||||
Asset(AssetLoader* loader, ghoul::filesystem::File assetPath);
|
||||
|
||||
~Asset();
|
||||
|
||||
std::string id() const;
|
||||
std::string assetFilePath() const;
|
||||
@@ -73,12 +76,15 @@ public:
|
||||
AssetLoader* loader() const;
|
||||
State state() const;
|
||||
|
||||
CallbackHandle addStateChangeCallback(StateChangeCallback cb);
|
||||
void removeStateChangeCallback(CallbackHandle handle);
|
||||
|
||||
void setState(State state);
|
||||
void addSynchronization(std::shared_ptr<ResourceSynchronization> synchronization);
|
||||
std::vector<std::shared_ptr<ResourceSynchronization>> synchronizations();
|
||||
|
||||
std::vector<std::shared_ptr<ResourceSynchronization>> synchronizations() const;
|
||||
|
||||
// Sync
|
||||
bool isSynchronized();
|
||||
bool startSynchronizations();
|
||||
bool cancelSynchronizations();
|
||||
bool restartSynchronizations();
|
||||
@@ -108,14 +114,12 @@ public:
|
||||
|
||||
std::string resolveLocalResource(std::string resourceName);
|
||||
private:
|
||||
|
||||
void handleRequests();
|
||||
void startSync(ResourceSynchronization& rs);
|
||||
void cancelSync(ResourceSynchronization& rs);
|
||||
|
||||
State _state;
|
||||
std::atomic<State> _state;
|
||||
AssetLoader* _loader;
|
||||
std::vector<std::shared_ptr<ResourceSynchronization>> _synchronizations;
|
||||
mutable std::mutex _synchronizationsMutex;
|
||||
|
||||
bool _hasAssetPath;
|
||||
// The name of the asset
|
||||
@@ -135,6 +139,15 @@ private:
|
||||
|
||||
// Assets that refers to this asset as a requested asset
|
||||
std::vector<std::weak_ptr<Asset>> _requestingAssets;
|
||||
|
||||
// Synchronization callback handles
|
||||
std::unordered_map<ResourceSynchronization*, ResourceSynchronization::CallbackHandle>
|
||||
_syncCallbackHandles;
|
||||
|
||||
CallbackHandle _nextCallbackHandle;
|
||||
std::unordered_map<CallbackHandle, StateChangeCallback> _stateChangeCallbacks;
|
||||
std::mutex _stateChangeCallbackMutex;
|
||||
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -48,7 +49,8 @@ int onInitialize(lua_State* state);
|
||||
int onDeinitialize(lua_State* state);
|
||||
int onInitializeDependency(lua_State* state);
|
||||
int onDeinitializeDependency(lua_State* state);
|
||||
int importDependency(lua_State* state);
|
||||
int require(lua_State* state);
|
||||
int request(lua_State* state);
|
||||
int localResource(lua_State* state);
|
||||
int syncedResource(lua_State* state);
|
||||
int noOperation(lua_State* state);
|
||||
@@ -57,6 +59,9 @@ int exportAsset(lua_State* state);
|
||||
|
||||
class AssetLoader {
|
||||
public:
|
||||
using CallbackHandle = size_t;
|
||||
using AssetLoadCallback = std::function<void(std::shared_ptr<Asset>)>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
@@ -92,7 +97,7 @@ public:
|
||||
* Returns the asset identified by the identifier,
|
||||
* if the asset is loaded. Otherwise return nullptr.
|
||||
*/
|
||||
std::shared_ptr<Asset> has(const std::string& identifier);
|
||||
std::shared_ptr<Asset> has(const std::string& identifier) const;
|
||||
|
||||
/**
|
||||
* Return all assets loaded using the loadAsset method.
|
||||
@@ -113,7 +118,7 @@ public:
|
||||
/**
|
||||
* Return the asset root directory
|
||||
*/
|
||||
const std::string& assetRootDirectory();
|
||||
const std::string& assetRootDirectory() const;
|
||||
|
||||
void callOnInitialize(Asset* asset);
|
||||
|
||||
@@ -123,7 +128,11 @@ public:
|
||||
|
||||
void callOnDependencyDeinitialize(Asset* asset, Asset* dependant);
|
||||
|
||||
std::string generateAssetPath(const std::string& baseDirectory, const std::string& path) const;
|
||||
std::string generateAssetPath(const std::string& baseDirectory,
|
||||
const std::string& path) const;
|
||||
|
||||
CallbackHandle addAssetLoadCallback(AssetLoadCallback);
|
||||
void removeAssetLoadCallback(CallbackHandle cbh);
|
||||
|
||||
private:
|
||||
std::shared_ptr<Asset> require(const std::string& identifier);
|
||||
@@ -144,7 +153,8 @@ private:
|
||||
int onDeinitializeLua(Asset* asset);
|
||||
int onInitializeDependencyLua(Asset* dependant, Asset* dependency);
|
||||
int onDeinitializeDependencyLua(Asset* dependant, Asset* dependency);
|
||||
int importDependencyLua(Asset* asset);
|
||||
int requireLua(Asset* asset);
|
||||
int requestLua(Asset* asset);
|
||||
int localResourceLua(Asset* asset);
|
||||
int syncedResourceLua(Asset* asset);
|
||||
int exportAssetLua(Asset* asset);
|
||||
@@ -154,25 +164,31 @@ private:
|
||||
friend int assetloader::onDeinitialize(lua_State* state);
|
||||
friend int assetloader::onInitializeDependency(lua_State* state);
|
||||
friend int assetloader::onDeinitializeDependency(lua_State* state);
|
||||
friend int assetloader::importDependency(lua_State* state);
|
||||
friend int assetloader::require(lua_State* state);
|
||||
friend int assetloader::request(lua_State* state);
|
||||
friend int assetloader::localResource(lua_State* state);
|
||||
friend int assetloader::syncedResource(lua_State* state);
|
||||
friend int assetloader::exportAsset(lua_State* state);
|
||||
|
||||
std::shared_ptr<Asset> _rootAsset;
|
||||
std::map<std::string, std::shared_ptr<Asset>> _loadedAssets;
|
||||
std::unordered_map<std::string, std::shared_ptr<Asset>> _loadedAssets;
|
||||
std::vector<std::shared_ptr<Asset>> _assetStack;
|
||||
|
||||
std::string _assetRootDirectory;
|
||||
ghoul::lua::LuaState* _luaState;
|
||||
|
||||
// References to lua values
|
||||
std::map<Asset*, std::vector<int>> _onInitializationFunctionRefs;
|
||||
std::map<Asset*, std::vector<int>> _onDeinitializationFunctionRefs;
|
||||
std::map<Asset*, std::map<Asset*, std::vector<int>>> _onDependencyInitializationFunctionRefs;
|
||||
std::map<Asset*, std::map<Asset*, std::vector<int>>> _onDependencyDeinitializationFunctionRefs;
|
||||
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;
|
||||
|
||||
std::unordered_map<CallbackHandle, AssetLoadCallback> _assetLoadCallbacks;
|
||||
CallbackHandle _nextCallbackId;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ private:
|
||||
void startSynchronization(Asset& asset);
|
||||
void cancelSynchronization(Asset& asset);
|
||||
|
||||
void assetStateChanged(Asset& asset, Asset::State state);
|
||||
|
||||
std::unordered_map<std::string, bool> _pendingStateChangeCommands;
|
||||
//std::unordered_map<Asset*, AssetState> _stateChangesInProgress;
|
||||
@@ -92,6 +93,8 @@ private:
|
||||
std::unordered_map<Asset*, std::unordered_set<Asset*>> _syncDependencies;
|
||||
|
||||
std::unique_ptr<AssetLoader> _assetLoader;
|
||||
AssetLoader::CallbackHandle _addAssetCallbackHandle;
|
||||
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -45,7 +45,6 @@ void GuiAssetComponent::render() {
|
||||
|
||||
AssetManager& assetManager = OsEng.assetManager();
|
||||
|
||||
|
||||
std::vector<std::shared_ptr<Asset>> allAssets =
|
||||
assetManager.rootAsset()->subTreeAssets();
|
||||
|
||||
@@ -53,6 +52,19 @@ void GuiAssetComponent::render() {
|
||||
ImGui::Text("%s", a->assetFilePath().c_str());
|
||||
ImGui::NextColumn();
|
||||
|
||||
std::string stateText;
|
||||
switch(a->state()) {
|
||||
case Asset::State::Loaded: stateText = "Loaded"; break;
|
||||
case Asset::State::LoadingFailed: stateText = "LoadingFailed"; break;
|
||||
case Asset::State::Synchronizing: stateText = "Synchronizing"; break;
|
||||
case Asset::State::SyncRejected: stateText = "SyncRejected"; break;
|
||||
case Asset::State::SyncResolved: stateText = "SyncResolved"; break;
|
||||
case Asset::State::Initialized: stateText = "Initialized"; break;
|
||||
case Asset::State::InitializationFailed: stateText = "InitializationFailed"; break;
|
||||
default: stateText = "Unknown"; break;
|
||||
}
|
||||
ImGui::Text("%s", stateText.c_str());
|
||||
|
||||
ImGui::NextColumn();
|
||||
ImGui::Separator();
|
||||
/*
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <unordered_set>
|
||||
#include <mutex>
|
||||
|
||||
namespace {
|
||||
const char* _loggerCat = "Asset";
|
||||
@@ -50,6 +52,12 @@ Asset::Asset(AssetLoader* loader, ghoul::filesystem::File assetPath)
|
||||
, _assetPath(assetPath)
|
||||
{}
|
||||
|
||||
Asset::~Asset() {
|
||||
for (const auto& it : _syncCallbackHandles) {
|
||||
it.first->removeStateChangeCallback(it.second);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Asset::resolveLocalResource(std::string resourceName) {
|
||||
std::string currentAssetDirectory = assetDirectory();
|
||||
return currentAssetDirectory +
|
||||
@@ -65,28 +73,71 @@ void Asset::handleRequests() {
|
||||
}
|
||||
}
|
||||
|
||||
void Asset::startSync(ResourceSynchronization& rs) {
|
||||
rs.start();
|
||||
}
|
||||
|
||||
void Asset::cancelSync(ResourceSynchronization& rs) {
|
||||
rs.cancel();
|
||||
}
|
||||
|
||||
Asset::State Asset::state() const {
|
||||
return _state;
|
||||
}
|
||||
|
||||
Asset::CallbackHandle Asset::addStateChangeCallback(StateChangeCallback cb) {
|
||||
std::lock_guard<std::mutex> guard(_stateChangeCallbackMutex);
|
||||
CallbackHandle h = _nextCallbackHandle++;
|
||||
_stateChangeCallbacks.emplace(h, cb);
|
||||
return h;
|
||||
}
|
||||
|
||||
void Asset::removeStateChangeCallback(Asset::CallbackHandle handle) {
|
||||
std::lock_guard<std::mutex> guard(_stateChangeCallbackMutex);
|
||||
_stateChangeCallbacks.erase(handle);
|
||||
}
|
||||
|
||||
void Asset::setState(Asset::State state) {
|
||||
_state = state;
|
||||
_stateChangeCallbackMutex.lock();
|
||||
std::vector<StateChangeCallback> callbacks;
|
||||
callbacks.reserve(_stateChangeCallbacks.size());
|
||||
for (const auto& it : _stateChangeCallbacks) {
|
||||
callbacks.push_back(it.second);
|
||||
}
|
||||
_stateChangeCallbackMutex.unlock();
|
||||
for (auto& cb : callbacks) {
|
||||
cb(state);
|
||||
}
|
||||
}
|
||||
|
||||
void Asset::addSynchronization(std::shared_ptr<ResourceSynchronization> synchronization) {
|
||||
_synchronizations.push_back(synchronization);
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(_synchronizationsMutex);
|
||||
_synchronizations.push_back(synchronization);
|
||||
}
|
||||
|
||||
// Set up callback for synchronization state change.
|
||||
// This will be called from another thread, so we need to mutex protect
|
||||
// things that are touched by the callback.
|
||||
ResourceSynchronization::CallbackHandle cbh = synchronization->addStateChangeCallback(
|
||||
[this](ResourceSynchronization::State s) {
|
||||
std::vector<std::shared_ptr<ResourceSynchronization>> syncs =
|
||||
this->synchronizations();
|
||||
|
||||
if (s == ResourceSynchronization::State::Resolved) {
|
||||
auto it = std::find_if(
|
||||
syncs.begin(),
|
||||
syncs.end(),
|
||||
[](std::shared_ptr<ResourceSynchronization>& s) {
|
||||
return !s->isResolved();
|
||||
}
|
||||
);
|
||||
if (it == syncs.end()) {
|
||||
setState(State::SyncResolved);
|
||||
}
|
||||
} else if (s == ResourceSynchronization::State::Rejected) {
|
||||
setState(State::SyncRejected);
|
||||
}
|
||||
}
|
||||
);
|
||||
_syncCallbackHandles[synchronization.get()] = cbh;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<ResourceSynchronization>> Asset::synchronizations()
|
||||
{
|
||||
std::vector<std::shared_ptr<ResourceSynchronization>> Asset::synchronizations() const {
|
||||
std::lock_guard<std::mutex> guard(_synchronizationsMutex);
|
||||
return _synchronizations;
|
||||
}
|
||||
|
||||
@@ -110,24 +161,34 @@ std::vector<std::shared_ptr<Asset>> Asset::requiredSubTreeAssets() {
|
||||
return assetVector;
|
||||
}
|
||||
|
||||
bool Asset::isSynchronized() {
|
||||
State s = state();
|
||||
return s == State::SyncResolved ||
|
||||
s == State::Initialized ||
|
||||
s == State::InitializationFailed;
|
||||
}
|
||||
|
||||
bool Asset::startSynchronizations() {
|
||||
bool startedAnySync = false;
|
||||
bool foundUnresolved = false;
|
||||
// Start synchronization of all children first.
|
||||
for (auto& child : childAssets()) {
|
||||
bool started = child->startSynchronizations();
|
||||
if (started) {
|
||||
startedAnySync = true;
|
||||
if (child->startSynchronizations()) {
|
||||
foundUnresolved = true;
|
||||
}
|
||||
}
|
||||
for (const auto& s : _synchronizations) {
|
||||
// Now synchronize its own synchronizations.
|
||||
for (const auto& s : synchronizations()) {
|
||||
if (!s->isResolved()) {
|
||||
startedAnySync = true;
|
||||
startSync(*s);
|
||||
foundUnresolved = true;
|
||||
s->start();
|
||||
setState(State::Synchronizing);
|
||||
}
|
||||
}
|
||||
if (!startedAnySync) {
|
||||
// If all syncs are resolved (or no syncs exist), mark as resolved.
|
||||
if (!foundUnresolved) {
|
||||
setState(State::SyncResolved);
|
||||
}
|
||||
return startedAnySync;
|
||||
return foundUnresolved;
|
||||
}
|
||||
|
||||
bool Asset::cancelSynchronizations() {
|
||||
@@ -138,10 +199,11 @@ bool Asset::cancelSynchronizations() {
|
||||
cancelledAnySync = true;
|
||||
}
|
||||
}
|
||||
for (const auto& s : _synchronizations) {
|
||||
for (const auto& s : synchronizations()) {
|
||||
if (s->isSyncing()) {
|
||||
cancelledAnySync = true;
|
||||
cancelSync(*s);
|
||||
s->cancel();
|
||||
setState(State::Loaded);
|
||||
}
|
||||
}
|
||||
if (cancelledAnySync) {
|
||||
@@ -183,7 +245,7 @@ float Asset::synchronizationProgress() {
|
||||
bool Asset::isInitReady() const {
|
||||
// An asset is ready for initialization if all synchronizations are resolved
|
||||
// and all its dependencies are ready for initialization.
|
||||
for (const std::shared_ptr<ResourceSynchronization>& sync : _synchronizations) {
|
||||
for (const std::shared_ptr<ResourceSynchronization> sync : synchronizations()) {
|
||||
if (!sync->isResolved()) {
|
||||
return false;
|
||||
}
|
||||
@@ -382,8 +444,8 @@ std::vector<std::shared_ptr<Asset>> Asset::requestedAssets() {
|
||||
std::vector<std::shared_ptr<Asset>> Asset::childAssets() {
|
||||
std::vector<std::shared_ptr<Asset>> children;
|
||||
children.reserve(_requiredAssets.size() + _requestedAssets.size());
|
||||
children.insert(_requiredAssets.begin(), _requiredAssets.end(), children.end());
|
||||
children.insert(_requestedAssets.begin(), _requestedAssets.end(), children.end());
|
||||
children.insert(children.end(), _requiredAssets.begin(), _requiredAssets.end());
|
||||
children.insert(children.end(), _requestedAssets.begin(), _requestedAssets.end());
|
||||
return children;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,8 @@
|
||||
namespace {
|
||||
const char* AssetGlobalVariableName = "asset";
|
||||
|
||||
const char* ImportDependencyFunctionName = "import";
|
||||
const char* RequireFunctionName = "require";
|
||||
const char* RequestFunctionName = "request";
|
||||
const char* ExportFunctionName = "export";
|
||||
|
||||
const char* SyncedResourceFunctionName = "syncedResource";
|
||||
@@ -101,8 +102,13 @@ std::shared_ptr<Asset> AssetLoader::loadAsset(std::string path) {
|
||||
|
||||
ghoul::lua::runScriptFile(*_luaState, path);
|
||||
_loadedAssets.emplace(asset->id(), asset);
|
||||
asset->setState(Asset::State::Loaded);
|
||||
|
||||
for (const auto& cb : _assetLoadCallbacks) {
|
||||
cb.second(asset);
|
||||
}
|
||||
|
||||
asset->setState(Asset::State::Loaded);
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
@@ -120,6 +126,19 @@ std::string AssetLoader::generateAssetPath(const std::string& baseDirectory,
|
||||
AssetFileSuffix);
|
||||
}
|
||||
|
||||
AssetLoader::CallbackHandle
|
||||
AssetLoader::addAssetLoadCallback(AssetLoader::AssetLoadCallback cb)
|
||||
{
|
||||
CallbackHandle handle = _nextCallbackId;
|
||||
_assetLoadCallbacks.emplace(handle, cb);
|
||||
return handle;
|
||||
}
|
||||
|
||||
void AssetLoader::removeAssetLoadCallback(AssetLoader::CallbackHandle handle) {
|
||||
_assetLoadCallbacks.erase(handle);
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Asset> AssetLoader::getAsset(std::string name) {
|
||||
ghoul::filesystem::Directory directory = currentDirectory();
|
||||
std::string path = generateAssetPath(directory, name);
|
||||
@@ -150,7 +169,7 @@ int AssetLoader::onDeinitializeLua(Asset* asset) {
|
||||
|
||||
int AssetLoader::onInitializeDependencyLua(Asset* dependant, Asset* dependency) {
|
||||
int nArguments = lua_gettop(*_luaState);
|
||||
SCRIPT_CHECK_ARGUMENTS("onInitializeDependency", *_luaState, 1, nArguments);
|
||||
SCRIPT_CHECK_ARGUMENTS("onInitialize", *_luaState, 1, nArguments);
|
||||
int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX);
|
||||
_onDependencyInitializationFunctionRefs[dependant][dependency].push_back(referenceIndex);
|
||||
return 0;
|
||||
@@ -158,7 +177,7 @@ int AssetLoader::onInitializeDependencyLua(Asset* dependant, Asset* dependency)
|
||||
|
||||
int AssetLoader::onDeinitializeDependencyLua(Asset* dependant, Asset* dependency) {
|
||||
int nArguments = lua_gettop(*_luaState);
|
||||
SCRIPT_CHECK_ARGUMENTS("onDeinitializeDependency", *_luaState, 1, nArguments);
|
||||
SCRIPT_CHECK_ARGUMENTS("onDeinitialize", *_luaState, 1, nArguments);
|
||||
int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX);
|
||||
_onDependencyDeinitializationFunctionRefs[dependant][dependency].push_back(referenceIndex);
|
||||
return 0;
|
||||
@@ -178,7 +197,7 @@ std::shared_ptr<Asset> AssetLoader::request(const std::string& name) {
|
||||
parent->request(asset);
|
||||
return asset;
|
||||
} catch (const ghoul::RuntimeError& e) {
|
||||
LERROR("Failed to load " << name << e.component << " :" << e.message);
|
||||
LERROR("Failed to load " << name << ". " << e.component << " :" << e.message);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -209,10 +228,10 @@ void AssetLoader::remove(const Asset* asset) {
|
||||
//_rootAsset->removeDependency(id);
|
||||
}
|
||||
|
||||
std::shared_ptr<Asset> AssetLoader::has(const std::string& identifier) {
|
||||
std::shared_ptr<Asset> AssetLoader::has(const std::string& identifier) const {
|
||||
const auto it = _loadedAssets.find(identifier);
|
||||
if (it == _loadedAssets.end()) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
@@ -225,8 +244,7 @@ std::shared_ptr<Asset> AssetLoader::rootAsset() const {
|
||||
return _rootAsset;
|
||||
}
|
||||
|
||||
const std::string & AssetLoader::assetRootDirectory()
|
||||
{
|
||||
const std::string& AssetLoader::assetRootDirectory() const {
|
||||
return _assetRootDirectory;
|
||||
}
|
||||
|
||||
@@ -329,7 +347,8 @@ void AssetLoader::pushAsset(std::shared_ptr<Asset> asset) {
|
||||
|- Asset
|
||||
| |- localResource
|
||||
| |- syncedResource
|
||||
| |- import
|
||||
| |- require
|
||||
| |- request
|
||||
| |- export
|
||||
| |- onInitialize
|
||||
| |- onDeinitialize
|
||||
@@ -366,12 +385,19 @@ void AssetLoader::pushAsset(std::shared_ptr<Asset> asset) {
|
||||
lua_pushcclosure(*_luaState, &assetloader::syncedResource, 1);
|
||||
lua_setfield(*_luaState, assetTableIndex, SyncedResourceFunctionName);
|
||||
|
||||
// Register import-dependency function
|
||||
// Asset, Dependency import(string path)
|
||||
// Register require function
|
||||
// Asset, Dependency require(string path)
|
||||
lua_pushlightuserdata(*_luaState, asset.get());
|
||||
lua_pushcclosure(*_luaState, &assetloader::importDependency, 1);
|
||||
lua_setfield(*_luaState, assetTableIndex, ImportDependencyFunctionName);
|
||||
lua_pushcclosure(*_luaState, &assetloader::require, 1);
|
||||
lua_setfield(*_luaState, assetTableIndex, RequireFunctionName);
|
||||
|
||||
// Register request function
|
||||
// Dependency request(string path)
|
||||
lua_pushlightuserdata(*_luaState, asset.get());
|
||||
lua_pushcclosure(*_luaState, &assetloader::request, 1);
|
||||
lua_setfield(*_luaState, assetTableIndex, RequestFunctionName);
|
||||
|
||||
|
||||
// Register export-dependency function
|
||||
// export(string key, any value)
|
||||
lua_pushlightuserdata(*_luaState, asset.get());
|
||||
@@ -426,9 +452,9 @@ void AssetLoader::updateLuaGlobals() {
|
||||
lua_setglobal(*_luaState, AssetGlobalVariableName);
|
||||
}
|
||||
|
||||
int AssetLoader::importDependencyLua(Asset* dependant) {
|
||||
int AssetLoader::requireLua(Asset* dependant) {
|
||||
int nArguments = lua_gettop(*_luaState);
|
||||
SCRIPT_CHECK_ARGUMENTS("import", *_luaState, 1, nArguments);
|
||||
SCRIPT_CHECK_ARGUMENTS("require", *_luaState, 1, nArguments);
|
||||
|
||||
std::string assetName = luaL_checkstring(*_luaState, 1);
|
||||
|
||||
@@ -458,6 +484,32 @@ int AssetLoader::importDependencyLua(Asset* dependant) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
int AssetLoader::requestLua(Asset* parent) {
|
||||
int nArguments = lua_gettop(*_luaState);
|
||||
SCRIPT_CHECK_ARGUMENTS("request", *_luaState, 1, nArguments);
|
||||
|
||||
std::string assetName = luaL_checkstring(*_luaState, 1);
|
||||
|
||||
std::shared_ptr<Asset> child = request(assetName);
|
||||
|
||||
if (child) {
|
||||
addLuaDependencyTable(parent, child.get());
|
||||
|
||||
// Get the dependency table
|
||||
lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef);
|
||||
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);
|
||||
|
||||
|
||||
lua_pushvalue(*_luaState, dependencyTableIndex);
|
||||
} else {
|
||||
lua_pushnil(*_luaState);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int AssetLoader::exportAssetLua(Asset* asset) {
|
||||
int nArguments = lua_gettop(*_luaState);
|
||||
SCRIPT_CHECK_ARGUMENTS("exportAsset", *_luaState, 2, nArguments);
|
||||
|
||||
@@ -70,18 +70,32 @@ int onDeinitializeDependency(lua_State* state) {
|
||||
|
||||
|
||||
/**
|
||||
* Imports dependencies
|
||||
* Requires rependency
|
||||
* Gives access to
|
||||
* AssetTable: Exported lua values
|
||||
* Dependency: ...
|
||||
* Usage: {AssetTable, Dependency} = asset.import(string assetIdentifier)
|
||||
*/
|
||||
int importDependency(lua_State* state) {
|
||||
int require(lua_State* state) {
|
||||
Asset *asset =
|
||||
reinterpret_cast<Asset*>(lua_touserdata(state, lua_upvalueindex(1)));
|
||||
return asset->loader()->importDependencyLua(asset);
|
||||
return asset->loader()->requireLua(asset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests rependency
|
||||
* Gives access to
|
||||
* Dependency: ...
|
||||
* Usage: Dependency = asset.import(string assetIdentifier)
|
||||
*/
|
||||
int request(lua_State* state) {
|
||||
Asset *asset =
|
||||
reinterpret_cast<Asset*>(lua_touserdata(state, lua_upvalueindex(1)));
|
||||
return asset->loader()->requestLua(asset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int localResource(lua_State* state) {
|
||||
Asset *asset =
|
||||
reinterpret_cast<Asset*>(lua_touserdata(state, lua_upvalueindex(1)));
|
||||
|
||||
@@ -42,11 +42,24 @@ AssetManager::AssetManager(std::unique_ptr<AssetLoader> loader)
|
||||
{}
|
||||
|
||||
void AssetManager::initialize() {
|
||||
_assetLoader->rootAsset()->initialize();
|
||||
_addAssetCallbackHandle = _assetLoader->addAssetLoadCallback(
|
||||
[this] (std::shared_ptr<Asset> a) {
|
||||
a->addStateChangeCallback([&a, this] (Asset::State state) {
|
||||
assetStateChanged(*a, state);
|
||||
});
|
||||
}
|
||||
);
|
||||
std::shared_ptr<Asset> rootAsset = _assetLoader->rootAsset();
|
||||
rootAsset->addStateChangeCallback([&rootAsset, this] (Asset::State state) {
|
||||
assetStateChanged(*rootAsset, state);
|
||||
});
|
||||
rootAsset->initialize();
|
||||
}
|
||||
|
||||
void AssetManager::deinitialize() {
|
||||
_assetLoader->rootAsset()->deinitialize();
|
||||
|
||||
_assetLoader->removeAssetLoadCallback(_addAssetCallbackHandle);
|
||||
}
|
||||
|
||||
bool AssetManager::update() {
|
||||
@@ -139,6 +152,13 @@ void AssetManager::startSynchronization(Asset&) {
|
||||
void AssetManager::cancelSynchronization(Asset&) {
|
||||
// todo: implement this
|
||||
}
|
||||
|
||||
void AssetManager::assetStateChanged(Asset& asset, Asset::State state) {
|
||||
// Todo: store this and handle the state change data in the update loop.
|
||||
// to make sure this happens on the main thread.
|
||||
// Check if assets should start syncing or if they should init.
|
||||
// flags: autoSync, autoInit ?
|
||||
}
|
||||
|
||||
/**
|
||||
* Load or unload asset depening on target state
|
||||
@@ -322,13 +342,22 @@ void AssetManager::unloadAsset(Asset* asset) {
|
||||
}
|
||||
|
||||
std::shared_ptr<Asset> AssetManager::tryAddAsset(const std::string& path) {
|
||||
_assetLoader->add(path);
|
||||
try {
|
||||
_assetLoader->add(path);
|
||||
} catch (const ghoul::RuntimeError& e) {
|
||||
LERROR("Error adding asset: " << e.component << ": " << e.message);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool AssetManager::tryRemoveAsset(const std::string& path) {
|
||||
_assetLoader->remove(path);
|
||||
return false;
|
||||
try {
|
||||
_assetLoader->remove(path);
|
||||
} catch (const ghoul::RuntimeError& e) {
|
||||
LERROR("Error removing asset: " << e.component << ": " << e.message);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetManager::tryInitializeAsset(Asset& asset) {
|
||||
|
||||
@@ -139,8 +139,6 @@ void ResourceSynchronization::begin() {
|
||||
void ResourceSynchronization::setState(State state) {
|
||||
_state = state;
|
||||
_callbackMutex.lock();
|
||||
|
||||
|
||||
std::vector<StateChangeCallback> callbacks;
|
||||
callbacks.reserve(_stateChangeCallbacks.size());
|
||||
for (const auto& it : _stateChangeCallbacks) {
|
||||
|
||||
Reference in New Issue
Block a user