Feature/lua function cleanup (#1719)

General cleanup of Lua functions and handling of variable extract from a Lua state
This commit is contained in:
Alexander Bock
2021-08-19 16:02:14 +02:00
committed by GitHub
parent 8175a7eb5b
commit af617d1d10
29 changed files with 860 additions and 2061 deletions
+1
View File
@@ -108,6 +108,7 @@ set(SOURCE_FILES
rendering/renderabletrailorbit.cpp
rendering/renderabletrailtrajectory.cpp
rendering/screenspacedashboard.cpp
rendering/screenspacedashboard_lua.inl
rendering/screenspaceframebuffer.cpp
rendering/screenspaceimagelocal.cpp
rendering/screenspaceimageonline.cpp
@@ -54,79 +54,10 @@ namespace {
#include "screenspacedashboard_codegen.cpp"
} // namespace
#include "screenspacedashboard_lua.inl"
namespace openspace {
namespace luascriptfunctions {
/**
* \ingroup LuaScripts
* addDashboardItemToScreenSpace(string, table):
*/
int addDashboardItemToScreenSpace(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addDashboardItemToScreenSpace");
const std::string& name = ghoul::lua::value<std::string>(L, 1);
const int type = lua_type(L, 2);
if (type != LUA_TTABLE) {
return ghoul::lua::luaError(L, "Expected argument of type 'table'");
}
ghoul::Dictionary d;
try {
ghoul::lua::luaDictionaryFromState(L, d);
}
catch (const ghoul::lua::LuaFormatException& e) {
LERRORC("addDashboardItem", e.what());
return 0;
}
ScreenSpaceRenderable* ssr = global::renderEngine->screenSpaceRenderable(name);
if (!ssr) {
return ghoul::lua::luaError(L, "Provided name is not a ScreenSpace item");
}
ScreenSpaceDashboard* dash = dynamic_cast<ScreenSpaceDashboard*>(ssr);
if (!dash) {
return ghoul::lua::luaError(
L,
"Provided name is a ScreenSpace item but not a dashboard"
);
}
dash->dashboard().addDashboardItem(DashboardItem::createFromDictionary(d));
lua_settop(L, 0);
return 0;
}
/**
* \ingroup LuaScripts
* removeDashboardItemsFromScreenSpace(string):
*/
int removeDashboardItemsFromScreenSpace(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::removeDashboardItemsFromScreenSpace");
const std::string& name = ghoul::lua::value<std::string>(L, 1);
ScreenSpaceRenderable* ssr = global::renderEngine->screenSpaceRenderable(name);
if (!ssr) {
return ghoul::lua::luaError(L, "Provided name is not a ScreenSpace item");
}
ScreenSpaceDashboard* dash = dynamic_cast<ScreenSpaceDashboard*>(ssr);
if (!dash) {
return ghoul::lua::luaError(
L,
"Provided name is a ScreenSpace item but not a dashboard"
);
}
dash->dashboard().clearDashboardItems();
return 0;
}
} // namespace luascriptfunctions
documentation::Documentation ScreenSpaceDashboard::Documentation() {
return codegen::doc<Parameters>("base_screenspace_dashboard");
}
@@ -0,0 +1,77 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
namespace openspace::luascriptfunctions {
/**
* \ingroup LuaScripts
* addDashboardItemToScreenSpace(string, table):
*/
int addDashboardItemToScreenSpace(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addDashboardItemToScreenSpace");
auto [name, d] = ghoul::lua::values<std::string, ghoul::Dictionary>(L);
ScreenSpaceRenderable* ssr = global::renderEngine->screenSpaceRenderable(name);
if (!ssr) {
return ghoul::lua::luaError(L, "Provided name is not a ScreenSpace item");
}
ScreenSpaceDashboard* dash = dynamic_cast<ScreenSpaceDashboard*>(ssr);
if (!dash) {
return ghoul::lua::luaError(
L,
"Provided name is a ScreenSpace item but not a dashboard"
);
}
dash->dashboard().addDashboardItem(DashboardItem::createFromDictionary(d));
return 0;
}
/**
* \ingroup LuaScripts
* removeDashboardItemsFromScreenSpace(string):
*/
int removeDashboardItemsFromScreenSpace(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::removeDashboardItemsFromScreenSpace");
const std::string name = ghoul::lua::value<std::string>(L);
ScreenSpaceRenderable* ssr = global::renderEngine->screenSpaceRenderable(name);
if (!ssr) {
return ghoul::lua::luaError(L, "Provided name is not a ScreenSpace item");
}
ScreenSpaceDashboard* dash = dynamic_cast<ScreenSpaceDashboard*>(ssr);
if (!dash) {
return ghoul::lua::luaError(
L,
"Provided name is a ScreenSpace item but not a dashboard"
);
}
dash->dashboard().clearDashboardItems();
return 0;
}
} // namespace openspace::luascriptfunctions
+51 -63
View File
@@ -88,43 +88,45 @@ ExoplanetSystem findExoplanetSystemInData(std::string_view starName) {
std::string name;
std::getline(ss, name, ',');
if (name.substr(0, name.length() - 2) == starName) {
std::string location_s;
std::getline(ss, location_s);
long location = std::stol(location_s.c_str());
if (name.substr(0, name.length() - 2) != starName) {
continue;
}
data.seekg(location);
data.read(reinterpret_cast<char*>(&p), sizeof(ExoplanetDataEntry));
std::string location_s;
std::getline(ss, location_s);
long location = std::stol(location_s.c_str());
sanitizeNameString(name);
data.seekg(location);
data.read(reinterpret_cast<char*>(&p), sizeof(ExoplanetDataEntry));
if (!hasSufficientData(p)) {
LWARNING(fmt::format("Insufficient data for exoplanet: '{}'", name));
continue;
}
sanitizeNameString(name);
system.planetNames.push_back(name);
system.planetsData.push_back(p);
if (!hasSufficientData(p)) {
LWARNING(fmt::format("Insufficient data for exoplanet: '{}'", name));
continue;
}
// Star data - Should not vary between planets, but one data entry might
// lack data for the host star while another does not. So for every planet,
// update star data if needed
const glm::vec3 pos{ p.positionX, p.positionY, p.positionZ };
if (system.starData.position != pos && isValidPosition(pos)) {
system.starData.position = pos;
}
if (system.starData.radius != p.rStar && !std::isnan(p.rStar)) {
system.starData.radius = p.rStar;
}
if (system.starData.bv != p.bmv && !std::isnan(p.bmv)) {
system.starData.bv = p.bmv;
}
if (system.starData.teff != p.teff && !std::isnan(p.teff)) {
system.starData.teff = p.teff;
}
if (system.starData.luminosity != p.luminosity && !std::isnan(p.luminosity)) {
system.starData.luminosity = p.luminosity;
}
system.planetNames.push_back(name);
system.planetsData.push_back(p);
// Star data - Should not vary between planets, but one data entry might lack data
// for the host star while another does not. So for every planet, update star data
// if needed
const glm::vec3 pos = glm::vec3(p.positionX, p.positionY, p.positionZ);
if (system.starData.position != pos && isValidPosition(pos)) {
system.starData.position = pos;
}
if (system.starData.radius != p.rStar && !std::isnan(p.rStar)) {
system.starData.radius = p.rStar;
}
if (system.starData.bv != p.bmv && !std::isnan(p.bmv)) {
system.starData.bv = p.bmv;
}
if (system.starData.teff != p.teff && !std::isnan(p.teff)) {
system.starData.teff = p.teff;
}
if (system.starData.luminosity != p.luminosity && !std::isnan(p.luminosity)) {
system.starData.luminosity = p.luminosity;
}
}
@@ -555,50 +557,40 @@ void createExoplanetSystem(const std::string& starName) {
int addExoplanetSystem(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::addExoplanetSystem");
std::variant<std::string, ghoul::Dictionary> v =
ghoul::lua::value<std::variant<std::string, ghoul::Dictionary>>(L);
const int t = lua_type(L, 1);
if (t == LUA_TSTRING) {
if (std::holds_alternative<std::string>(v)) {
// The user provided a single name
const std::string& starName = ghoul::lua::value<std::string>(L, 1);
std::string starName = std::get<std::string>(v);
createExoplanetSystem(starName);
}
else if (t == LUA_TTABLE) {
else {
// A list of names was provided
ghoul::Dictionary d;
ghoul::lua::luaDictionaryFromState(L, d);
for (size_t i = 1; i <= d.size(); ++i) {
if (!d.hasValue<std::string>(std::to_string(i))) {
ghoul::Dictionary starNames = ghoul::lua::value<ghoul::Dictionary>(L);
for (size_t i = 1; i <= starNames.size(); ++i) {
if (!starNames.hasValue<std::string>(std::to_string(i))) {
return ghoul::lua::luaError(
L, fmt::format("List item {} is of invalid type", i)
L,
fmt::format("List item {} is of invalid type", i)
);
}
const std::string& starName = d.value<std::string>(std::to_string(i));
const std::string& starName = starNames.value<std::string>(std::to_string(i));
createExoplanetSystem(starName);
}
lua_pop(L, 1);
}
else {
return ghoul::lua::luaError(L, "Invalid input");
}
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
int removeExoplanetSystem(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::removeExoplanetSystem");
std::string starName = ghoul::lua::value<std::string>(L);
const int StringLocation = -1;
const std::string starName = luaL_checkstring(L, StringLocation);
const std::string starIdentifier = createIdentifier(starName);
const std::string starIdentifier = createIdentifier(std::move(starName));
openspace::global::scriptEngine->queueScript(
"openspace.removeSceneGraphNode('" + starIdentifier + "');",
scripting::ScriptEngine::RemoteScripting::Yes
);
return 0;
}
@@ -656,7 +648,6 @@ std::vector<std::string> hostStarsWithSufficientData() {
// For easier read, sort by names and remove duplicates
std::sort(names.begin(), names.end());
names.erase(std::unique(names.begin(), names.end()), names.end());
return names;
}
@@ -664,15 +655,13 @@ int getListOfExoplanets(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::getListOfExoplanets");
std::vector<std::string> names = hostStarsWithSufficientData();
lua_newtable(L);
int number = 1;
for (const std::string& s : names) {
lua_pushstring(L, s.c_str());
ghoul::lua::push(L, s);
lua_rawseti(L, -2, number);
++number;
}
return 1;
}
@@ -683,16 +672,15 @@ int listAvailableExoplanetSystems(lua_State* L) {
std::string output;
for (auto it = names.begin(); it != names.end(); ++it) {
if (it != names.end()) {
output += *it + ", ";
}
output += *it + ", ";
}
output.pop_back();
output.pop_back();
LINFO(fmt::format(
"There is data available for the following {} exoplanet systems: {}",
names.size(), output
));
return 0;
}
+37 -113
View File
@@ -47,10 +47,8 @@ int addLayer(lua_State* L) {
ZoneScoped
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::addLayer");
// String arguments
const std::string& globeName = ghoul::lua::value<std::string>(L, 1);
const std::string& layerGroupName = ghoul::lua::value<std::string>(L, 2);
auto [globeName, layerGroupName, layerDict] =
ghoul::lua::values<std::string, std::string, ghoul::Dictionary>(L);
// Get the node and make sure it exists
SceneGraphNode* n = global::renderEngine->scene()->sceneGraphNode(globeName);
@@ -73,23 +71,10 @@ int addLayer(lua_State* L) {
}
// Get the dictionary defining the layer
ghoul::Dictionary d;
try {
ghoul::lua::luaDictionaryFromState(L, d);
}
catch (const ghoul::lua::LuaFormatException& e) {
LERRORC("addLayerFromDictionary", e.what());
lua_settop(L, 0);
return 0;
}
lua_settop(L, 0);
Layer* layer = globe->layerManager().addLayer(groupID, d);
Layer* layer = globe->layerManager().addLayer(groupID, layerDict);
if (layer) {
layer->initialize();
}
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -98,11 +83,8 @@ int addLayer(lua_State* L) {
*/
int deleteLayer(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::deleteLayer");
const std::string& globeName = luaL_checkstring(L, 1);
const std::string& layerGroupName = luaL_checkstring(L, 2);
const std::string& layerName = luaL_checkstring(L, 3);
lua_pop(L, 3);
auto [globeName, layerGroupName, layerName] =
ghoul::lua::values<std::string, std::string, std::string>(L);
// Get the node and make sure it exists
SceneGraphNode* n = global::renderEngine->scene()->sceneGraphNode(globeName);
@@ -125,17 +107,12 @@ 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;
}
int getLayers(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::getLayers");
const std::string& globeIdentifier = ghoul::lua::value<std::string>(L, 1);
const std::string& layer = ghoul::lua::value<std::string>(L, 2);
lua_pop(L, 2);
auto [globeIdentifier, layer] = ghoul::lua::values<std::string, std::string>(L);
SceneGraphNode* n = sceneGraphNode(globeIdentifier);
if (!n) {
@@ -168,12 +145,8 @@ int getLayers(lua_State* L) {
int moveLayer(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 4, "lua::moveLayer");
const std::string& globeIdentifier = ghoul::lua::value<std::string>(L, 1);
const std::string& layer = ghoul::lua::value<std::string>(L, 2);
int oldPosition = ghoul::lua::value<int>(L, 3);
int newPosition = ghoul::lua::value<int>(L, 4);
lua_pop(L, 4);
auto [globeIdentifier, layer, oldPosition, newPosition] =
ghoul::lua::values<std::string, std::string, int, int>(L);
if (oldPosition == newPosition) {
return 0;
@@ -197,22 +170,16 @@ int moveLayer(lua_State* L) {
globebrowsing::LayerGroup& lg = globe->layerManager().layerGroup(group);
lg.moveLayers(oldPosition, newPosition);
return 0;
}
int goToChunk(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 4, "lua::goToChunk");
auto [identifier, x, y, level] = ghoul::lua::values<std::string, int, int, int>(L);
const std::string& globeIdentifier = ghoul::lua::value<std::string>(L, 1);
const int x = ghoul::lua::value<int>(L, 2);
const int y = ghoul::lua::value<int>(L, 3);
const int level = ghoul::lua::value<int>(L, 4);
lua_pop(L, 4);
SceneGraphNode* n = sceneGraphNode(globeIdentifier);
SceneGraphNode* n = sceneGraphNode(identifier);
if (!n) {
return ghoul::lua::luaError(L, "Unknown globe name: " + globeIdentifier);
return ghoul::lua::luaError(L, "Unknown globe name: " + identifier);
}
const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
@@ -221,22 +188,18 @@ int goToChunk(lua_State* L) {
}
global::moduleEngine->module<GlobeBrowsingModule>()->goToChunk(*globe, x, y, level);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
int goToGeo(lua_State* L) {
int nArguments = ghoul::lua::checkArgumentsAndThrow(L, { 2, 4 }, "lua::goToGeo");
ghoul::lua::checkArgumentsAndThrow(L, { 2, 4 }, "lua::goToGeo");
// Check if the user provided a Scene graph node identifier as the first argument.
// lua_isstring returns true for both numbers and strings, so better use !lua_isnumber
const bool providedGlobeIdentifier = !lua_isnumber(L, 1);
const int parameterOffset = providedGlobeIdentifier ? 1 : 0;
const SceneGraphNode* n;
if (providedGlobeIdentifier) {
const std::string& globeIdentifier = ghoul::lua::value<std::string>(L, 1);
const std::string& globeIdentifier = ghoul::lua::value<std::string>(L);
n = sceneGraphNode(globeIdentifier);
if (!n) {
return ghoul::lua::luaError(L, "Unknown globe name: " + globeIdentifier);
@@ -249,8 +212,8 @@ int goToGeo(lua_State* L) {
}
}
const double latitude = ghoul::lua::value<double>(L, parameterOffset + 1);
const double longitude = ghoul::lua::value<double>(L, parameterOffset + 2);
auto [latitude, longitude, altitude] =
ghoul::lua::values<double, double, std::optional<double>>(L);
const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
if (!globe) {
@@ -258,32 +221,29 @@ int goToGeo(lua_State* L) {
return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe");
}
else {
return ghoul::lua::luaError(L,
"Current anchor node is not a RenderableGlobe. "
"Either change the anchor to a globe, or specify a globe identifier "
"as the first argument"
return ghoul::lua::luaError(
L,
"Current anchor node is not a RenderableGlobe. Either change the anchor "
"to a globe, or specify a globe identifier as the first argument"
);
}
}
if (nArguments == parameterOffset + 2) {
global::moduleEngine->module<GlobeBrowsingModule>()->goToGeo(
*globe, latitude, longitude
);
}
else if (nArguments == parameterOffset + 3) {
const double altitude = ghoul::lua::value<double>(L, parameterOffset + 3);
if (altitude.has_value()) {
global::moduleEngine->module<GlobeBrowsingModule>()->goToGeo(
*globe,
latitude,
longitude,
altitude
*altitude
);
}
else {
global::moduleEngine->module<GlobeBrowsingModule>()->goToGeo(
*globe,
latitude,
longitude
);
}
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -394,12 +354,8 @@ int flyToGeo(lua_State* L) {
int getLocalPositionFromGeo(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 4, "lua::getLocalPositionFromGeo");
const std::string& globeIdentifier = ghoul::lua::value<std::string>(L, 1);
const double latitude = ghoul::lua::value<double>(L, 2);
const double longitude = ghoul::lua::value<double>(L, 3);
const double altitude = ghoul::lua::value<double>(L, 4);
lua_pop(L, 4);
auto [globeIdentifier, latitude, longitude, altitude] =
ghoul::lua::values<std::string, double, double, double>(L);
SceneGraphNode* n = sceneGraphNode(globeIdentifier);
if (!n) {
@@ -411,16 +367,8 @@ int getLocalPositionFromGeo(lua_State* L) {
}
GlobeBrowsingModule& mod = *(global::moduleEngine->module<GlobeBrowsingModule>());
glm::vec3 pos = mod.cartesianCoordinatesFromGeo(
*globe,
latitude,
longitude,
altitude
);
ghoul::lua::push(L, pos.x, pos.y, pos.z);
ghoul_assert(lua_gettop(L) == 3, "Incorrect number of items left on stack");
glm::vec3 p = mod.cartesianCoordinatesFromGeo(*globe, latitude, longitude, altitude);
ghoul::lua::push(L, p.x, p.y, p.z);
return 3;
}
@@ -450,72 +398,48 @@ int getGeoPositionForCamera(lua_State* L) {
posHandle.centerToReferenceSurface);
ghoul::lua::push(L, glm::degrees(geo2.lat), glm::degrees(geo2.lon), altitude);
ghoul_assert(lua_gettop(L) == 3, "Incorrect number of items left on stack");
return 3;
}
int loadWMSCapabilities(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::loadWMSCapabilities");
std::string name = ghoul::lua::value<std::string>(L, 1);
std::string globe = ghoul::lua::value<std::string>(L, 2);
std::string url = ghoul::lua::value<std::string>(L, 3);
auto [name, globe, url] =
ghoul::lua::values<std::string, std::string, std::string>(L);
global::moduleEngine->module<GlobeBrowsingModule>()->loadWMSCapabilities(
std::move(name),
std::move(globe),
std::move(url)
);
lua_pop(L, 3);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
int removeWMSServer(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::removeWMSServer");
const std::string& name = ghoul::lua::value<std::string>(
L,
1,
ghoul::lua::PopValue::Yes
);
const std::string name = ghoul::lua::value<std::string>(L);
global::moduleEngine->module<GlobeBrowsingModule>()->removeWMSServer(name);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
int capabilities(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::capabilities");
const std::string name = ghoul::lua::value<std::string>(L);
const std::string& name = ghoul::lua::value<std::string>(
L,
1,
ghoul::lua::PopValue::Yes
);
GlobeBrowsingModule::Capabilities cap =
global::moduleEngine->module<GlobeBrowsingModule>()->capabilities(name);
lua_newtable(L);
for (unsigned long i = 0; i < cap.size(); ++i) {
for (size_t i = 0; i < cap.size(); ++i) {
const GlobeBrowsingModule::Layer& l = cap[i];
lua_newtable(L);
ghoul::lua::push(L, "Name", l.name);
lua_settable(L, -3);
ghoul::lua::push(L, "URL", l.url);
lua_settable(L, -3);
lua_rawseti(L, -2, i + 1);
}
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
+16 -26
View File
@@ -30,48 +30,38 @@ int convertFromRaDec(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::convertFromRaDec");
glm::dvec2 degrees = glm::dvec2(0.0);
if (lua_type(L, 1) == LUA_TSTRING && lua_type(L, 2) == LUA_TSTRING) {
std::string ra = ghoul::lua::value<std::string>(L, 1);
std::string dec = ghoul::lua::value<std::string>(L, 2);
if (ghoul::lua::hasValue<std::string>(L, 1) &&
ghoul::lua::hasValue<std::string>(L, 2))
{
auto [ra, dec] = ghoul::lua::values<std::string, std::string>(L);
degrees = icrsToDecimalDegrees(ra, dec);
}
else if (lua_type(L, 1) == LUA_TNUMBER && lua_type(L, 2) == LUA_TNUMBER) {
degrees.x = ghoul::lua::value<double>(L, 1);
degrees.y = ghoul::lua::value<double>(L, 2);
else if (ghoul::lua::hasValue<double>(L, 1) && ghoul::lua::hasValue<double>(L, 2)) {
auto [x, y] = ghoul::lua::values<double, double>(L);
degrees.x = x;
degrees.y = y;
}
else {
throw ghoul::lua::LuaRuntimeException("lua::convertFromRaDec: Ra and Dec have to "
"be of the same type, either String or Number"
throw ghoul::lua::LuaRuntimeException(
"Ra and Dec have to be of the same type, either String or Number"
);
}
double distance = ghoul::lua::value<double>(L, 3);
lua_settop(L, 0);
double distance = ghoul::lua::value<double>(L);
glm::dvec3 pos = icrsToGalacticCartesian(degrees.x, degrees.y, distance);
ghoul::lua::push(L, pos);
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
int convertToRaDec(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::convertToRaDec");
auto [x, y, z] = ghoul::lua::values<double, double, double>(L);
double x = ghoul::lua::value<double>(L, 1);
double y = ghoul::lua::value<double>(L, 2);
double z = ghoul::lua::value<double>(L, 3);
lua_settop(L, 0);
glm::dvec3 deg = galacticCartesianToIcrs(x, y, z);
std::pair<std::string, std::string> raDecPair = decimalDegreesToIcrs(deg.x, deg.y);
glm::dvec3 degrees = galacticCartesianToIcrs(x, y, z);
std::pair<std::string, std::string> raDecPair
= decimalDegreesToIcrs(degrees.x, degrees.y);
ghoul::lua::push(L, raDecPair.first); // Ra
ghoul::lua::push(L, raDecPair.second); // Dec
ghoul::lua::push(L, degrees.z); // Distance
ghoul_assert(lua_gettop(L) == 3, "Incorrect number of items left on stack");
// Ra, Dec, Distance
ghoul::lua::push(L, raDecPair.first, raDecPair.second, deg.z);
return 3;
}
+13 -91
View File
@@ -33,95 +33,37 @@
namespace openspace::luascriptfunctions {
int createStateMachine(lua_State* L) {
const int nArguments = ghoul::lua::checkArgumentsAndThrow(
L,
{ 2, 3 },
"lua::createStateMachine"
);
// If three arguments, a start state was included
std::optional<std::string> startState = std::nullopt;
if (nArguments > 2) {
startState = ghoul::lua::value<std::string>(L, 3, ghoul::lua::PopValue::Yes);
}
// Last dictionary is on top of the stack
ghoul::Dictionary transitions;
try {
ghoul::lua::luaDictionaryFromState(L, transitions);
}
catch (const ghoul::lua::LuaFormatException& e) {
LERRORC("createStateMachine", e.what());
return 0;
}
// Pop, so that first dictionary is on top and can be read
lua_pop(L, 1);
ghoul::Dictionary states;
try {
ghoul::lua::luaDictionaryFromState(L, states);
}
catch (const ghoul::lua::LuaFormatException& e) {
LERRORC("createStateMachine", e.what());
return 0;
}
ghoul::lua::checkArgumentsAndThrow(L, { 2, 3 }, "lua::createStateMachine");
auto [states, transitions, startState] = ghoul::lua::values<
ghoul::Dictionary, ghoul::Dictionary, std::optional<std::string>
>(L);
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
module->initializeStateMachine(states, transitions, startState);
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
module->initializeStateMachine(
std::move(states),
std::move(transitions),
std::move(startState)
);
return 0;
}
int goToState(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::goToState");
const bool isString = (lua_isstring(L, 1) != 0);
std::string newState = ghoul::lua::value<std::string>(L);
if (!isString) {
lua_settop(L, 0);
const char* msg = lua_pushfstring(
L,
"%s expected, got %s",
lua_typename(L, LUA_TSTRING),
luaL_typename(L, 0)
);
return luaL_error(L, "bad argument #%d (%s)", 1, msg);
}
const std::string newState = lua_tostring(L, 1);
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
module->transitionTo(newState);
LINFOC("StateMachine", "Transitioning to " + newState);
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
int setInitialState(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::setStartState");
const bool isString = (lua_isstring(L, 1) != 0);
std::string startState = ghoul::lua::value<std::string>(L);
if (!isString) {
lua_settop(L, 0);
const char* msg = lua_pushfstring(
L,
"%s expected, got %s",
lua_typename(L, LUA_TSTRING),
luaL_typename(L, 0)
);
return luaL_error(L, "bad argument #%d (%s)", 1, msg);
}
const std::string startState = lua_tostring(L, 1);
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
module->setInitialState(startState);
LINFOC("StateMachine", "Initial state set to: " + startState);
lua_settop(L, 0);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
@@ -130,9 +72,7 @@ int currentState(lua_State* L) {
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
std::string currentState = module->currentState();
lua_pushstring(L, currentState.c_str());
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
ghoul::lua::push(L, std::move(currentState));
return 1;
}
@@ -141,32 +81,16 @@ int possibleTransitions(lua_State* L) {
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
std::vector<std::string> transitions = module->possibleTransitions();
ghoul::lua::push(L, transitions);
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
int canGoToState(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::canGoToState");
const bool isString = (lua_isstring(L, 1) != 0);
std::string state = ghoul::lua::value<std::string>(L);
if (!isString) {
lua_settop(L, 0);
const char* msg = lua_pushfstring(
L,
"%s expected, got %s",
lua_typename(L, LUA_TSTRING),
luaL_typename(L, 0)
);
return luaL_error(L, "bad argument #%d (%s)", 1, msg);
}
const std::string state = lua_tostring(L, 1);
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
ghoul::lua::push(L, module->canGoToState(state));
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
@@ -174,7 +98,6 @@ int printCurrentStateInfo(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::printCurrentStateInfo");
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
if (module->hasStateMachine()) {
std::string currentState = module->currentState();
std::vector<std::string> transitions = module->possibleTransitions();
@@ -188,7 +111,6 @@ int printCurrentStateInfo(lua_State* L) {
LINFOC("StateMachine", "No state machine has been created");
}
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 1;
}