Initialize requested assets when they are ready

This commit is contained in:
Emil Axelsson
2017-12-11 11:12:39 +01:00
parent 0396832ae5
commit e0504980ad
7 changed files with 64 additions and 75 deletions

View File

@@ -1,3 +1,3 @@
asset.request('keybindings')
asset.request('solarsystem')
asset.request('missions/newhorizons/spice/spice')
asset.require('missions/newhorizons/spice/spice')

View File

@@ -75,9 +75,6 @@ public:
std::string assetName() const;
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);
@@ -121,7 +118,6 @@ public:
std::string resolveLocalResource(std::string resourceName);
private:
void requiredAssetChangedState(std::shared_ptr<Asset> a);
void requestedAssetChangedState(std::shared_ptr<Asset> a);
void addRequestingAsset(std::shared_ptr<Asset> a);
void removeRequestingAsset(std::shared_ptr<Asset> a);
@@ -157,11 +153,6 @@ private:
// 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

@@ -25,7 +25,7 @@
#ifndef __OPENSPACE_CORE___ASSETLOADER___H__
#define __OPENSPACE_CORE___ASSETLOADER___H__
#include <openspace/scene/scenegraphnode.h>
#include <openspace/scene/asset.h>
#include <openspace/scripting/lualibrary.h>
#include <openspace/util/resourcesynchronization.h>
@@ -42,7 +42,6 @@
namespace openspace {
class Asset;
namespace assetloader {
int onInitialize(lua_State* state);
@@ -57,6 +56,11 @@ int noOperation(lua_State* state);
int exportAsset(lua_State* state);
} // namespace assetloader
class AssetStateChangeListener {
public:
virtual void assetStateChanged(std::shared_ptr<Asset> asset, Asset::State state) = 0;
};
class AssetLoader {
public:
/**
@@ -84,12 +88,6 @@ public:
*/
void remove(const std::string& identifier);
/**
* Remove the asset as a dependency on the root asset
* The asset is unloaded synchronously
*/
void remove(const Asset* asset);
/**
* Returns the asset identified by the identifier,
* if the asset is loaded. Otherwise return nullptr.
@@ -127,6 +125,11 @@ public:
std::string generateAssetPath(const std::string& baseDirectory,
const std::string& path) const;
void addAssetStateChangeListener(AssetStateChangeListener* listener);
void removeAssetStateChangeListener(AssetStateChangeListener* listener);
void assetStateChanged(std::shared_ptr<Asset> asset, Asset::State state);
private:
std::shared_ptr<Asset> require(const std::string& identifier);
@@ -179,6 +182,8 @@ private:
std::unordered_map<Asset*, std::map<Asset*, std::vector<int>>>
_onDependencyDeinitializationFunctionRefs;
std::vector<AssetStateChangeListener*> _assetStateChangeListeners;
int _assetsTableRef;
};

View File

@@ -51,7 +51,7 @@ class Asset;
* from the system if it is not a dependency of a loaded asset.
*/
class AssetManager {
class AssetManager : AssetStateChangeListener {
public:
AssetManager(
std::unique_ptr<AssetLoader> loader
@@ -64,12 +64,13 @@ public:
void removeAll();
std::shared_ptr<Asset> rootAsset();
void assetStateChanged(std::shared_ptr<Asset> asset, Asset::State state) override;
bool update();
scripting::LuaLibrary luaLibrary();
private:
std::shared_ptr<Asset> tryAddAsset(const std::string& path);
bool tryRemoveAsset(const std::string& path);
void assetStateChanged(std::shared_ptr<Asset> asset, Asset::State state);
std::unordered_map<std::string, bool> _pendingStateChangeCommands;
std::mutex _pendingInitializationsMutex;

View File

@@ -69,57 +69,34 @@ 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) {
if (_state == state) {
return;
}
_state = state;
std::shared_ptr<Asset> thisAsset = shared_from_this();
for (auto& requiringAsset : _requiringAssets) {
if (std::shared_ptr<Asset> a = requiringAsset.lock()) {
a->requiredAssetChangedState(shared_from_this());
a->requiredAssetChangedState(thisAsset);
}
}
for (auto& requestingAsset : _requestingAssets) {
if (std::shared_ptr<Asset> a = requestingAsset.lock()) {
a->requestedAssetChangedState(shared_from_this());
}
}
std::lock_guard<std::mutex> guard(_stateChangeCallbackMutex);
for (auto& cb : _stateChangeCallbacks) {
cb.second(state);
}
_loader->assetStateChanged(thisAsset, state);
}
void Asset::requiredAssetChangedState(std::shared_ptr<Asset> child) {
State childState = child->state();
if (childState == State::SyncResolved) {
if (isSyncResolveReady()) {
setState(State::SyncResolved);
}
}
else if (childState == State::SyncRejected) {
} else if (childState == State::SyncRejected) {
setState(State::SyncRejected);
}
}
void Asset::requestedAssetChangedState(std::shared_ptr<Asset> child) {
// TODO: implement this
}
void Asset::addSynchronization(std::shared_ptr<ResourceSynchronization> synchronization) {
{
std::lock_guard<std::mutex> guard(_synchronizationsMutex);
@@ -274,7 +251,7 @@ bool Asset::restartSynchronizations() {
}
float Asset::synchronizationProgress() {
std::vector<std::shared_ptr<Asset>> assets = subTreeAssets();
std::vector<std::shared_ptr<Asset>> assets = requiredSubTreeAssets();
size_t nTotalBytes = 0;
size_t nSyncedBytes = 0;
@@ -502,11 +479,13 @@ void Asset::addRequestingAsset(std::shared_ptr<Asset> parent) {
if (parentState == State::Synchronizing ||
parentState == State::SyncResolved ||
parentState == State::Initialized)
parentState == State::Initialized ||
parentState == State::InitializationFailed)
{
if (childState != State::Synchronizing ||
childState != State::SyncResolved ||
childState != State::Initialized)
if (childState != State::Synchronizing &&
childState != State::SyncResolved &&
childState != State::Initialized &&
childState != State::InitializationFailed)
{
startSynchronizations();
}

View File

@@ -121,7 +121,33 @@ std::string AssetLoader::generateAssetPath(const std::string& baseDirectory,
"." +
AssetFileSuffix);
}
void AssetLoader::addAssetStateChangeListener(AssetStateChangeListener* listener) {
const auto it = std::find(
_assetStateChangeListeners.begin(),
_assetStateChangeListeners.end(),
listener
);
if (it == _assetStateChangeListeners.end()) {
_assetStateChangeListeners.push_back(listener);
}
}
void AssetLoader::removeAssetStateChangeListener(AssetStateChangeListener* listener) {
_assetStateChangeListeners.erase(std::remove(
_assetStateChangeListeners.begin(),
_assetStateChangeListeners.end(),
listener
));
}
void AssetLoader::assetStateChanged(std::shared_ptr<Asset> asset, Asset::State state) {
for (auto& listener : _assetStateChangeListeners) {
listener->assetStateChanged(asset, state);
}
}
std::shared_ptr<Asset> AssetLoader::getAsset(std::string name) {
ghoul::filesystem::Directory directory = currentDirectory();
std::string path = generateAssetPath(directory, name);
@@ -217,14 +243,6 @@ std::shared_ptr<Asset> AssetLoader::add(const std::string& identifier) {
void AssetLoader::remove(const std::string& identifier) {
ghoul_assert(_assetStack.size() == 1, "Can only unload an asset from the root asset");
unrequest(identifier);
// TODO: Implement this
//_rootAsset->removeDependency(id);
}
void AssetLoader::remove(const Asset* asset) {
ghoul_assert(_assetStack.size() == 1, "Can only unload an asset from the root asset");
// TODO: Implement this
//_rootAsset->removeDependency(id);
}
std::shared_ptr<Asset> AssetLoader::has(const std::string& name) const {

View File

@@ -42,23 +42,14 @@ AssetManager::AssetManager(std::unique_ptr<AssetLoader> loader)
{}
void AssetManager::initialize() {
/*_addAssetCallbackHandle = _assetLoader->addAssetLoadCallback(
[this] (std::shared_ptr<Asset> a) {
a->addStateChangeCallback([a, this] (Asset::State state) {
assetStateChanged(a, state);
});
}
);*/
_assetLoader->addAssetStateChangeListener(this);
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);
_assetLoader->removeAssetStateChangeListener(this);
}
bool AssetManager::update() {
@@ -94,6 +85,10 @@ bool AssetManager::update() {
}
void AssetManager::assetStateChanged(std::shared_ptr<Asset> asset, Asset::State state) {
if (asset->requestingAssets().empty()) {
return;
}
if (rootAsset()->state() == Asset::State::Initialized) {
if (state == Asset::State::Loaded) {
asset->startSynchronizations();
@@ -156,7 +151,7 @@ scripting::LuaLibrary AssetManager::luaLibrary() {
std::shared_ptr<Asset> AssetManager::tryAddAsset(const std::string& path) {
try {
_assetLoader->add(path);
return _assetLoader->add(path);
} catch (const ghoul::RuntimeError& e) {
LERROR("Error adding asset: " << e.component << ": " << e.message);
}