Callbacks for asset state changes

This commit is contained in:
Emil Axelsson
2017-11-17 00:15:54 +01:00
parent 436062381e
commit f3aeecaf23
16 changed files with 295 additions and 96 deletions

View File

@@ -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')

View File

@@ -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",

View File

@@ -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')

View File

@@ -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'))

View File

@@ -1,4 +1,4 @@
local AssetHelper = asset.import("assethelper")
local AssetHelper = asset.require("assethelper")
local syncedDirectory = asset.syncedResource({
Type = "HttpSynchronization",

View File

@@ -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;

View File

@@ -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 = {

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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();
/*

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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)));

View File

@@ -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) {

View File

@@ -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) {