mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-07 04:00:37 -06:00
Initialize requested assets when they are ready
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
asset.request('keybindings')
|
||||
asset.request('solarsystem')
|
||||
asset.request('missions/newhorizons/spice/spice')
|
||||
asset.require('missions/newhorizons/spice/spice')
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user