From b82a604c8da18d41232b8a9628f2b066c2df35a4 Mon Sep 17 00:00:00 2001 From: myk002 Date: Mon, 31 Oct 2022 11:43:37 -0700 Subject: [PATCH 1/5] factor out keys -> lua onInput code to LuaTools --- library/LuaApi.cpp | 44 +++++++++++++++++++++++++++++++++++++ library/include/LuaTools.h | 4 ++++ library/modules/Screen.cpp | 45 +------------------------------------- 3 files changed, 49 insertions(+), 44 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 4a97a0502..328d8ba4f 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -158,6 +158,50 @@ void Lua::GetVector(lua_State *state, std::vector &pvec) } } +void Lua::PushInterfaceKeys(lua_State *L, + const std::set &keys) { + lua_createtable(L, 0, keys.size() + 5); + + for (auto &key : keys) + { + if (auto name = enum_item_raw_key(key)) + lua_pushstring(L, name); + else + lua_pushinteger(L, key); + + lua_pushboolean(L, true); + lua_rawset(L, -3); + + int charval = Screen::keyToChar(key); + if (charval >= 0) + { + lua_pushinteger(L, charval); + lua_setfield(L, -2, "_STRING"); + } + } + + if (df::global::enabler) { + if (df::global::enabler->mouse_lbut_down) { + lua_pushboolean(L, true); + lua_setfield(L, -2, "_MOUSE_L"); + } + if (df::global::enabler->mouse_rbut_down) { + lua_pushboolean(L, true); + lua_setfield(L, -2, "_MOUSE_R"); + } + if (df::global::enabler->mouse_lbut) { + lua_pushboolean(L, true); + lua_setfield(L, -2, "_MOUSE_L_DOWN"); + df::global::enabler->mouse_lbut = 0; + } + if (df::global::enabler->mouse_rbut) { + lua_pushboolean(L, true); + lua_setfield(L, -2, "_MOUSE_R_DOWN"); + df::global::enabler->mouse_rbut = 0; + } + } +} + int Lua::PushPosXYZ(lua_State *state, df::coord pos) { if (!pos.isValid()) diff --git a/library/include/LuaTools.h b/library/include/LuaTools.h index 6dc5ae0bd..1b3c5d595 100644 --- a/library/include/LuaTools.h +++ b/library/include/LuaTools.h @@ -30,6 +30,8 @@ distribution. #include #include +#include "df/interfacest.h" + #include "ColorText.h" #include "DataDefs.h" @@ -321,6 +323,8 @@ namespace DFHack {namespace Lua { Push(L, val); lua_setfield(L, idx, name); } + DFHACK_EXPORT void PushInterfaceKeys(lua_State *L, const std::set &keys); + template void PushVector(lua_State *state, const T &pvec, bool addn = false) { diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index bff14a380..ebcc3f229 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -749,50 +749,7 @@ int dfhack_lua_viewscreen::do_input(lua_State *L) } lua_pushvalue(L, -2); - - lua_createtable(L, 0, keys->size()+3); - - for (auto it = keys->begin(); it != keys->end(); ++it) - { - auto key = *it; - - if (auto name = enum_item_raw_key(key)) - lua_pushstring(L, name); - else - lua_pushinteger(L, key); - - lua_pushboolean(L, true); - lua_rawset(L, -3); - - int charval = Screen::keyToChar(key); - if (charval >= 0) - { - lua_pushinteger(L, charval); - lua_setfield(L, -2, "_STRING"); - } - } - - if (enabler) - { - if (enabler->mouse_lbut_down) { - lua_pushboolean(L, true); - lua_setfield(L, -2, "_MOUSE_L"); - } - if (enabler->mouse_rbut_down) { - lua_pushboolean(L, true); - lua_setfield(L, -2, "_MOUSE_R"); - } - if (enabler->mouse_lbut) { - lua_pushboolean(L, true); - lua_setfield(L, -2, "_MOUSE_L_DOWN"); - enabler->mouse_lbut = 0; - } - if (enabler->mouse_rbut) { - lua_pushboolean(L, true); - lua_setfield(L, -2, "_MOUSE_R_DOWN"); - enabler->mouse_rbut = 0; - } - } + Lua::PushInterfaceKeys(L, *keys); lua_call(L, 2, 0); self->update_focus(L, -1); From e4d0bb9e46c234bd84ad9b5df10faa1caeccc0f0 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 4 Nov 2022 17:54:18 -0700 Subject: [PATCH 2/5] move Lua push methods into LuaTools.cpp --- library/LuaApi.cpp | 121 +--------------------------------------- library/LuaTools.cpp | 129 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 128 insertions(+), 122 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 328d8ba4f..9f713244d 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -68,6 +68,7 @@ distribution. #include "df/activity_entry.h" #include "df/activity_event.h" +#include "df/enabler.h" #include "df/job.h" #include "df/job_item.h" #include "df/building.h" @@ -78,9 +79,6 @@ distribution. #include "df/identity.h" #include "df/nemesis_record.h" #include "df/historical_figure.h" -#include "df/historical_entity.h" -#include "df/entity_position.h" -#include "df/entity_position_assignment.h" #include "df/histfig_entity_link_positionst.h" #include "df/plant_raw.h" #include "df/creature_raw.h" @@ -95,7 +93,6 @@ distribution. #include "df/unit_misc_trait.h" #include "df/proj_itemst.h" #include "df/itemdef.h" -#include "df/enabler.h" #include "df/feature_init.h" #include "df/plant.h" #include "df/specific_ref.h" @@ -117,122 +114,6 @@ using Random::PerlinNoise3D; void dfhack_printerr(lua_State *S, const std::string &str); -void Lua::Push(lua_State *state, const Units::NoblePosition &pos) -{ - lua_createtable(state, 0, 3); - Lua::PushDFObject(state, pos.entity); - lua_setfield(state, -2, "entity"); - Lua::PushDFObject(state, pos.assignment); - lua_setfield(state, -2, "assignment"); - Lua::PushDFObject(state, pos.position); - lua_setfield(state, -2, "position"); -} - -void Lua::Push(lua_State *state, df::coord pos) -{ - lua_createtable(state, 0, 3); - lua_pushinteger(state, pos.x); - lua_setfield(state, -2, "x"); - lua_pushinteger(state, pos.y); - lua_setfield(state, -2, "y"); - lua_pushinteger(state, pos.z); - lua_setfield(state, -2, "z"); -} - -void Lua::Push(lua_State *state, df::coord2d pos) -{ - lua_createtable(state, 0, 2); - lua_pushinteger(state, pos.x); - lua_setfield(state, -2, "x"); - lua_pushinteger(state, pos.y); - lua_setfield(state, -2, "y"); -} - -void Lua::GetVector(lua_State *state, std::vector &pvec) -{ - lua_pushnil(state); // first key - while (lua_next(state, 1) != 0) - { - pvec.push_back(lua_tostring(state, -1)); - lua_pop(state, 1); // remove value, leave key - } -} - -void Lua::PushInterfaceKeys(lua_State *L, - const std::set &keys) { - lua_createtable(L, 0, keys.size() + 5); - - for (auto &key : keys) - { - if (auto name = enum_item_raw_key(key)) - lua_pushstring(L, name); - else - lua_pushinteger(L, key); - - lua_pushboolean(L, true); - lua_rawset(L, -3); - - int charval = Screen::keyToChar(key); - if (charval >= 0) - { - lua_pushinteger(L, charval); - lua_setfield(L, -2, "_STRING"); - } - } - - if (df::global::enabler) { - if (df::global::enabler->mouse_lbut_down) { - lua_pushboolean(L, true); - lua_setfield(L, -2, "_MOUSE_L"); - } - if (df::global::enabler->mouse_rbut_down) { - lua_pushboolean(L, true); - lua_setfield(L, -2, "_MOUSE_R"); - } - if (df::global::enabler->mouse_lbut) { - lua_pushboolean(L, true); - lua_setfield(L, -2, "_MOUSE_L_DOWN"); - df::global::enabler->mouse_lbut = 0; - } - if (df::global::enabler->mouse_rbut) { - lua_pushboolean(L, true); - lua_setfield(L, -2, "_MOUSE_R_DOWN"); - df::global::enabler->mouse_rbut = 0; - } - } -} - -int Lua::PushPosXYZ(lua_State *state, df::coord pos) -{ - if (!pos.isValid()) - { - lua_pushnil(state); - return 1; - } - else - { - lua_pushinteger(state, pos.x); - lua_pushinteger(state, pos.y); - lua_pushinteger(state, pos.z); - return 3; - } -} - -int Lua::PushPosXY(lua_State *state, df::coord2d pos) -{ - if (!pos.isValid()) - { - lua_pushnil(state); - return 1; - } - else - { - lua_pushinteger(state, pos.x); - lua_pushinteger(state, pos.y); - return 2; - } -} - static df::coord2d CheckCoordXY(lua_State *state, int base, bool vararg = false) { df::coord2d p; diff --git a/library/LuaTools.cpp b/library/LuaTools.cpp index fea90b394..3cd6a1f7d 100644 --- a/library/LuaTools.cpp +++ b/library/LuaTools.cpp @@ -41,6 +41,7 @@ distribution. #include "modules/World.h" #include "modules/Gui.h" #include "modules/Job.h" +#include "modules/Screen.h" #include "modules/Translation.h" #include "modules/Units.h" @@ -51,11 +52,15 @@ distribution. #include "DFHackVersion.h" #include "PluginManager.h" +#include "df/building.h" +#include "df/enabler.h" +#include "df/entity_position.h" +#include "df/entity_position_assignment.h" +#include "df/historical_entity.h" +#include "df/item.h" #include "df/job.h" #include "df/job_item.h" -#include "df/building.h" #include "df/unit.h" -#include "df/item.h" #include "df/world.h" #include @@ -81,6 +86,126 @@ inline void AssertCoreSuspend(lua_State *state) assert(!Lua::IsCoreContext(state) || DFHack::Core::getInstance().isSuspended()); } +/* + * Lua Push methods + */ + +void DFHack::Lua::Push(lua_State *state, const Units::NoblePosition &pos) +{ + lua_createtable(state, 0, 3); + Lua::PushDFObject(state, pos.entity); + lua_setfield(state, -2, "entity"); + Lua::PushDFObject(state, pos.assignment); + lua_setfield(state, -2, "assignment"); + Lua::PushDFObject(state, pos.position); + lua_setfield(state, -2, "position"); +} + +void DFHack::Lua::Push(lua_State *state, df::coord pos) +{ + lua_createtable(state, 0, 3); + lua_pushinteger(state, pos.x); + lua_setfield(state, -2, "x"); + lua_pushinteger(state, pos.y); + lua_setfield(state, -2, "y"); + lua_pushinteger(state, pos.z); + lua_setfield(state, -2, "z"); +} + +void DFHack::Lua::Push(lua_State *state, df::coord2d pos) +{ + lua_createtable(state, 0, 2); + lua_pushinteger(state, pos.x); + lua_setfield(state, -2, "x"); + lua_pushinteger(state, pos.y); + lua_setfield(state, -2, "y"); +} + +void DFHack::Lua::GetVector(lua_State *state, std::vector &pvec) +{ + lua_pushnil(state); // first key + while (lua_next(state, 1) != 0) + { + pvec.push_back(lua_tostring(state, -1)); + lua_pop(state, 1); // remove value, leave key + } +} + +void DFHack::Lua::PushInterfaceKeys(lua_State *L, + const std::set &keys) { + lua_createtable(L, 0, keys.size() + 5); + + for (auto &key : keys) + { + if (auto name = enum_item_raw_key(key)) + lua_pushstring(L, name); + else + lua_pushinteger(L, key); + + lua_pushboolean(L, true); + lua_rawset(L, -3); + + int charval = Screen::keyToChar(key); + if (charval >= 0) + { + lua_pushinteger(L, charval); + lua_setfield(L, -2, "_STRING"); + } + } + + if (df::global::enabler) { + if (df::global::enabler->mouse_lbut_down) { + lua_pushboolean(L, true); + lua_setfield(L, -2, "_MOUSE_L"); + } + if (df::global::enabler->mouse_rbut_down) { + lua_pushboolean(L, true); + lua_setfield(L, -2, "_MOUSE_R"); + } + if (df::global::enabler->mouse_lbut) { + lua_pushboolean(L, true); + lua_setfield(L, -2, "_MOUSE_L_DOWN"); + df::global::enabler->mouse_lbut = 0; + } + if (df::global::enabler->mouse_rbut) { + lua_pushboolean(L, true); + lua_setfield(L, -2, "_MOUSE_R_DOWN"); + df::global::enabler->mouse_rbut = 0; + } + } +} + +int DFHack::Lua::PushPosXYZ(lua_State *state, df::coord pos) +{ + if (!pos.isValid()) + { + lua_pushnil(state); + return 1; + } + else + { + lua_pushinteger(state, pos.x); + lua_pushinteger(state, pos.y); + lua_pushinteger(state, pos.z); + return 3; + } +} + +int DFHack::Lua::PushPosXY(lua_State *state, df::coord2d pos) +{ + if (!pos.isValid()) + { + lua_pushnil(state); + return 1; + } + else + { + lua_pushinteger(state, pos.x); + lua_pushinteger(state, pos.y); + return 2; + } +} + /* * Public DF object reference handling API */ From 1d03afcd6faf71fe766af60b2b16efeaae7bafc1 Mon Sep 17 00:00:00 2001 From: myk002 Date: Mon, 7 Nov 2022 15:53:00 -0800 Subject: [PATCH 3/5] update changelog --- docs/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index 7aad40128..545ac2c68 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -70,6 +70,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `spectate`: improved documentation of features and functionality ## API +- ``Lua::PushInterfaceKeys()``: transforms viewscreen ``feed()`` keys into something that can be interpreted by lua-based widgets - Constructions module: added ``insert()`` to insert constructions into the game's sorted list. ## Lua From 4668d8c4a33bef21d0c3083c969a4b04b9995d4c Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 4 Nov 2022 17:40:50 -0700 Subject: [PATCH 4/5] Add Lua::Push method for maps --- library/include/LuaTools.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/include/LuaTools.h b/library/include/LuaTools.h index 1b3c5d595..e4245f09a 100644 --- a/library/include/LuaTools.h +++ b/library/include/LuaTools.h @@ -356,6 +356,13 @@ namespace DFHack {namespace Lua { lua_settable(state, -3); } + template + void Push(lua_State *L, const std::map &pmap) { + lua_createtable(L, 0, pmap.size()); + for (auto &entry : pmap) + TableInsert(L, entry.first, entry.second); + } + DFHACK_EXPORT void CheckPen(lua_State *L, Screen::Pen *pen, int index, bool allow_nil = false, bool allow_color = true); DFHACK_EXPORT bool IsCoreContext(lua_State *state); From d0753b4a9c0ffe56dfaa81a2947ccee32e3a759c Mon Sep 17 00:00:00 2001 From: myk002 Date: Mon, 7 Nov 2022 16:48:28 -0800 Subject: [PATCH 5/5] update changelog --- docs/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index 545ac2c68..7f15d5279 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -71,6 +71,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## API - ``Lua::PushInterfaceKeys()``: transforms viewscreen ``feed()`` keys into something that can be interpreted by lua-based widgets +- ``Lua::Push()``: now handles maps with otherwise supported keys and values - Constructions module: added ``insert()`` to insert constructions into the game's sorted list. ## Lua