mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-25 21:48:57 -05:00
Use shared pointers for assets
This commit is contained in:
@@ -20,7 +20,7 @@ asset.sync = {
|
||||
|
||||
|
||||
-- Simple sphere to represent the Sun
|
||||
asset.Sun = {
|
||||
local Sun = {
|
||||
Name = "Sun",
|
||||
Renderable = {
|
||||
Parent = sunParentName,
|
||||
@@ -41,7 +41,7 @@ asset.Sun = {
|
||||
}
|
||||
|
||||
-- Billboard to represent the sun
|
||||
asset.SunGlare = {
|
||||
local SunGlare = {
|
||||
Name = "SunGlare",
|
||||
Parent = sunParentName,
|
||||
Renderable = {
|
||||
@@ -55,9 +55,9 @@ asset.SunGlare = {
|
||||
}
|
||||
|
||||
-- Marker for the sun
|
||||
asset.SunMarker = {
|
||||
local SunMarker = {
|
||||
Name = "SunMarker",
|
||||
Parent = asset.Sun.Name,
|
||||
Parent = Sun.Name,
|
||||
Renderable = {
|
||||
Type = "RenderablePlane",
|
||||
Size = 3.0E11,
|
||||
@@ -75,7 +75,7 @@ asset.SunMarker = {
|
||||
}
|
||||
|
||||
assetHelper.registerSceneGraphNodes(asset, {
|
||||
asset.Sun,
|
||||
asset.SunGlare,
|
||||
asset.SunMarker
|
||||
Sun,
|
||||
SunGlare,
|
||||
SunMarker
|
||||
})
|
||||
|
||||
@@ -14,7 +14,7 @@ local SunIau = {
|
||||
Transform = {
|
||||
Translation = {
|
||||
Type = "SpiceTranslation",
|
||||
Body = "SUN",
|
||||
Target = "SUN",
|
||||
Observer = "SSB",
|
||||
},
|
||||
Rotation = {
|
||||
@@ -26,8 +26,8 @@ local SunIau = {
|
||||
}
|
||||
|
||||
assetHelper.registerSceneGraphNodes(asset, {
|
||||
asset.SolarSystemBarycenter,
|
||||
asset.SunIau
|
||||
SolarSystemBarycenter,
|
||||
SunIau
|
||||
})
|
||||
|
||||
asset.export("SolarSystemBarycenter", SolarSystemBarycenter)
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace ghoul::fontrendering { class FontManager; }
|
||||
namespace openspace {
|
||||
|
||||
class AssetLoader;
|
||||
class AssetSynchronizer;
|
||||
class ConfigurationManager;
|
||||
class DownloadManager;
|
||||
class GUI;
|
||||
@@ -123,6 +124,7 @@ public:
|
||||
WindowWrapper& windowWrapper();
|
||||
AssetLoader& assetLoader();
|
||||
ResourceSynchronizer& resourceSynchronizer();
|
||||
AssetSynchronizer& assetSynchronizer();
|
||||
ghoul::fontrendering::FontManager& fontManager();
|
||||
interaction::NavigationHandler& navigationHandler();
|
||||
interaction::KeyBindingManager& keyBindingManager();
|
||||
@@ -202,6 +204,7 @@ private:
|
||||
std::unique_ptr<interaction::NavigationHandler> _navigationHandler;
|
||||
std::unique_ptr<interaction::KeyBindingManager> _keyBindingManager;
|
||||
std::unique_ptr<ResourceSynchronizer> _resourceSynchronizer;
|
||||
std::unique_ptr<AssetSynchronizer> _assetSynchronizer;
|
||||
std::unique_ptr<scripting::ScriptEngine> _scriptEngine;
|
||||
std::unique_ptr<scripting::ScriptScheduler> _scriptScheduler;
|
||||
std::unique_ptr<VirtualPropertyManager> _virtualPropertyManager;
|
||||
|
||||
@@ -33,13 +33,17 @@
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <iterator>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class AssetLoader;
|
||||
|
||||
class Asset {
|
||||
class Asset : public std::enable_shared_from_this<Asset> {
|
||||
public:
|
||||
using Optional = std::pair<Asset*, bool>;
|
||||
using Optional = std::pair<std::shared_ptr<Asset>, bool>;
|
||||
|
||||
enum class ReadyState : unsigned int {
|
||||
Loaded,
|
||||
@@ -67,30 +71,29 @@ public:
|
||||
|
||||
void addSynchronization(std::shared_ptr<ResourceSynchronization> synchronization);
|
||||
std::vector<std::shared_ptr<ResourceSynchronization>> synchronizations();
|
||||
std::vector<std::shared_ptr<ResourceSynchronization>> getSynchronizationsRecursive();
|
||||
|
||||
std::vector<std::shared_ptr<Asset>> allActiveAssets();
|
||||
std::vector<std::shared_ptr<Asset>> allAssets();
|
||||
|
||||
bool isInitReady() const;
|
||||
void initialize();
|
||||
void deinitialize();
|
||||
|
||||
bool hasRequiredDependency(const Asset* asset) const;
|
||||
void addRequiredDependency(Asset* asset);
|
||||
void addRequiredDependency(std::shared_ptr<Asset> asset);
|
||||
void removeRequiredDependency(Asset* asset);
|
||||
void removeRequiredDependency(const std::string& assetId);
|
||||
|
||||
bool hasDependants() const;
|
||||
bool hasInitializedDependants() const;
|
||||
|
||||
std::vector<Asset*> optionalAssets() const;
|
||||
std::vector<std::shared_ptr<Asset>> optionalAssets() const;
|
||||
bool hasOptionalDependency(const Asset* asset) const;
|
||||
bool hasEnabledOptionalDependency(const Asset* asset) const;
|
||||
void setOptionalDependencyEnabled(Asset* asset, bool enabled);
|
||||
void addOptionalDependency(Asset* asset, bool enabled);
|
||||
void addOptionalDependency(std::shared_ptr<Asset> asset, bool enabled);
|
||||
void removeOptionalDependency(Asset* asset);
|
||||
|
||||
void dependantDidInitialize(Asset* dependant);
|
||||
void dependantWillDeinitialize(Asset* dependant);
|
||||
|
||||
std::string resolveLocalResource(std::string resourceName);
|
||||
std::string resolveSyncedResource(std::string resourceName);
|
||||
private:
|
||||
@@ -105,16 +108,16 @@ private:
|
||||
std::optional<std::string> _assetPath;
|
||||
|
||||
// Required dependencies
|
||||
std::vector<Asset*> _requiredDependencies;
|
||||
std::vector<std::shared_ptr<Asset>> _requiredDependencies;
|
||||
|
||||
// Assets that refers to this asset as an required dependency
|
||||
std::vector<Asset*> _requiredDependants;
|
||||
std::vector<std::weak_ptr<Asset>> _requiredDependants;
|
||||
|
||||
// Optional dependencies
|
||||
std::vector<Optional> _optionalDependencies;
|
||||
|
||||
// Assets that refers to this asset as an optional dependency
|
||||
std::vector<Asset*> _optionalDependants;
|
||||
std::vector<std::weak_ptr<Asset>> _optionalDependants;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -78,14 +78,14 @@ public:
|
||||
* - Import one asset
|
||||
* - Unimport all other assets
|
||||
*/
|
||||
Asset* loadSingleAsset(const std::string& identifier);
|
||||
std::shared_ptr<Asset> loadSingleAsset(const std::string& identifier);
|
||||
|
||||
/**
|
||||
* Import an asset:
|
||||
* Add the asset as an optional on the root asset
|
||||
* The asset is imported synchronously
|
||||
*/
|
||||
Asset* importAsset(const std::string& identifier);
|
||||
std::shared_ptr<Asset> importAsset(const std::string& identifier);
|
||||
|
||||
/**
|
||||
* Unimport an asset:
|
||||
@@ -107,13 +107,18 @@ public:
|
||||
/**
|
||||
* Return the root asset
|
||||
*/
|
||||
Asset* rootAsset() const;
|
||||
std::shared_ptr<Asset> rootAsset() const;
|
||||
|
||||
/**
|
||||
* Return the sync root directory
|
||||
*/
|
||||
const std::string& syncRootDirectory();
|
||||
|
||||
/**
|
||||
* Return the asset root directory
|
||||
*/
|
||||
const std::string& assetRootDirectory();
|
||||
|
||||
void callOnInitialize(Asset* asset);
|
||||
|
||||
void callOnDeinitialize(Asset* asset);
|
||||
@@ -125,13 +130,13 @@ public:
|
||||
std::string generateAssetPath(const std::string& baseDirectory, const std::string& path) const;
|
||||
|
||||
private:
|
||||
Asset* importRequiredDependency(const std::string& identifier);
|
||||
Asset* importOptionalDependency(const std::string& identifier, bool enabled = true);
|
||||
Asset* loadAsset(std::string name);
|
||||
Asset* getAsset(std::string name);
|
||||
std::shared_ptr<Asset> importRequiredDependency(const std::string& identifier);
|
||||
std::shared_ptr<Asset> importOptionalDependency(const std::string& identifier, bool enabled = true);
|
||||
std::shared_ptr<Asset> loadAsset(std::string name);
|
||||
std::shared_ptr<Asset> getAsset(std::string name);
|
||||
ghoul::filesystem::Directory currentDirectory();
|
||||
|
||||
void pushAsset(Asset* asset);
|
||||
void pushAsset(std::shared_ptr<Asset> asset);
|
||||
void popAsset();
|
||||
void updateLuaGlobals();
|
||||
void addLuaDependencyTable(Asset* dependant, Asset* dependency);
|
||||
@@ -160,9 +165,9 @@ private:
|
||||
friend int assetloader::resolveSyncedResource(lua_State* state);
|
||||
friend int assetloader::exportAsset(lua_State* state);
|
||||
|
||||
std::unique_ptr<Asset> _rootAsset;
|
||||
std::map<std::string, std::unique_ptr<Asset>> _importedAssets;
|
||||
std::vector<Asset*> _assetStack;
|
||||
std::shared_ptr<Asset> _rootAsset;
|
||||
std::map<std::string, std::shared_ptr<Asset>> _importedAssets;
|
||||
std::vector<std::shared_ptr<Asset>> _assetStack;
|
||||
|
||||
AssetSynchronizer* _assetSynchronizer;
|
||||
std::string _assetRootDirectory;
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
|
||||
#include <openspace/scene/asset.h>
|
||||
#include <openspace/scene/assetloader.h>
|
||||
#include <openspace/scene/assetsynchronizer.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/rotation.h>
|
||||
#include <openspace/scene/scale.h>
|
||||
@@ -146,6 +147,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName,
|
||||
, _parallelConnection(new ParallelConnection)
|
||||
, _renderEngine(new RenderEngine)
|
||||
, _resourceSynchronizer(new ResourceSynchronizer)
|
||||
, _assetSynchronizer(new AssetSynchronizer(_resourceSynchronizer.get()))
|
||||
, _settingsEngine(new SettingsEngine)
|
||||
, _syncEngine(std::make_unique<SyncEngine>(4096))
|
||||
, _timeManager(new TimeManager)
|
||||
@@ -595,7 +597,15 @@ void OpenSpaceEngine::loadSingleAsset(const std::string& assetPath) {
|
||||
|
||||
_scene = std::make_unique<Scene>();
|
||||
_renderEngine->setScene(_scene.get());
|
||||
_assetLoader->loadSingleAsset(assetPath);
|
||||
std::shared_ptr<Asset> asset = _assetLoader->loadSingleAsset(assetPath);
|
||||
std::vector<std::shared_ptr<Asset>> assets = asset->allActiveAssets();
|
||||
for (const auto& asset : assets) {
|
||||
_assetSynchronizer->addAsset(asset);
|
||||
}
|
||||
LINFO("SYNCS");
|
||||
|
||||
asset->initialize();
|
||||
|
||||
} catch (const ghoul::FileNotFoundError& e) {
|
||||
LERRORC(e.component, e.message);
|
||||
return;
|
||||
@@ -1481,6 +1491,11 @@ ResourceSynchronizer & OpenSpaceEngine::resourceSynchronizer() {
|
||||
return *_resourceSynchronizer;
|
||||
}
|
||||
|
||||
AssetSynchronizer & OpenSpaceEngine::assetSynchronizer() {
|
||||
ghoul_assert(_assetSynchronizer, "Asset Synchronizer must not be nullptr");
|
||||
return *_assetSynchronizer;
|
||||
}
|
||||
|
||||
ghoul::fontrendering::FontManager& OpenSpaceEngine::fontManager() {
|
||||
ghoul_assert(_fontManager, "Font Manager must not be nullptr");
|
||||
return *_fontManager;
|
||||
|
||||
+76
-39
@@ -59,7 +59,7 @@ std::string Asset::resolveLocalResource(std::string resourceName) {
|
||||
|
||||
std::string Asset::syncDirectory() const {
|
||||
std::string currentAssetDirectory = assetDirectory();
|
||||
std::string rootAssetDirectory = loader()->syncRootDirectory();
|
||||
std::string rootAssetDirectory = loader()->assetRootDirectory();
|
||||
std::string relativePath = FileSys.relativePath(currentAssetDirectory,
|
||||
rootAssetDirectory);
|
||||
|
||||
@@ -67,7 +67,7 @@ std::string Asset::syncDirectory() const {
|
||||
ghoul::filesystem::FileSystem::PathSeparator +
|
||||
relativePath +
|
||||
ghoul::filesystem::FileSystem::PathSeparator +
|
||||
assetName();
|
||||
ghoul::filesystem::File(_assetPath.value()).baseName();
|
||||
}
|
||||
|
||||
Asset::ReadyState Asset::readyState() const {
|
||||
@@ -78,6 +78,41 @@ void Asset::addSynchronization(std::shared_ptr<ResourceSynchronization> synchron
|
||||
_synchronizations.push_back(synchronization);
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<ResourceSynchronization>> Asset::synchronizations()
|
||||
{
|
||||
return _synchronizations;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Asset>> Asset::allAssets() {
|
||||
std::set<std::shared_ptr<Asset>> assets({ shared_from_this() });
|
||||
for (auto& dep : _requiredDependencies) {
|
||||
std::vector<std::shared_ptr<Asset>> depAssets = dep->allActiveAssets();
|
||||
std::copy(depAssets.begin(), depAssets.end(), std::inserter(assets, assets.end()));
|
||||
}
|
||||
for (auto& dep : _optionalDependencies) {
|
||||
std::vector<std::shared_ptr<Asset>> depAssets = dep.first->allActiveAssets();
|
||||
std::copy(depAssets.begin(), depAssets.end(), std::inserter(assets, assets.end()));
|
||||
}
|
||||
std::vector<std::shared_ptr<Asset>> assetVector(assets.begin(), assets.end());
|
||||
return assetVector;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Asset >> Asset::allActiveAssets() {
|
||||
std::set<std::shared_ptr<Asset>> assets({ shared_from_this() });
|
||||
for (auto& dep : _requiredDependencies) {
|
||||
std::vector<std::shared_ptr<Asset>> depAssets = dep->allActiveAssets();
|
||||
std::copy(depAssets.begin(), depAssets.end(), std::inserter(assets, assets.end()));
|
||||
}
|
||||
for (auto& dep : _optionalDependencies) {
|
||||
if (dep.second) {
|
||||
std::vector<std::shared_ptr<Asset>> depAssets = dep.first->allActiveAssets();
|
||||
std::copy(depAssets.begin(), depAssets.end(), std::inserter(assets, assets.end()));
|
||||
}
|
||||
}
|
||||
std::vector<std::shared_ptr<Asset>> assetVector(assets.begin(), assets.end());
|
||||
return assetVector;
|
||||
}
|
||||
|
||||
bool Asset::isInitReady() const {
|
||||
// An asset is ready for initialization if all synchronizations are resolved
|
||||
// and all its required dependencies are ready for initialization.
|
||||
@@ -117,7 +152,7 @@ void Asset::initialize() {
|
||||
|
||||
// Notify dependencies
|
||||
for (auto& dependency : _requiredDependencies) {
|
||||
dependency->dependantDidInitialize(this);
|
||||
loader()->callOnDependantInitialize(dependency.get(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +163,7 @@ void Asset::deinitialize() {
|
||||
|
||||
// Notify dependencies
|
||||
for (auto& dependency : _requiredDependencies) {
|
||||
dependency->dependantWillDeinitialize(this);
|
||||
loader()->callOnDependantDeinitialize(dependency.get(), this);
|
||||
}
|
||||
|
||||
// Call onDeinitialize in Lua
|
||||
@@ -170,21 +205,23 @@ std::string Asset::assetName() const {
|
||||
return _assetName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
AssetLoader* Asset::loader() const {
|
||||
return _loader;
|
||||
}
|
||||
|
||||
bool Asset::hasRequiredDependency(const Asset* asset) const {
|
||||
const auto it = std::find(_requiredDependencies.begin(),
|
||||
_requiredDependencies.end(),
|
||||
asset);
|
||||
const auto it = std::find_if(
|
||||
_requiredDependencies.begin(),
|
||||
_requiredDependencies.end(),
|
||||
[asset](std::shared_ptr<Asset> dep) {
|
||||
return dep.get() == asset;
|
||||
}
|
||||
);
|
||||
|
||||
return it != _requiredDependencies.end();
|
||||
}
|
||||
|
||||
void Asset::addRequiredDependency(Asset* dependency) {
|
||||
void Asset::addRequiredDependency(std::shared_ptr<Asset> dependency) {
|
||||
if (_readyState == Asset::ReadyState::Initialized) {
|
||||
// TODO: Throw: cannot add dep while asset is initialized.
|
||||
return;
|
||||
@@ -200,22 +237,26 @@ void Asset::addRequiredDependency(Asset* dependency) {
|
||||
}
|
||||
|
||||
_requiredDependencies.push_back(dependency);
|
||||
dependency->_requiredDependants.push_back(this);
|
||||
dependency->_requiredDependants.push_back(shared_from_this());
|
||||
|
||||
//addPropertySubOwner(dependency);
|
||||
}
|
||||
|
||||
void Asset::removeRequiredDependency(Asset* dependency) {
|
||||
_requiredDependencies.erase(
|
||||
std::remove(_requiredDependencies.begin(),
|
||||
std::remove_if(_requiredDependencies.begin(),
|
||||
_requiredDependencies.end(),
|
||||
dependency),
|
||||
|
||||
[dependency](std::shared_ptr<Asset> asset) {
|
||||
return asset.get() == dependency;
|
||||
}
|
||||
),
|
||||
_requiredDependencies.end()
|
||||
);
|
||||
std::vector<Asset*>& dependants = dependency->_requiredDependants;
|
||||
std::vector<std::weak_ptr<Asset>>& dependants = dependency->_requiredDependants;
|
||||
dependants.erase(
|
||||
std::remove(dependants.begin(), dependants.end(), this),
|
||||
std::remove_if(dependants.begin(), dependants.end(), [this](std::weak_ptr<Asset> asset) {
|
||||
return asset.lock().get() == this;
|
||||
}),
|
||||
dependants.end()
|
||||
);
|
||||
|
||||
@@ -228,33 +269,27 @@ void Asset::removeRequiredDependency(const std::string& assetId) {
|
||||
auto dep = std::find_if(
|
||||
_requiredDependencies.begin(),
|
||||
_requiredDependencies.end(),
|
||||
[&assetId](const Asset* d) {
|
||||
[&assetId](const std::shared_ptr<Asset>& d) {
|
||||
return d->id() == assetId;
|
||||
});
|
||||
|
||||
if (dep != _requiredDependencies.end()) {
|
||||
removeRequiredDependency(*dep);
|
||||
removeRequiredDependency(dep->get());
|
||||
} else {
|
||||
LERROR("No such dependency '" << assetId << "'");
|
||||
}
|
||||
}
|
||||
|
||||
void Asset::dependantDidInitialize(Asset* dependant) {
|
||||
loader()->callOnDependantInitialize(this, dependant);
|
||||
}
|
||||
|
||||
void Asset::dependantWillDeinitialize(Asset* dependant) {
|
||||
loader()->callOnDependantDeinitialize(this, dependant);
|
||||
}
|
||||
|
||||
bool Asset::hasDependants() const {
|
||||
for (const auto& dependant : _requiredDependants) {
|
||||
if (dependant->hasRequiredDependency(this)) {
|
||||
std::shared_ptr<Asset> d = dependant.lock();
|
||||
if (d && d->hasRequiredDependency(this)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (const auto& dependant : _optionalDependants) {
|
||||
if (dependant->hasEnabledOptionalDependency(this)) {
|
||||
std::shared_ptr<Asset> d = dependant.lock();
|
||||
if (d && d->hasEnabledOptionalDependency(this)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -263,15 +298,17 @@ bool Asset::hasDependants() const {
|
||||
|
||||
bool Asset::hasInitializedDependants() const {
|
||||
for (const auto& dependant : _requiredDependants) {
|
||||
if (dependant->readyState() == Asset::ReadyState::Initialized &&
|
||||
dependant->hasRequiredDependency(this))
|
||||
std::shared_ptr<Asset> d = dependant.lock();
|
||||
if (d && d->readyState() == Asset::ReadyState::Initialized &&
|
||||
d->hasRequiredDependency(this))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (const auto& dependant : _optionalDependants) {
|
||||
if (dependant->readyState() == Asset::ReadyState::Initialized &&
|
||||
dependant->hasEnabledOptionalDependency(this))
|
||||
std::shared_ptr<Asset> d = dependant.lock();
|
||||
if (d && d->readyState() == Asset::ReadyState::Initialized &&
|
||||
d->hasEnabledOptionalDependency(this))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -279,8 +316,8 @@ bool Asset::hasInitializedDependants() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<Asset*> Asset::optionalAssets() const {
|
||||
std::vector<Asset*> assets(_optionalDependencies.size());
|
||||
std::vector<std::shared_ptr<Asset>> Asset::optionalAssets() const {
|
||||
std::vector<std::shared_ptr<Asset>> assets(_optionalDependencies.size());
|
||||
std::transform(
|
||||
_optionalDependencies.begin(),
|
||||
_optionalDependencies.end(),
|
||||
@@ -297,7 +334,7 @@ bool Asset::hasOptionalDependency(const Asset* asset) const {
|
||||
_optionalDependencies.begin(),
|
||||
_optionalDependencies.end(),
|
||||
[&asset](const Optional& o) {
|
||||
return o.first == asset;
|
||||
return o.first.get() == asset;
|
||||
}
|
||||
);
|
||||
return it != _optionalDependencies.end();
|
||||
@@ -308,7 +345,7 @@ bool Asset::hasEnabledOptionalDependency(const Asset* asset) const {
|
||||
_optionalDependencies.begin(),
|
||||
_optionalDependencies.end(),
|
||||
[&asset](const Optional& o) {
|
||||
return o.first == asset && o.second;
|
||||
return o.first.get() == asset && o.second;
|
||||
}
|
||||
);
|
||||
return it != _optionalDependencies.end();
|
||||
@@ -319,7 +356,7 @@ void Asset::setOptionalDependencyEnabled(Asset* asset, bool enabled) {
|
||||
_optionalDependencies.begin(),
|
||||
_optionalDependencies.end(),
|
||||
[&asset](const Optional& o) {
|
||||
return o.first == asset;
|
||||
return o.first.get() == asset;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -334,7 +371,7 @@ void Asset::removeOptionalDependency(Asset* asset) {
|
||||
_optionalDependencies.begin(),
|
||||
_optionalDependencies.end(),
|
||||
[&asset](Optional& o) {
|
||||
return o.first == asset;
|
||||
return o.first.get() == asset;
|
||||
}
|
||||
),
|
||||
_optionalDependencies.end()
|
||||
@@ -342,7 +379,7 @@ void Asset::removeOptionalDependency(Asset* asset) {
|
||||
// TODO: Update and validate
|
||||
}
|
||||
|
||||
void Asset::addOptionalDependency(Asset* asset, bool enabled) {
|
||||
void Asset::addOptionalDependency(std::shared_ptr<Asset> asset, bool enabled) {
|
||||
_optionalDependencies.push_back(std::make_pair(asset, enabled));
|
||||
// TODO: Update and validate
|
||||
}
|
||||
|
||||
+61
-45
@@ -77,11 +77,11 @@ AssetLoader::AssetLoader(
|
||||
std::string syncRootDirectory
|
||||
)
|
||||
: _luaState(&luaState)
|
||||
, _rootAsset(std::make_unique<Asset>(this))
|
||||
, _rootAsset(std::make_shared<Asset>(this))
|
||||
, _assetRootDirectory(assetRootDirectory)
|
||||
, _syncRootDirectory(std::move(syncRootDirectory))
|
||||
{
|
||||
pushAsset(_rootAsset.get());
|
||||
pushAsset(_rootAsset);
|
||||
|
||||
// Create _assets table.
|
||||
lua_newtable(*_luaState);
|
||||
@@ -91,12 +91,10 @@ AssetLoader::AssetLoader(
|
||||
AssetLoader::~AssetLoader() {
|
||||
}
|
||||
|
||||
Asset* AssetLoader::loadAsset(std::string path) {
|
||||
std::unique_ptr<Asset> asset = std::make_unique<Asset>(this, path);
|
||||
std::shared_ptr<Asset> AssetLoader::loadAsset(std::string path) {
|
||||
std::shared_ptr<Asset> asset = std::make_shared<Asset>(this, path);
|
||||
|
||||
Asset* rawAsset = asset.get();
|
||||
|
||||
pushAsset(rawAsset);
|
||||
pushAsset(asset);
|
||||
ghoul::OnScopeExit e([this]() {
|
||||
popAsset();
|
||||
});
|
||||
@@ -106,9 +104,9 @@ Asset* AssetLoader::loadAsset(std::string path) {
|
||||
}
|
||||
|
||||
ghoul::lua::runScriptFile(*_luaState, path);
|
||||
_importedAssets.emplace(rawAsset->id(), std::move(asset));
|
||||
_importedAssets.emplace(asset->id(), asset);
|
||||
|
||||
return rawAsset;
|
||||
return asset;
|
||||
}
|
||||
|
||||
std::string AssetLoader::generateAssetPath(const std::string& baseDirectory,
|
||||
@@ -125,7 +123,7 @@ std::string AssetLoader::generateAssetPath(const std::string& baseDirectory,
|
||||
AssetFileSuffix);
|
||||
}
|
||||
|
||||
Asset* AssetLoader::getAsset(std::string name) {
|
||||
std::shared_ptr<Asset> AssetLoader::getAsset(std::string name) {
|
||||
ghoul::filesystem::Directory directory = currentDirectory();
|
||||
std::string path = generateAssetPath(directory, name);
|
||||
|
||||
@@ -134,7 +132,7 @@ Asset* AssetLoader::getAsset(std::string name) {
|
||||
|
||||
return it == _importedAssets.end() ?
|
||||
loadAsset(path) :
|
||||
it->second.get();
|
||||
it->second;
|
||||
}
|
||||
|
||||
int AssetLoader::onInitializeLua(Asset* asset) {
|
||||
@@ -180,16 +178,16 @@ int AssetLoader::addSynchronizationLua(Asset* asset) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Asset* AssetLoader::importRequiredDependency(const std::string& name) {
|
||||
Asset* asset = getAsset(name);
|
||||
Asset* dependant = _assetStack.back();
|
||||
std::shared_ptr<Asset> AssetLoader::importRequiredDependency(const std::string& name) {
|
||||
std::shared_ptr<Asset> asset = getAsset(name);
|
||||
std::shared_ptr<Asset> dependant = _assetStack.back();
|
||||
dependant->addRequiredDependency(asset);
|
||||
return asset;
|
||||
}
|
||||
|
||||
Asset* AssetLoader::importOptionalDependency(const std::string& name, bool enabled) {
|
||||
Asset* asset = getAsset(name);
|
||||
Asset* owner = _assetStack.back();
|
||||
std::shared_ptr<Asset> AssetLoader::importOptionalDependency(const std::string& name, bool enabled) {
|
||||
std::shared_ptr<Asset> asset = getAsset(name);
|
||||
std::shared_ptr<Asset> owner = _assetStack.back();
|
||||
owner->addOptionalDependency(asset, enabled);
|
||||
return asset;
|
||||
}
|
||||
@@ -202,20 +200,20 @@ ghoul::filesystem::Directory AssetLoader::currentDirectory() {
|
||||
}
|
||||
}
|
||||
|
||||
Asset* AssetLoader::loadSingleAsset(const std::string& identifier) {
|
||||
Asset* imported = importOptionalDependency(identifier, true);
|
||||
std::vector<Asset*> optionals = _rootAsset->optionalAssets();
|
||||
std::shared_ptr<Asset> AssetLoader::loadSingleAsset(const std::string& identifier) {
|
||||
std::shared_ptr<Asset> imported = importOptionalDependency(identifier, true);
|
||||
std::vector<std::shared_ptr<Asset>> optionals = _rootAsset->optionalAssets();
|
||||
|
||||
// Remove all other optionals
|
||||
for (auto& optional : optionals) {
|
||||
if (optional != imported) {
|
||||
_rootAsset->removeOptionalDependency(optional);
|
||||
_rootAsset->removeOptionalDependency(optional.get());
|
||||
}
|
||||
}
|
||||
return imported;
|
||||
}
|
||||
|
||||
Asset* AssetLoader::importAsset(const std::string & identifier) {
|
||||
std::shared_ptr<Asset> AssetLoader::importAsset(const std::string & identifier) {
|
||||
ghoul_assert(_assetStack.size() == 1, "Can only import an asset from the root asset");
|
||||
return importOptionalDependency(identifier);
|
||||
}
|
||||
@@ -233,19 +231,26 @@ ghoul::lua::LuaState* AssetLoader::luaState() {
|
||||
return _luaState;
|
||||
}
|
||||
|
||||
Asset* AssetLoader::rootAsset() const {
|
||||
return _rootAsset.get();
|
||||
std::shared_ptr<Asset> AssetLoader::rootAsset() const {
|
||||
return _rootAsset;
|
||||
}
|
||||
|
||||
const std::string& AssetLoader::syncRootDirectory() {
|
||||
return _syncRootDirectory;
|
||||
}
|
||||
|
||||
const std::string & AssetLoader::assetRootDirectory()
|
||||
{
|
||||
return _assetRootDirectory;
|
||||
}
|
||||
|
||||
void AssetLoader::callOnInitialize(Asset* asset) {
|
||||
for (int init : _onInitializationFunctionRefs[asset]) {
|
||||
lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, init);
|
||||
if (lua_pcall(*_luaState, 0, 0, 0) != LUA_OK) {
|
||||
throw ghoul::lua::LuaRuntimeException(luaL_checkstring(*_luaState, -1));
|
||||
throw ghoul::lua::LuaRuntimeException(
|
||||
"When initializing " + asset->assetFilePath() + ": " + luaL_checkstring(*_luaState, -1)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,7 +260,9 @@ void AssetLoader::callOnDeinitialize(Asset * 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) {
|
||||
throw ghoul::lua::LuaRuntimeException(luaL_checkstring(*_luaState, -1));
|
||||
throw ghoul::lua::LuaRuntimeException(
|
||||
"When deinitializing " + asset->assetFilePath() + ": " + luaL_checkstring(*_luaState, -1)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -264,7 +271,10 @@ void AssetLoader::callOnDependantInitialize(Asset* asset, Asset* dependant) {
|
||||
for (int init : _onDependencyInitializationFunctionRefs[dependant][asset]) {
|
||||
lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, init);
|
||||
if (lua_pcall(*_luaState, 0, 0, 0) != LUA_OK) {
|
||||
throw ghoul::lua::LuaRuntimeException(luaL_checkstring(*_luaState, -1));
|
||||
throw ghoul::lua::LuaRuntimeException(
|
||||
"When initializing dependency " + dependant->assetFilePath() + " -> " +
|
||||
asset->assetFilePath() + ": " + luaL_checkstring(*_luaState, -1)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -274,7 +284,10 @@ void AssetLoader::callOnDependantDeinitialize(Asset* asset, Asset* dependant) {
|
||||
for (auto it = funs.rbegin(); it != funs.rend(); it++) {
|
||||
lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, *it);
|
||||
if (lua_pcall(*_luaState, 0, 0, 0) != LUA_OK) {
|
||||
throw ghoul::lua::LuaRuntimeException(luaL_checkstring(*_luaState, -1));
|
||||
throw ghoul::lua::LuaRuntimeException(
|
||||
"When deinitializing dependency " + dependant->assetFilePath() + " -> " +
|
||||
asset->assetFilePath() + ": " + luaL_checkstring(*_luaState, -1)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -305,10 +318,14 @@ int AssetLoader::resolveSyncedResourceLua(Asset* asset) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void AssetLoader::pushAsset(Asset* asset) {
|
||||
void AssetLoader::pushAsset(std::shared_ptr<Asset> asset) {
|
||||
if (std::find(_assetStack.begin(), _assetStack.end(), asset) != _assetStack.end()) {
|
||||
throw ghoul::lua::LuaRuntimeException("Circular inclusion of assets.");
|
||||
}
|
||||
|
||||
_assetStack.push_back(asset);
|
||||
|
||||
if (asset == _rootAsset.get()) {
|
||||
if (asset == _rootAsset) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -354,49 +371,49 @@ void AssetLoader::pushAsset(Asset* asset) {
|
||||
|
||||
// Register local resource function
|
||||
// string localResource(string path)
|
||||
lua_pushlightuserdata(*_luaState, asset);
|
||||
lua_pushlightuserdata(*_luaState, asset.get());
|
||||
lua_pushcclosure(*_luaState, &assetloader::resolveLocalResource, 1);
|
||||
lua_setfield(*_luaState, assetTableIndex, LocalResourceFunctionName);
|
||||
|
||||
// Register synced resource function
|
||||
// string syncedResource(string path)
|
||||
lua_pushlightuserdata(*_luaState, asset);
|
||||
lua_pushlightuserdata(*_luaState, asset.get());
|
||||
lua_pushcclosure(*_luaState, &assetloader::resolveSyncedResource, 1);
|
||||
lua_setfield(*_luaState, assetTableIndex, SyncedResourceFunctionName);
|
||||
|
||||
// Register import-dependency function
|
||||
// Asset, Dependency import(string path)
|
||||
lua_pushlightuserdata(*_luaState, asset);
|
||||
lua_pushlightuserdata(*_luaState, asset.get());
|
||||
lua_pushcclosure(*_luaState, &assetloader::importRequiredDependency, 1);
|
||||
lua_setfield(*_luaState, assetTableIndex, ImportRequiredDependencyFunctionName);
|
||||
|
||||
// Register import-optional function
|
||||
// Asset, Dependency importOptional(string path)
|
||||
lua_pushlightuserdata(*_luaState, asset);
|
||||
lua_pushlightuserdata(*_luaState, asset.get());
|
||||
lua_pushcclosure(*_luaState, &assetloader::importOptionalDependency, 1);
|
||||
lua_setfield(*_luaState, assetTableIndex, ImportOptionalDependencyFunctionName);
|
||||
|
||||
// Register export-dependency function
|
||||
// export(string key, any value)
|
||||
lua_pushlightuserdata(*_luaState, asset);
|
||||
lua_pushlightuserdata(*_luaState, asset.get());
|
||||
lua_pushcclosure(*_luaState, &assetloader::exportAsset, 1);
|
||||
lua_setfield(*_luaState, assetTableIndex, ExportFunctionName);
|
||||
|
||||
// Register onInitialize function
|
||||
// void onInitialize(function<void()> initializationFunction)
|
||||
lua_pushlightuserdata(*_luaState, asset);
|
||||
lua_pushlightuserdata(*_luaState, asset.get());
|
||||
lua_pushcclosure(*_luaState, &assetloader::onInitialize, 1);
|
||||
lua_setfield(*_luaState, assetTableIndex, OnInitializeFunctionName);
|
||||
|
||||
// Register onDeinitialize function
|
||||
// void onDeinitialize(function<void()> deinitializationFunction)
|
||||
lua_pushlightuserdata(*_luaState, asset);
|
||||
lua_pushlightuserdata(*_luaState, asset.get());
|
||||
lua_pushcclosure(*_luaState, &assetloader::onDeinitialize, 1);
|
||||
lua_setfield(*_luaState, assetTableIndex, OnDeinitializeFunctionName);
|
||||
|
||||
// Register addSynchronization function
|
||||
// void addSynchronization(table synchronization)
|
||||
lua_pushlightuserdata(*_luaState, asset);
|
||||
lua_pushlightuserdata(*_luaState, asset.get());
|
||||
lua_pushcclosure(*_luaState, &assetloader::addSynchronization, 1);
|
||||
lua_setfield(*_luaState, assetTableIndex, AddSynchronizationFunctionName);
|
||||
|
||||
@@ -422,10 +439,9 @@ void AssetLoader::popAsset() {
|
||||
|
||||
void AssetLoader::updateLuaGlobals() {
|
||||
// Set `asset` lua global to point to the current asset table
|
||||
std::shared_ptr<Asset> asset = _assetStack.back();
|
||||
|
||||
Asset* asset = _assetStack.back();
|
||||
|
||||
if (asset == _rootAsset.get()) {
|
||||
if (asset == _rootAsset) {
|
||||
lua_pushnil(*_luaState);
|
||||
lua_setglobal(*_luaState, AssetGlobalVariableName);
|
||||
return;
|
||||
@@ -443,13 +459,13 @@ int AssetLoader::importRequiredDependencyLua(Asset* dependant) {
|
||||
|
||||
std::string assetName = luaL_checkstring(*_luaState, 1);
|
||||
|
||||
Asset* dependency = importRequiredDependency(assetName);
|
||||
std::shared_ptr<Asset> dependency = importRequiredDependency(assetName);
|
||||
|
||||
if (!dependency) {
|
||||
return luaL_error(*_luaState, "Asset '%s' not found", assetName.c_str());
|
||||
}
|
||||
|
||||
addLuaDependencyTable(dependant, dependency);
|
||||
addLuaDependencyTable(dependant, dependency.get());
|
||||
|
||||
// Get the exports table
|
||||
lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef);
|
||||
@@ -476,13 +492,13 @@ int AssetLoader::importOptionalDependencyLua(Asset* dependant) {
|
||||
std::string assetName = luaL_checkstring(*_luaState, 1);
|
||||
bool enabled = lua_toboolean(*_luaState, 2);
|
||||
|
||||
Asset* dependency = importOptionalDependency(assetName, enabled);
|
||||
std::shared_ptr<Asset> dependency = importOptionalDependency(assetName, enabled);
|
||||
|
||||
if (!dependency) {
|
||||
return luaL_error(*_luaState, "Asset '%s' not found", assetName.c_str());
|
||||
}
|
||||
|
||||
addLuaDependencyTable(dependant, dependency);
|
||||
addLuaDependencyTable(dependant, dependency.get());
|
||||
|
||||
// Get the exports table
|
||||
lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef);
|
||||
|
||||
Reference in New Issue
Block a user