diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 54c70fb2f7..386da78ffd 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/include/openspace/interaction/navigationhandler.h b/include/openspace/interaction/navigationhandler.h index 6137e1f4da..9ab9e08f20 100644 --- a/include/openspace/interaction/navigationhandler.h +++ b/include/openspace/interaction/navigationhandler.h @@ -36,6 +36,7 @@ #include #include +#include namespace openspace { class Camera; diff --git a/include/openspace/scene/asset.h b/include/openspace/scene/asset.h index 020576c9f5..e1185694ff 100644 --- a/include/openspace/scene/asset.h +++ b/include/openspace/scene/asset.h @@ -90,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(); diff --git a/modules/globebrowsing/globebrowsingmodule_lua.inl b/modules/globebrowsing/globebrowsingmodule_lua.inl index 4e37ed0162..e4a14583d0 100644 --- a/modules/globebrowsing/globebrowsingmodule_lua.inl +++ b/modules/globebrowsing/globebrowsingmodule_lua.inl @@ -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 = 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(lua_tonumber(L, 1)); int y = static_cast(lua_tonumber(L, 2)); int level = static_cast(lua_tonumber(L, 3)); + lua_settop(L, 0); OsEng.moduleEngine().module()->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::fromRadians(geo2.lat).asDegrees()); lua_pushnumber(L, Angle::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()->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()->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()->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 diff --git a/src/engine/moduleengine.cpp b/src/engine/moduleengine.cpp index 506ee3efa0..d806a69f0e 100644 --- a/src/engine/moduleengine.cpp +++ b/src/engine/moduleengine.cpp @@ -30,6 +30,7 @@ #include #include +#include #include diff --git a/src/engine/moduleengine_lua.inl b/src/engine/moduleengine_lua.inl index 87aca7e4c6..8176fabf44 100644 --- a/src/engine/moduleengine_lua.inl +++ b/src/engine/moduleengine_lua.inl @@ -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; } diff --git a/src/engine/openspaceengine_lua.inl b/src/engine/openspaceengine_lua.inl index 26463aa004..276b5f2afb 100644 --- a/src/engine/openspaceengine_lua.inl +++ b/src/engine/openspaceengine_lua.inl @@ -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 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 diff --git a/src/engine/wrapper/windowwrapper.cpp b/src/engine/wrapper/windowwrapper.cpp index fa4e590620..c77d7286fc 100644 --- a/src/engine/wrapper/windowwrapper.cpp +++ b/src/engine/wrapper/windowwrapper.cpp @@ -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; } diff --git a/src/interaction/keybindingmanager_lua.inl b/src/interaction/keybindingmanager_lua.inl index edb1972467..ec1f0d0096 100644 --- a/src/interaction/keybindingmanager_lua.inl +++ b/src/interaction/keybindingmanager_lua.inl @@ -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; } diff --git a/src/interaction/navigationhandler_lua.inl b/src/interaction/navigationhandler_lua.inl index 1f0c76678b..173fa84dee 100644 --- a/src/interaction/navigationhandler_lua.inl +++ b/src/interaction/navigationhandler_lua.inl @@ -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; } diff --git a/src/mission/missionmanager_lua.inl b/src/mission/missionmanager_lua.inl index 381293d821..fac99a845d 100644 --- a/src/mission/missionmanager_lua.inl +++ b/src/mission/missionmanager_lua.inl @@ -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; } diff --git a/src/network/parallelconnection_lua.inl b/src/network/parallelconnection_lua.inl index b63a5e80ca..02ddb5aba4 100644 --- a/src/network/parallelconnection_lua.inl +++ b/src/network/parallelconnection_lua.inl @@ -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; } diff --git a/src/rendering/dashboard.cpp b/src/rendering/dashboard.cpp index 1b4cca20d2..8bf9f3a158 100644 --- a/src/rendering/dashboard.cpp +++ b/src/rendering/dashboard.cpp @@ -27,6 +27,7 @@ #include #include +#include #include "dashboard_lua.inl" namespace openspace { diff --git a/src/rendering/dashboard_lua.inl b/src/rendering/dashboard_lua.inl index bca0d67444..bc8f29eb58 100644 --- a/src/rendering/dashboard_lua.inl +++ b/src/rendering/dashboard_lua.inl @@ -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; } diff --git a/src/rendering/renderengine_lua.inl b/src/rendering/renderengine_lua.inl index cbdf30b31b..463bfdb592 100644 --- a/src/rendering/renderengine_lua.inl +++ b/src/rendering/renderengine_lua.inl @@ -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(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(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(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; } diff --git a/src/scene/asset.cpp b/src/scene/asset.cpp index ed9993c18d..23c1aa0db9 100644 --- a/src/scene/asset.cpp +++ b/src/scene/asset.cpp @@ -27,6 +27,7 @@ #include +#include #include #include @@ -185,10 +186,10 @@ void Asset::clearSynchronizations() { for (const SynchronizationWatcher::WatchHandle& h : _syncWatches) { _synchronizationWatcher->unwatchSynchronization(h); } + _syncWatches.clear(); } -void Asset::syncStateChanged(ResourceSynchronization::State state) -{ +void Asset::syncStateChanged(ResourceSynchronization::State state) { if (state == ResourceSynchronization::State::Resolved) { if (!isSynchronized() && isSyncResolveReady()) { setState(State::SyncResolved); @@ -274,28 +275,39 @@ bool Asset::isSyncingOrResolved() const { s == State::InitializationFailed; } -bool Asset::hasLoadedParent() const { - for (const auto& p : _requiringAssets) { - std::shared_ptr parent = p.lock(); - if (!parent) { - continue; - } - if (parent->isLoaded()) { - return true; +bool Asset::hasLoadedParent() { + { + std::vector>::iterator it = _requiringAssets.begin(); + while (it != _requiringAssets.end()) { + std::shared_ptr parent = it->lock(); + if (!parent) { + it = _requiringAssets.erase(it); + continue; + } + if (parent->isLoaded()) { + return true; + } + ++it; } } - for (const auto& p : _requestingAssets) { - std::shared_ptr parent = p.lock(); - if (!parent) { - continue; - } - if (parent->isLoaded()) { - return true; - } - if (parent->hasLoadedParent()) { - return true; + { + std::vector>::iterator it = _requestingAssets.begin(); + while (it != _requestingAssets.end()) { + std::shared_ptr parent = it->lock(); + if (!parent) { + it = _requestingAssets.erase(it); + continue; + } + if (parent->isLoaded()) { + return true; + } + if (parent->hasLoadedParent()) { + return true; + } + ++it; } } + return false; } diff --git a/src/scene/assetloader.cpp b/src/scene/assetloader.cpp index 0ac7d72549..f4dbb8fc37 100644 --- a/src/scene/assetloader.cpp +++ b/src/scene/assetloader.cpp @@ -145,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); @@ -227,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); @@ -238,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) { + int top = lua_gettop(*_luaState); std::shared_ptr parentAsset = _currentAsset; setCurrentAsset(asset); @@ -251,6 +257,7 @@ bool AssetLoader::loadAsset(std::shared_ptr asset) { if (!FileSys.fileExists(asset->assetFilePath())) { LERROR("Could not load asset '" << asset->assetFilePath() << "': File does not exist."); + lua_settop(*_luaState, top); return false; } @@ -258,9 +265,11 @@ bool AssetLoader::loadAsset(std::shared_ptr 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; } @@ -384,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; } @@ -392,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; } @@ -401,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; } @@ -411,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; } @@ -547,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; } @@ -565,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) { + 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; } @@ -583,6 +603,8 @@ void AssetLoader::setCurrentAsset(std::shared_ptr 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) { @@ -590,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 dependency = require(assetName); @@ -614,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; } @@ -622,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 child = request(assetName); @@ -635,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; } @@ -647,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; } @@ -665,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(); @@ -701,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) { diff --git a/src/scene/scene_lua.inl b/src/scene/scene_lua.inl index 89c037e9c7..25bfeea128 100644 --- a/src/scene/scene_lua.inl +++ b/src/scene/scene_lua.inl @@ -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; } diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index fa72088b0d..167c96d26f 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -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; } diff --git a/src/scripting/scriptengine_lua.inl b/src/scripting/scriptengine_lua.inl index 2f0096ae5a..c7e948f4be 100644 --- a/src/scripting/scriptengine_lua.inl +++ b/src/scripting/scriptengine_lua.inl @@ -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; } diff --git a/src/scripting/scriptscheduler_lua.inl b/src/scripting/scriptscheduler_lua.inl index 05e94a2590..489108ab67 100644 --- a/src/scripting/scriptscheduler_lua.inl +++ b/src/scripting/scriptscheduler_lua.inl @@ -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; } diff --git a/src/util/spicemanager_lua.inl b/src/util/spicemanager_lua.inl index f080bd4f8e..f93c4a32f1 100644 --- a/src/util/spicemanager_lua.inl +++ b/src/util/spicemanager_lua.inl @@ -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; } diff --git a/src/util/time_lua.inl b/src/util/time_lua.inl index 7d711e9151..9c9c36d65a 100644 --- a/src/util/time_lua.inl +++ b/src/util/time_lua.inl @@ -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; }