Merge pull request #499 from OpenSpace/feature/fix-torrent-bug

Fix asset bugs
This commit is contained in:
Alexander Bock
2018-02-12 09:39:51 -05:00
committed by GitHub
28 changed files with 345 additions and 79 deletions

View File

@@ -29,6 +29,7 @@
#include <openspace/util/keys.h>
#include <openspace/util/mouse.h>
#include <ghoul/glm.h>
#include <ghoul/misc/assert.h>
#include <functional>
#include <memory>

View File

@@ -36,6 +36,7 @@
#include <openspace/util/keys.h>
#include <ghoul/misc/boolean.h>
#include <ghoul/misc/assert.h>
namespace openspace {
class Camera;

View File

@@ -80,6 +80,7 @@ public:
State state() const;
void addSynchronization(std::shared_ptr<ResourceSynchronization> synchronization);
void clearSynchronizations();
std::vector<std::shared_ptr<ResourceSynchronization>> ownSynchronizations() const;
void syncStateChanged(ResourceSynchronization::State s);
@@ -89,7 +90,7 @@ public:
* i.e. if this and all required assets loaded without errors.
*/
bool load();
bool hasLoadedParent() const;
bool hasLoadedParent();
bool isLoaded() const;
void unload();
void unloadIfUnwanted();

View File

@@ -81,14 +81,17 @@ int addLayer(lua_State* L) {
}
catch (const ghoul::lua::LuaFormatException& e) {
LERRORC("addLayerFromDictionary", e.what());
lua_settop(L, 0);
return 0;
}
lua_settop(L, 0);
std::shared_ptr<Layer> layer = globe->layerManager()->addLayer(groupID, d);
if (layer) {
layer->initialize();
}
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -113,6 +116,8 @@ int deleteLayer(lua_State* L) {
const std::string LayerGroupName = luaL_checkstring(L, LayerGroupLocation);
const std::string LayerName = luaL_checkstring(L, NameLocation);
lua_settop(L, 0);
// Get the node and make sure it exists
SceneGraphNode* node = OsEng.renderEngine().scene()->sceneGraphNode(GlobeName);
if (!node) {
@@ -133,6 +138,7 @@ int deleteLayer(lua_State* L) {
globe->layerManager()->deleteLayer(groupID, LayerName);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -148,10 +154,12 @@ int goToChunk(lua_State* L) {
int x = static_cast<int>(lua_tonumber(L, 1));
int y = static_cast<int>(lua_tonumber(L, 2));
int level = static_cast<int>(lua_tonumber(L, 3));
lua_settop(L, 0);
OsEng.moduleEngine().module<GlobeBrowsingModule>()->goToChunk(x, y, level);
return 0;
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
int goToGeo(lua_State* L) {
@@ -174,6 +182,8 @@ int goToGeo(lua_State* L) {
altitude);
}
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -202,10 +212,13 @@ int getGeoPosition(lua_State* L) {
double altitude = glm::length(cameraPositionModelSpace -
posHandle.centerToReferenceSurface);
lua_settop(L, 0);
lua_pushnumber(L, Angle<double>::fromRadians(geo2.lat).asDegrees());
lua_pushnumber(L, Angle<double>::fromRadians(geo2.lon).asDegrees());
lua_pushnumber(L, altitude);
ghoul_assert(lua_gettop(L) == 3, "Incorrect number of items left on stack");
return 3;
}
@@ -220,6 +233,7 @@ int loadWMSCapabilities(lua_State* L) {
std::string name = lua_tostring(L, -3);
std::string globe = lua_tostring(L, -2);
std::string url = lua_tostring(L, -1);
lua_settop(L, 0);
OsEng.moduleEngine().module<GlobeBrowsingModule>()->loadWMSCapabilities(
std::move(name),
@@ -227,6 +241,7 @@ int loadWMSCapabilities(lua_State* L) {
std::move(url)
);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -238,7 +253,11 @@ int removeWMSServer(lua_State* L) {
}
std::string name = lua_tostring(L, -1);
lua_settop(L, 0);
OsEng.moduleEngine().module<GlobeBrowsingModule>()->removeWMSServer(name);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -253,6 +272,7 @@ int capabilities(lua_State* L) {
GlobeBrowsingModule::Capabilities cap =
OsEng.moduleEngine().module<GlobeBrowsingModule>()->capabilities(name);
lua_settop(L, 0);
lua_newtable(L);
for (unsigned long i = 0; i < cap.size(); ++i) {
const GlobeBrowsingModule::Layer& l = cap[i];
@@ -270,6 +290,7 @@ int capabilities(lua_State* L) {
lua_rawseti(L, -2, i + 1);
}
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
#endif // GLOBEBROWSING_USE_GDAL

View File

@@ -106,6 +106,11 @@ void SyncModule::internalInitialize(const ghoul::Dictionary& configuration) {
fTask->registerClass<SyncAssetTask>("SyncAssetTask");
_torrentClient.initialize();
// Deinitialize
OsEng.registerModuleCallback(OpenSpaceEngine::CallbackOption::Deinitialize, [&] {
_torrentClient.deinitialize();
});
}
std::vector<documentation::Documentation> SyncModule::documentations() const {

View File

@@ -68,7 +68,7 @@ void SyncAssetTask::perform(const Task::ProgressCallback & progressCallback) {
scripting::ScriptEngine scriptEngine;
registerCoreClasses(scriptEngine);
;
for (OpenSpaceModule* m : OsEng.moduleEngine().modules()) {
scriptEngine.addLibrary(m->luaLibrary());

View File

@@ -30,7 +30,7 @@
namespace {
constexpr const char* _loggerCat = "TorrentClient";
std::chrono::milliseconds PollInterval(200);
std::chrono::milliseconds PollInterval(1000);
} // namespace
namespace openspace {
@@ -53,14 +53,11 @@ TorrentError::TorrentError(std::string component)
namespace openspace {
TorrentClient::TorrentClient()
: _keepRunning(true)
: _active(false)
{}
TorrentClient::~TorrentClient() {
std::lock_guard<std::mutex> guard(_mutex);
_keepRunning = false;
_torrentThread.join();
_session = nullptr;
deinitialize();
}
void TorrentClient::initialize() {
@@ -92,40 +89,65 @@ void TorrentClient::initialize() {
_session->listen_on(std::make_pair(20280, 20290), ec);
_session->start_upnp();
_active = true;
_torrentThread = std::thread([this]() {
while (_keepRunning) {
while (_active) {
pollAlerts();
std::this_thread::sleep_for(PollInterval);
std::unique_lock<std::mutex> lock(_abortMutex);
_abortNotifier.wait_for(lock, PollInterval);
}
});
}
void TorrentClient::deinitialize() {
if (!_active) {
return;
}
_active = false;
_abortNotifier.notify_all();
if (_torrentThread.joinable()) {
_torrentThread.join();
}
std::vector<lt::torrent_handle> handles = _session->get_torrents();
for (lt::torrent_handle h : handles) {
_session->remove_torrent(h);
}
_torrents.clear();
_session->abort();
_session = nullptr;
}
void TorrentClient::pollAlerts() {
// Libtorrent does not seem to reliably generate alerts for all added torrents.
// To make sure that the program does not keep waiting for already finished
// downsloads, we go through the whole list of torrents when polling.
// However, in theory, the commented code below should be more efficient:
/*
std::vector<libtorrent::alert*> alerts;
{
std::lock_guard<std::mutex> guard(_mutex);
_session->pop_alerts(&alerts);
}
for (lt::alert const* a : alerts) {
//LINFO(a->message());
// if we receive the finished alert or an error, we're done
if (const lt::torrent_finished_alert* alert =
lt::alert_cast<lt::torrent_finished_alert>(a))
{
notify(alert->handle.id());
}
if (const lt::piece_finished_alert* alert =
lt::alert_cast<lt::piece_finished_alert>(a))
{
notify(alert->handle.id());
}
if (const lt::torrent_error_alert* alert =
lt::alert_cast<lt::torrent_error_alert>(a))
for (lt::alert* a : alerts) {
if (const lt::torrent_alert* alert =
dynamic_cast<lt::torrent_alert*>(a))
{
notify(alert->handle.id());
}
}
*/
std::vector<lt::torrent_handle> handles;
{
std::lock_guard<std::mutex> guard(_mutex);
handles = _session->get_torrents();
}
for (lt::torrent_handle h : handles) {
notify(h.id());
}
}
TorrentClient::TorrentId TorrentClient::addTorrentFile(std::string torrentFile,
@@ -167,6 +189,11 @@ TorrentClient::TorrentId TorrentClient::addMagnetLink(std::string magnetLink,
}
libtorrent::error_code ec;
libtorrent::add_torrent_params p = libtorrent::parse_magnet_uri(magnetLink, ec);
if (ec) {
LERROR(magnetLink << ": " << ec.message());
}
p.save_path = destination;
p.storage_mode = libtorrent::storage_mode_allocate;
@@ -195,24 +222,29 @@ void TorrentClient::removeTorrent(TorrentId id) {
}
void TorrentClient::notify(TorrentId id) {
std::lock_guard<std::mutex> guard(_mutex);
auto torrent = _torrents.find(id);
if (torrent == _torrents.end()) {
return;
}
libtorrent::torrent_handle h = torrent->second.handle;
libtorrent::torrent_status status = h.status();
TorrentProgressCallback callback;
TorrentProgress progress;
progress.finished = status.is_finished;
progress.nTotalBytesKnown = status.total_wanted > 0;
progress.nTotalBytes = status.total_wanted;
progress.nDownloadedBytes = status.total_wanted_done;
{
std::lock_guard<std::mutex> guard(_mutex);
torrent->second.callback(progress);
auto torrent = _torrents.find(id);
if (torrent == _torrents.end()) {
return;
}
libtorrent::torrent_handle h = torrent->second.handle;
libtorrent::torrent_status status = h.status();
progress.finished = status.is_finished;
progress.nTotalBytesKnown = status.total_wanted > 0;
progress.nTotalBytes = status.total_wanted;
progress.nDownloadedBytes = status.total_wanted_done;
callback = torrent->second.callback;
}
callback(progress);
}
} // namespace openspace
@@ -227,6 +259,8 @@ TorrentClient::~TorrentClient() {}
void TorrentClient::initialize() {}
void TorrentClient::deinitialize() {}
void TorrentClient::pollAlerts() {}
TorrentClient::TorrentId TorrentClient::addTorrentFile(std::string, std::string,

View File

@@ -57,6 +57,7 @@ public:
using TorrentId = int32_t;
virtual void initialize() = 0;
virtual void deinitialize() = 0;
virtual TorrentId addTorrentFile(std::string torrentFile,
std::string destination,
TorrentProgressCallback cb) = 0;
@@ -78,6 +79,7 @@ public:
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <unordered_map>
#include "libtorrent/torrent_handle.hpp"
@@ -92,6 +94,7 @@ public:
virtual ~TorrentClient();
void initialize() override;
void deinitialize() override;
TorrentId addTorrentFile(std::string torrentFile,
std::string destination,
TorrentProgressCallback cb) override;
@@ -116,7 +119,9 @@ private:
std::unique_ptr<libtorrent::session> _session;
std::thread _torrentThread;
std::mutex _mutex;
std::atomic_bool _keepRunning;
std::atomic_bool _active;
std::mutex _abortMutex;
std::condition_variable _abortNotifier;
};
} // namespace openspace
@@ -131,6 +136,7 @@ public:
virtual ~TorrentClient();
void initialize() override;
void deinitialize() override;
TorrentId addTorrentFile(std::string torrentFile,
std::string destination,
TorrentProgressCallback cb) override;

View File

@@ -30,6 +30,7 @@
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/misc/assert.h>
#include <algorithm>

View File

@@ -57,6 +57,7 @@ int isLoaded(lua_State* L) {
else
lua_pushboolean(L, 0);
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}

View File

@@ -41,6 +41,7 @@ int toggleShutdown(lua_State* L) {
OsEng.toggleShutdownMode();
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -58,6 +59,7 @@ int writeDocumentation(lua_State* L) {
OsEng.writeStaticDocumentation();
OsEng.writeSceneDocumentation();
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -115,10 +117,13 @@ int addVirtualProperty(lua_State* L) {
);
}
else {
lua_settop(L, 0);
return luaL_error(L, "Unknown property type '%s'", type.c_str());
}
lua_settop(L, 0);
OsEng.virtualPropertyManager().addProperty(std::move(prop));
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -134,8 +139,10 @@ int removeVirtualProperty(lua_State* L) {
}
const std::string name = lua_tostring(L, -1);
lua_settop(L, 0);
properties::Property* p = OsEng.virtualPropertyManager().property(name);
OsEng.virtualPropertyManager().removeProperty(p);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -146,8 +153,8 @@ int removeVirtualProperty(lua_State* L) {
*/
int removeAllVirtualProperties(lua_State* L) {
const int nArguments = lua_gettop(L);
if (nArguments != 1) {
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
if (nArguments != 0) {
return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments);
}
std::vector<properties::Property*> ps = OsEng.virtualPropertyManager().properties();
@@ -155,6 +162,8 @@ int removeAllVirtualProperties(lua_State* L) {
OsEng.virtualPropertyManager().removeProperty(p);
delete p;
}
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -171,6 +180,7 @@ int addTag(lua_State* L) {
const std::string uri = lua_tostring(L, -2);
const std::string tag = lua_tostring(L, -1);
lua_settop(L, 0);
SceneGraphNode* node = OsEng.renderEngine().scene()->sceneGraphNode(uri);
if (!node) {
@@ -179,6 +189,7 @@ int addTag(lua_State* L) {
node->addTag(std::move(tag));
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -195,6 +206,7 @@ int removeTag(lua_State* L) {
const std::string uri = lua_tostring(L, -2);
const std::string tag = lua_tostring(L, -1);
lua_settop(L, 0);
SceneGraphNode* node = OsEng.renderEngine().scene()->sceneGraphNode(uri);
if (!node) {
@@ -203,6 +215,7 @@ int removeTag(lua_State* L) {
node->removeTag(tag);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -217,6 +230,7 @@ int downloadFile(lua_State* L) {
return luaL_error(L, "Expected %i arguments, got %i", 2, nArguments);
std::string uri = luaL_checkstring(L, -2);
std::string savePath = luaL_checkstring(L, -1);
lua_settop(L, 0);
const std::string _loggerCat = "OpenSpaceEngine";
LINFO("Downloading file from " << uri);
@@ -229,7 +243,9 @@ int downloadFile(lua_State* L) {
errorMsg += ": " + future->errorMessage;
return luaL_error(L, errorMsg.c_str());
}
return 1;
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
} // namespace luascriptfunctions

View File

@@ -41,6 +41,8 @@ int setSynchronization(lua_State* L) {
bool b = lua_toboolean(L, -1) != 0;
OsEng.windowWrapper().setSynchronization(b);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}

View File

@@ -69,6 +69,8 @@ int bindKey(lua_State* L) {
std::move(documentation)
);
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -115,6 +117,8 @@ int bindKeyLocal(lua_State* L) {
std::move(documentation)
);
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -131,6 +135,7 @@ int getKeyBindings(lua_State* L) {
}
std::string key = luaL_checkstring(L, -1);
lua_settop(L, 0);
using KeyInformation = interaction::KeyBindingManager::KeyInformation;
@@ -153,6 +158,8 @@ int getKeyBindings(lua_State* L) {
lua_settable(L, -3);
++i;
}
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
@@ -168,9 +175,11 @@ int clearKey(lua_State* L) {
}
std::string key = luaL_checkstring(L, -1);
lua_settop(L, 0);
OsEng.keyBindingManager().removeKeyBinding(key);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -187,6 +196,7 @@ int clearKeys(lua_State* L) {
OsEng.keyBindingManager().resetKeyBindings();
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}

View File

@@ -33,12 +33,14 @@ int restoreCameraStateFromFile(lua_State* L) {
}
std::string cameraStateFilePath = luaL_checkstring(L, -1);
lua_settop(L, 0);
if (cameraStateFilePath.empty()) {
return luaL_error(L, "filepath string is empty");
}
OsEng.navigationHandler().restoreCameraStateFromFile(cameraStateFilePath);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -53,8 +55,12 @@ int setCameraState(lua_State* L) {
ghoul::lua::luaDictionaryFromState(L, dictionary);
OsEng.navigationHandler().setCameraStateFromDictionary(dictionary);
} catch (const ghoul::RuntimeError& e) {
lua_settop(L, 0);
return luaL_error(L, "Could not set camera state: %s", e.what());
}
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -67,12 +73,14 @@ int saveCameraStateToFile(lua_State* L) {
}
std::string cameraStateFilePath = luaL_checkstring(L, -1);
lua_settop(L, 0);
if (cameraStateFilePath.empty()) {
return luaL_error(L, "filepath string is empty");
}
OsEng.navigationHandler().saveCameraStateToFile(cameraStateFilePath);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -85,6 +93,7 @@ int resetCameraDirection(lua_State* L) {
}
OsEng.navigationHandler().resetCameraDirection();
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}

View File

@@ -36,6 +36,8 @@ int loadMission(lua_State* L) {
}
std::string name = MissionManager::ref().loadMission(absPath(missionFileName));
lua_pushstring(L, name.c_str());
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
@@ -55,6 +57,8 @@ int unloadMission(lua_State* L) {
}
MissionManager::ref().unloadMission(missionName);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -72,6 +76,8 @@ int hasMission(lua_State* L) {
bool hasMission = MissionManager::ref().hasMission(missionName);
lua_pushboolean(L, hasMission);
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
@@ -86,6 +92,8 @@ int setCurrentMission(lua_State* L) {
return luaL_error(L, "Mission name is empty");
}
MissionManager::ref().setCurrentMission(missionName);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}

View File

@@ -31,6 +31,8 @@ int connect(lua_State* L) {
if (OsEng.windowWrapper().isMaster()) {
OsEng.parallelConnection().clientConnect();
}
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -41,6 +43,8 @@ int disconnect(lua_State* L) {
if (OsEng.windowWrapper().isMaster()) {
OsEng.parallelConnection().signalDisconnect();
}
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -51,6 +55,8 @@ int requestHostship(lua_State* L) {
if (OsEng.windowWrapper().isMaster()) {
OsEng.parallelConnection().requestHostship();
}
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -61,6 +67,8 @@ int resignHostship(lua_State* L) {
if (OsEng.windowWrapper().isMaster()) {
OsEng.parallelConnection().resignHostship();
}
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}

View File

@@ -27,6 +27,7 @@
#include <openspace/rendering/dashboarditem.h>
#include <openspace/scripting/scriptengine.h>
#include <ghoul/misc/assert.h>
#include "dashboard_lua.inl"
namespace openspace {

View File

@@ -46,10 +46,14 @@ int addDashboardItem(lua_State* L) {
}
catch (const ghoul::lua::LuaFormatException& e) {
LERRORC("addDashboardItem", e.what());
lua_settop(L, 0);
return 0;
}
lua_settop(L, 0);
OsEng.dashboard().addDashboardItem(DashboardItem::createFromDictionary(d));
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
else {
@@ -68,6 +72,8 @@ int removeDashboardItems(lua_State* L) {
}
OsEng.dashboard().removeDashboardItems();
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}

View File

@@ -41,6 +41,8 @@ int setRenderer(lua_State* L) {
}
std::string r = lua_tostring(L, -1);
OsEng.renderEngine().setRendererFromString(r);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -61,6 +63,8 @@ int toggleFade(lua_State* L) {
int direction = OsEng.renderEngine().globalBlackOutFactor() == fadedIn ? -1 : 1;
OsEng.renderEngine().startFading(direction, static_cast<float>(t));
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -78,6 +82,8 @@ int fadeIn(lua_State* L) {
double t = luaL_checknumber(L, -1);
OsEng.renderEngine().startFading(1, static_cast<float>(t));
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
/**
@@ -94,6 +100,8 @@ int fadeOut(lua_State* L) {
double t = luaL_checknumber(L, -1);
OsEng.renderEngine().startFading(-1, static_cast<float>(t));
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -119,6 +127,7 @@ int addScreenSpaceRenderable(lua_State* L) {
);
OsEng.renderEngine().addScreenSpaceRenderable(s);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -140,11 +149,13 @@ int removeScreenSpaceRenderable(lua_State* L) {
"removeScreenSpaceRenderable",
errorLocation(L) << "Could not find ScreenSpaceRenderable '" << name << "'"
);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
OsEng.renderEngine().removeScreenSpaceRenderable(s);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}

View File

@@ -27,6 +27,7 @@
#include <ghoul/logging/logmanager.h>
#include <iterator>
#include <algorithm>
#include <unordered_set>
@@ -80,12 +81,7 @@ Asset::Asset(AssetLoader* loader,
, _assetPath(assetPath)
{}
Asset::~Asset() {
for (const SynchronizationWatcher::WatchHandle& h : _syncWatches) {
_synchronizationWatcher->unwatchSynchronization(h);
}
_loader->untrackAsset(this);
}
Asset::~Asset() {}
std::string Asset::resolveLocalResource(std::string resourceName) {
std::string currentAssetDirectory = assetDirectory();
@@ -186,8 +182,14 @@ void Asset::addSynchronization(std::shared_ptr<ResourceSynchronization> synchron
_syncWatches.push_back(watch);
}
void Asset::syncStateChanged(ResourceSynchronization::State state)
{
void Asset::clearSynchronizations() {
for (const SynchronizationWatcher::WatchHandle& h : _syncWatches) {
_synchronizationWatcher->unwatchSynchronization(h);
}
_syncWatches.clear();
}
void Asset::syncStateChanged(ResourceSynchronization::State state) {
if (state == ResourceSynchronization::State::Resolved) {
if (!isSynchronized() && isSyncResolveReady()) {
setState(State::SyncResolved);
@@ -273,28 +275,39 @@ bool Asset::isSyncingOrResolved() const {
s == State::InitializationFailed;
}
bool Asset::hasLoadedParent() const {
for (const auto& p : _requiringAssets) {
std::shared_ptr<Asset> parent = p.lock();
if (!parent) {
continue;
}
if (parent->isLoaded()) {
return true;
bool Asset::hasLoadedParent() {
{
std::vector<std::weak_ptr<Asset>>::iterator it = _requiringAssets.begin();
while (it != _requiringAssets.end()) {
std::shared_ptr<Asset> parent = it->lock();
if (!parent) {
it = _requiringAssets.erase(it);
continue;
}
if (parent->isLoaded()) {
return true;
}
++it;
}
}
for (const auto& p : _requestingAssets) {
std::shared_ptr<Asset> parent = p.lock();
if (!parent) {
continue;
}
if (parent->isLoaded()) {
return true;
}
if (parent->hasLoadedParent()) {
return true;
{
std::vector<std::weak_ptr<Asset>>::iterator it = _requestingAssets.begin();
while (it != _requestingAssets.end()) {
std::shared_ptr<Asset> parent = it->lock();
if (!parent) {
it = _requestingAssets.erase(it);
continue;
}
if (parent->isLoaded()) {
return true;
}
if (parent->hasLoadedParent()) {
return true;
}
++it;
}
}
return false;
}

View File

@@ -106,6 +106,7 @@ AssetLoader::AssetLoader(ghoul::lua::LuaState& luaState,
AssetLoader::~AssetLoader() {
_currentAsset = nullptr;
_rootAsset = nullptr;
luaL_unref(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef);
}
void AssetLoader::trackAsset(std::shared_ptr<Asset> asset) {
@@ -144,6 +145,8 @@ void AssetLoader::setUpAssetLuaTable(Asset* asset) {
|- onDeinitialize
*/
int top = lua_gettop(*_luaState);
// Push the global table of AssetInfos to the lua stack.
lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef);
int globalTableIndex = lua_gettop(*_luaState);
@@ -226,9 +229,11 @@ void AssetLoader::setUpAssetLuaTable(Asset* asset) {
// Extend global asset info table (pushed to the lua stack earlier)
// with this AssetInfo table
lua_setfield(*_luaState, globalTableIndex, asset->id().c_str());
lua_settop(*_luaState, top);
}
void AssetLoader::tearDownAssetLuaTable(Asset* asset) {
int top = lua_gettop(*_luaState);
// Push the global table of AssetInfos to the lua stack.
lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef);
int globalTableIndex = lua_gettop(*_luaState);
@@ -237,9 +242,11 @@ void AssetLoader::tearDownAssetLuaTable(Asset* asset) {
// Clear entry from global asset table (pushed to the lua stack earlier)
lua_setfield(*_luaState, globalTableIndex, asset->id().c_str());
lua_settop(*_luaState, top);
}
bool AssetLoader::loadAsset(std::shared_ptr<Asset> asset) {
int top = lua_gettop(*_luaState);
std::shared_ptr<Asset> parentAsset = _currentAsset;
setCurrentAsset(asset);
@@ -250,6 +257,7 @@ bool AssetLoader::loadAsset(std::shared_ptr<Asset> asset) {
if (!FileSys.fileExists(asset->assetFilePath())) {
LERROR("Could not load asset '" << asset->assetFilePath() <<
"': File does not exist.");
lua_settop(*_luaState, top);
return false;
}
@@ -257,9 +265,11 @@ bool AssetLoader::loadAsset(std::shared_ptr<Asset> asset) {
ghoul::lua::runScriptFile(*_luaState, asset->assetFilePath());
} catch (const ghoul::lua::LuaRuntimeException& e) {
LERROR("Could not load asset '" << asset->assetFilePath() << "': " << e.message);
lua_settop(*_luaState, top);
return false;
}
lua_settop(*_luaState, top);
return true;
}
@@ -279,14 +289,17 @@ void AssetLoader::unloadAsset(std::shared_ptr<Asset> asset) {
luaL_unref(*_luaState, LUA_REGISTRYINDEX, ref);
}
}
_onDependencyInitializationFunctionRefs[asset.get()].clear();
_onDependencyInitializationFunctionRefs.erase(asset.get());
for (const auto& it : _onDependencyDeinitializationFunctionRefs[asset.get()]) {
for (int ref : it.second) {
luaL_unref(*_luaState, LUA_REGISTRYINDEX, ref);
}
}
_onDependencyDeinitializationFunctionRefs[asset.get()].clear();
_onDependencyDeinitializationFunctionRefs.erase(asset.get());
asset->clearSynchronizations();
untrackAsset(asset.get());
}
std::string AssetLoader::generateAssetPath(const std::string& baseDirectory,
@@ -380,6 +393,7 @@ int AssetLoader::onInitializeLua(Asset* asset) {
SCRIPT_CHECK_ARGUMENTS("onInitialize", *_luaState, 1, nArguments);
int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX);
_onInitializationFunctionRefs[asset].push_back(referenceIndex);
lua_settop(*_luaState, 0);
return 0;
}
@@ -388,6 +402,7 @@ int AssetLoader::onDeinitializeLua(Asset* asset) {
SCRIPT_CHECK_ARGUMENTS("onDeinitialize", *_luaState, 1, nArguments);
int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX);
_onDeinitializationFunctionRefs[asset].push_back(referenceIndex);
lua_settop(*_luaState, 0);
return 0;
}
@@ -397,7 +412,7 @@ int AssetLoader::onInitializeDependencyLua(Asset* dependant, Asset* dependency)
int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX);
_onDependencyInitializationFunctionRefs[dependant][dependency]
.push_back(referenceIndex);
lua_settop(*_luaState, 0);
return 0;
}
@@ -407,7 +422,7 @@ int AssetLoader::onDeinitializeDependencyLua(Asset* dependant, Asset* dependency
int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX);
_onDependencyDeinitializationFunctionRefs[dependant][dependency]
.push_back(referenceIndex);
lua_settop(*_luaState, 0);
return 0;
}
@@ -484,6 +499,8 @@ void AssetLoader::callOnInitialize(Asset* asset) {
luaL_checkstring(*_luaState, -1)
);
}
// Clean up lua stack, in case the pcall left anything there.
lua_settop(*_luaState, 0);
}
}
@@ -497,6 +514,8 @@ void AssetLoader::callOnDeinitialize(Asset * asset) {
luaL_checkstring(*_luaState, -1)
);
}
// Clean up lua stack, in case the pcall left anything there.
lua_settop(*_luaState, 0);
}
}
@@ -509,6 +528,8 @@ void AssetLoader::callOnDependencyInitialize(Asset* asset, Asset* dependant) {
asset->assetFilePath() + ": " + luaL_checkstring(*_luaState, -1)
);
}
// Clean up lua stack, in case the pcall left anything there.
lua_settop(*_luaState, 0);
}
// Potential Todo:
// Call dependency->onInitialize with the asset table
@@ -525,6 +546,8 @@ void AssetLoader::callOnDependencyDeinitialize(Asset* asset, Asset* dependant) {
asset->assetFilePath() + ": " + luaL_checkstring(*_luaState, -1)
);
}
// Clean up lua stack, in case the pcall left anything there.
lua_settop(*_luaState, 0);
}
}
@@ -535,7 +558,10 @@ int AssetLoader::localResourceLua(Asset* asset) {
std::string resourceName = luaL_checkstring(*_luaState, -1);
std::string resolved = asset->resolveLocalResource(resourceName);
lua_settop(*_luaState, 0);
lua_pushstring(*_luaState, resolved.c_str());
ghoul_assert(lua_gettop(*_luaState) == 1, "Incorrect number of items left on stack");
return 1;
}
@@ -553,17 +579,23 @@ int AssetLoader::syncedResourceLua(Asset* asset) {
asset->addSynchronization(sync);
lua_settop(*_luaState, 0);
lua_pushstring(*_luaState, absolutePath.c_str());
ghoul_assert(lua_gettop(*_luaState) == 1, "Incorrect number of items left on stack");
return 1;
}
void AssetLoader::setCurrentAsset(std::shared_ptr<Asset> asset) {
int top = lua_gettop(*_luaState);
_currentAsset = asset;
// Set `asset` lua global to point to the current asset table
if (asset == _rootAsset) {
lua_pushnil(*_luaState);
lua_setglobal(*_luaState, AssetGlobalVariableName);
lua_settop(*_luaState, top);
return;
}
@@ -571,6 +603,8 @@ void AssetLoader::setCurrentAsset(std::shared_ptr<Asset> asset) {
lua_getfield(*_luaState, -1, asset->id().c_str());
lua_getfield(*_luaState, -1, AssetTableName);
lua_setglobal(*_luaState, AssetGlobalVariableName);
lua_settop(*_luaState, top);
}
int AssetLoader::requireLua(Asset* dependant) {
@@ -578,6 +612,7 @@ int AssetLoader::requireLua(Asset* dependant) {
SCRIPT_CHECK_ARGUMENTS("require", *_luaState, 1, nArguments);
std::string assetName = luaL_checkstring(*_luaState, 1);
lua_settop(*_luaState, 0);
std::shared_ptr<Asset> dependency = require(assetName);
@@ -602,6 +637,12 @@ int AssetLoader::requireLua(Asset* dependant) {
lua_pushvalue(*_luaState, exportsTableIndex);
lua_pushvalue(*_luaState, dependencyTableIndex);
lua_replace(*_luaState, 2);
lua_replace(*_luaState, 1);
lua_settop(*_luaState, 2);
ghoul_assert(lua_gettop(*_luaState) == 2, "Incorrect number of items left on stack");
return 2;
}
@@ -610,6 +651,7 @@ int AssetLoader::requestLua(Asset* parent) {
SCRIPT_CHECK_ARGUMENTS("request", *_luaState, 1, nArguments);
std::string assetName = luaL_checkstring(*_luaState, 1);
lua_settop(*_luaState, 0);
std::shared_ptr<Asset> child = request(assetName);
@@ -623,6 +665,11 @@ int AssetLoader::requestLua(Asset* parent) {
int dependencyTableIndex = lua_gettop(*_luaState);
lua_pushvalue(*_luaState, dependencyTableIndex);
lua_replace(*_luaState, 1);
lua_settop(*_luaState, 1);
ghoul_assert(lua_gettop(*_luaState) == 1, "Incorrect number of items left on stack");
return 1;
}
@@ -635,7 +682,9 @@ int AssetLoader::existsLua(Asset* asset) {
ghoul::filesystem::Directory directory = currentDirectory();
std::string path = generateAssetPath(directory, assetName);
lua_settop(*_luaState, 0);
lua_pushboolean(*_luaState, FileSys.fileExists(path));
ghoul_assert(lua_gettop(*_luaState) == 1, "Incorrect number of items left on stack");
return 1;
}
@@ -653,10 +702,15 @@ int AssetLoader::exportAssetLua(Asset* asset) {
// push the second argument
lua_pushvalue(*_luaState, 2);
lua_setfield(*_luaState, exportsTableIndex, exportName.c_str());
lua_settop(*_luaState, 0);
ghoul_assert(lua_gettop(*_luaState) == 0, "Incorrect number of items left on stack");
return 0;
}
void AssetLoader::addLuaDependencyTable(Asset* dependant, Asset* dependency) {
int top = lua_gettop(*_luaState);
const std::string dependantId = dependant->id();
const std::string dependencyId = dependency->id();
@@ -689,6 +743,8 @@ void AssetLoader::addLuaDependencyTable(Asset* dependant, Asset* dependency) {
// Register the dependant table on the imported asset's dependants table.
lua_setfield(*_luaState, dependantsTableIndex, dependantId.c_str());
lua_settop(*_luaState, top);
}
void AssetLoader::addAssetListener(AssetListener* listener) {

View File

@@ -53,6 +53,7 @@ void AssetManager::initialize() {
void AssetManager::deinitialize() {
_assetLoader->rootAsset()->deinitialize();
_assetLoader->rootAsset()->unload();
_assetLoader->removeAssetListener(this);
_assetLoader = nullptr;
}

View File

@@ -320,10 +320,13 @@ int property_getValue(lua_State* L) {
"property_getValue",
errorLocation(L) << "Property with URL '" << uri << "' was not found"
);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
else
} else {
prop->getLuaValue(L);
}
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
@@ -340,6 +343,7 @@ int loadScene(lua_State* L) {
std::string sceneFile = luaL_checkstring(L, -1);
OsEng.scheduleLoadSingleAsset(sceneFile);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -377,6 +381,9 @@ int addSceneGraphNode(lua_State* L) {
} catch (const ghoul::RuntimeError& e) {
return luaL_error(L, "Error loading scene graph node: %s", e.what());
}
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -405,7 +412,10 @@ int removeSceneGraphNode(lua_State* L) {
}
node->deinitializeGL();
parent->detachChild(*node);
return 1;
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -416,7 +426,10 @@ int hasSceneGraphNode(lua_State* L) {
std::string nodeName = luaL_checkstring(L, -1);
SceneGraphNode* node = OsEng.renderEngine().scene()->sceneGraphNode(nodeName);
lua_settop(L, 0);
lua_pushboolean(L, node != nullptr);
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}

View File

@@ -81,6 +81,8 @@ void ScriptEngine::deinitialize() {
void ScriptEngine::initializeLuaState(lua_State* state) {
LDEBUG("Create openspace base library");
int top = lua_gettop(state);
lua_newtable(state);
lua_setglobal(state, OpenSpaceLibraryName.c_str());
@@ -88,6 +90,8 @@ void ScriptEngine::initializeLuaState(lua_State* state) {
for (LuaLibrary& lib : _registeredLibraries) {
registerLuaLibrary(state, lib);
}
lua_settop(state, top);
}
ghoul::lua::LuaState * ScriptEngine::luaState() {
@@ -462,6 +466,7 @@ void ScriptEngine::remapPrintFunction() {
bool ScriptEngine::registerLuaLibrary(lua_State* state, LuaLibrary& library) {
ghoul_assert(state, "State must not be nullptr");
int top = lua_gettop(state);
lua_getglobal(state, OpenSpaceLibraryName.c_str());
if (library.name.empty()) {
@@ -471,6 +476,7 @@ bool ScriptEngine::registerLuaLibrary(lua_State* state, LuaLibrary& library) {
else {
const bool allowed = isLibraryNameAllowed(state, library.name);
if (!allowed) {
lua_settop(state, top);
return false;
}
@@ -492,6 +498,8 @@ bool ScriptEngine::registerLuaLibrary(lua_State* state, LuaLibrary& library) {
// Pop the table
lua_pop(state, 1);
}
lua_settop(state, top);
return true;
}

View File

@@ -71,6 +71,8 @@ int walkCommon(lua_State* L, Func func) {
);
}
lua_settop(L, 0);
// Copy values into the lua_State
lua_newtable(L);
@@ -79,6 +81,7 @@ int walkCommon(lua_State* L, Func func) {
lua_rawseti(L, -2, i + 1);
}
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
} // namespace
@@ -115,6 +118,7 @@ int printInternal(ghoul::logging::LogLevel level, lua_State* L) {
LOGC(level, "print", lua_tostring(L, -1));
break;
}
lua_settop(L, 0);
return 0;
}
@@ -197,6 +201,8 @@ int absolutePath(lua_State* L) {
}
std::string path = luaL_checkstring(L, -1);
lua_settop(L, 0);
path = absPath(path);
//path = FileSys.convertPathSeparator(path, '/');
lua_pushstring(L, path.c_str());
@@ -217,6 +223,7 @@ int setPathToken(lua_State* L) {
const std::string path = luaL_checkstring(L, -1);
const std::string pathToken = luaL_checkstring(L, -2);
lua_settop(L, 0);
FileSys.registerPathToken(
pathToken,
path,
@@ -238,6 +245,8 @@ int fileExists(lua_State* L) {
const std::string file = luaL_checkstring(L, -1);
const bool e = FileSys.fileExists(absPath(file));
lua_settop(L, 0);
lua_pushboolean(L, (e ? 1 : 0));
return 1;
}
@@ -255,6 +264,8 @@ int directoryExists(lua_State* L) {
const std::string file = luaL_checkstring(L, -1);
const bool e = FileSys.directoryExists(absPath(file));
lua_settop(L, 0);
lua_pushboolean(L, (e ? 1 : 0));
return 1;
}
@@ -315,6 +326,8 @@ int directoryForPath(lua_State* L) {
const std::string file = luaL_checkstring(L, -1);
const std::string path = ghoul::filesystem::File(file).directoryName();
lua_settop(L, 0);
lua_pushstring(L, path.c_str());
return 1;
}

View File

@@ -39,6 +39,7 @@ int loadFile(lua_State* L) {
ghoul::lua::loadDictionaryFromFile(missionFileName, L)
);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -84,6 +85,7 @@ int loadScheduledScript(lua_State* L) {
return luaL_error(L, "Expected %i-%i arguments, got %i", 2, 4, nArguments);
}
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -95,6 +97,7 @@ int clear(lua_State* L) {
OsEng.scriptScheduler().clearSchedule();
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}

View File

@@ -49,7 +49,10 @@ int loadKernel(lua_State* L) {
}
unsigned int result = SpiceManager::ref().loadKernel(argument);
lua_settop(L, 0);
lua_pushnumber(L, result);
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
@@ -71,6 +74,8 @@ int unloadKernel(lua_State* L) {
ghoul::lua::errorLocation(L) <<
"Expected argument of type 'string' or 'number'"
);
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -84,6 +89,9 @@ int unloadKernel(lua_State* L) {
SpiceManager::ref().unloadKernel(argument);
}
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}

View File

@@ -46,6 +46,7 @@ int time_setDeltaTime(lua_State* L) {
if (isNumber) {
double value = lua_tonumber(L, -1);
OsEng.timeManager().time().setDeltaTime(value);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
else {
@@ -67,6 +68,7 @@ int time_setDeltaTime(lua_State* L) {
*/
int time_deltaTime(lua_State* L) {
lua_pushnumber(L, OsEng.timeManager().time().deltaTime());
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
@@ -82,6 +84,7 @@ int time_togglePause(lua_State* L) {
}
OsEng.timeManager().time().togglePause();
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -98,6 +101,8 @@ int time_setPause(lua_State* L) {
bool pause = lua_toboolean(L, -1) == 1;
OsEng.timeManager().time().setPause(pause);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -137,6 +142,7 @@ int time_setTime(lua_State* L) {
OsEng.timeManager().time().setTime(time);
return 0;
}
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -148,6 +154,7 @@ int time_setTime(lua_State* L) {
*/
int time_currentTime(lua_State* L) {
lua_pushnumber(L, OsEng.timeManager().time().j2000Seconds());
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
@@ -159,6 +166,7 @@ int time_currentTime(lua_State* L) {
*/
int time_currentTimeUTC(lua_State* L) {
lua_pushstring(L, OsEng.timeManager().time().UTC().c_str());
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
@@ -182,6 +190,7 @@ int time_currentWallTime(lua_State* L) {
utcTime->tm_sec
);
lua_pushstring(L, time.c_str());
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}