From 5eb5f83ad114e617ede10794317201896555b052 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Mon, 28 Apr 2025 10:38:02 -0500 Subject: [PATCH 1/7] replace some `#define`s with `constexpr` --- library/PluginManager.cpp | 1 + library/include/DataFuncs.h | 7 +++++++ library/include/LuaWrapper.h | 34 +++++++++++++++++----------------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/library/PluginManager.cpp b/library/PluginManager.cpp index 98a9eaeec4..575ebdc7f5 100644 --- a/library/PluginManager.cpp +++ b/library/PluginManager.cpp @@ -772,6 +772,7 @@ int Plugin::lua_cmd_wrapper(lua_State *state) int Plugin::lua_fun_wrapper(lua_State *state) { + using DFHack::LuaWrapper::UPVAL_CONTAINER_ID; auto cmd = (LuaFunction*)lua_touserdata(state, UPVAL_CONTAINER_ID); RefAutoinc lock(cmd->owner->access); diff --git a/library/include/DataFuncs.h b/library/include/DataFuncs.h index a8d2caca51..0b297a68e4 100644 --- a/library/include/DataFuncs.h +++ b/library/include/DataFuncs.h @@ -54,6 +54,7 @@ namespace df { T get_from_lua_state(lua_State* L, int idx) { using DFHack::LuaWrapper::field_error; + using DFHack::LuaWrapper::UPVAL_METHOD_NAME; using Ptr = std::add_pointer_t>; Ptr ptr{}; df::identity_traits::get()->lua_write(L, UPVAL_METHOD_NAME, &ptr, idx); @@ -69,6 +70,7 @@ namespace df { template T get_from_lua_state(lua_State* L, int idx) { + using DFHack::LuaWrapper::UPVAL_METHOD_NAME; T val{}; df::identity_traits::get()->lua_write(L, UPVAL_METHOD_NAME, &val, idx); return val; @@ -78,6 +80,7 @@ namespace df { requires std::is_invocable_r_v void call_and_push_impl(lua_State* L, int base, std::index_sequence, FT fun, ET... extra) { + using DFHack::LuaWrapper::UPVAL_METHOD_NAME; if constexpr (std::is_same_v) { std::invoke(fun, extra..., (get_from_lua_state(L, base+I))...); lua_pushnil(L); @@ -119,6 +122,7 @@ namespace df { struct function_wrapper { static const int num_args = sizeof...(AT)+1; static void execute(lua_State *L, int base, RT(CT::*mem_fun)(AT...)) { + using DFHack::LuaWrapper::UPVAL_METHOD_NAME; CT *self = (CT*)DFHack::LuaWrapper::get_object_addr(L, base++, UPVAL_METHOD_NAME, "invoke"); call_and_push(L, base, mem_fun, self); }; @@ -128,6 +132,7 @@ namespace df { struct function_wrapper { static const int num_args = sizeof...(AT)+1; static void execute(lua_State *L, int base, RT(CT::*mem_fun)(AT...) const) { + using DFHack::LuaWrapper::UPVAL_METHOD_NAME; CT *self = (CT*)DFHack::LuaWrapper::get_object_addr(L, base++, UPVAL_METHOD_NAME, "invoke"); call_and_push(L, base, mem_fun, self); }; @@ -154,6 +159,7 @@ namespace df { struct function_wrapper { static const int num_args = sizeof...(AT) + 1; static void execute(lua_State* L, int base, RT(CT::* mem_fun)(AT...)) { + using DFHack::LuaWrapper::UPVAL_METHOD_NAME; CT* self = (CT*)DFHack::LuaWrapper::get_object_addr(L, base++, UPVAL_METHOD_NAME, "invoke"); call_and_push(L, base, mem_fun, self); }; @@ -163,6 +169,7 @@ namespace df { struct function_wrapper { static const int num_args = sizeof...(AT) + 1; static void execute(lua_State* L, int base, RT(CT::* mem_fun)(AT...) const) { + using DFHack::LuaWrapper::UPVAL_METHOD_NAME; CT* self = (CT*)DFHack::LuaWrapper::get_object_addr(L, base++, UPVAL_METHOD_NAME, "invoke"); call_and_push(L, base, mem_fun, self); }; diff --git a/library/include/LuaWrapper.h b/library/include/LuaWrapper.h index 44bc19938c..b95713e572 100644 --- a/library/include/LuaWrapper.h +++ b/library/include/LuaWrapper.h @@ -70,51 +70,51 @@ namespace LuaWrapper { extern LuaToken DFHACK_PTR_IDTABLE_TOKEN; // Function registry names -#define DFHACK_CHANGEERROR_NAME "DFHack::ChangeError" -#define DFHACK_COMPARE_NAME "DFHack::ComparePtrs" -#define DFHACK_TYPE_TOSTRING_NAME "DFHack::TypeToString" -#define DFHACK_SIZEOF_NAME "DFHack::Sizeof" -#define DFHACK_DISPLACE_NAME "DFHack::Displace" -#define DFHACK_NEW_NAME "DFHack::New" -#define DFHACK_ASSIGN_NAME "DFHack::Assign" -#define DFHACK_IS_INSTANCE_NAME "DFHack::IsInstance" -#define DFHACK_DELETE_NAME "DFHack::Delete" -#define DFHACK_CAST_NAME "DFHack::Cast" + constexpr auto DFHACK_CHANGEERROR_NAME = "DFHack::ChangeError"; + constexpr auto DFHACK_COMPARE_NAME = "DFHack::ComparePtrs"; + constexpr auto DFHACK_TYPE_TOSTRING_NAME = "DFHack::TypeToString"; + constexpr auto DFHACK_SIZEOF_NAME = "DFHack::Sizeof"; + constexpr auto DFHACK_DISPLACE_NAME = "DFHack::Displace"; + constexpr auto DFHACK_NEW_NAME = "DFHack::New"; + constexpr auto DFHACK_ASSIGN_NAME = "DFHack::Assign"; + constexpr auto DFHACK_IS_INSTANCE_NAME = "DFHack::IsInstance"; + constexpr auto DFHACK_DELETE_NAME = "DFHack::Delete"; + constexpr auto DFHACK_CAST_NAME = "DFHack::Cast"; extern LuaToken DFHACK_EMPTY_TABLE_TOKEN; /* * Upvalue: contents of DFHACK_TYPETABLE_NAME */ -#define UPVAL_TYPETABLE lua_upvalueindex(1) + constexpr auto UPVAL_TYPETABLE = lua_upvalueindex(1); /* * Expected metatable of the current object. */ -#define UPVAL_METATABLE lua_upvalueindex(2) + constexpr auto UPVAL_METATABLE = lua_upvalueindex(2); /* * Table mapping field names to indices or data structure pointers. * Enum index table is linked into here via getmetatable($).__index. * Fields that are actually in UPVAL_METATABLE are marked with NULL light udata. */ -#define UPVAL_FIELDTABLE lua_upvalueindex(3) -#define UPVAL_METHOD_NAME lua_upvalueindex(3) + constexpr auto UPVAL_FIELDTABLE = lua_upvalueindex(3); + constexpr auto UPVAL_METHOD_NAME = lua_upvalueindex(3); /* * Only for containers: light udata with container identity. */ -#define UPVAL_CONTAINER_ID lua_upvalueindex(4) + constexpr auto UPVAL_CONTAINER_ID = lua_upvalueindex(4); /* * Only for containers: light udata with item identity. */ -#define UPVAL_ITEM_ID lua_upvalueindex(5) + constexpr auto UPVAL_ITEM_ID = lua_upvalueindex(5); /* * Only for containers: if not nil, overrides the item count. */ -#define UPVAL_ITEM_COUNT lua_upvalueindex(6) + constexpr auto UPVAL_ITEM_COUNT = lua_upvalueindex(6); inline void lua_dup(lua_State *state) { lua_pushvalue(state, -1); } inline void lua_swap(lua_State *state) { lua_insert(state, -2); } From c21478c256df11735aad4fed61e3faaf9d2ed99f Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Mon, 28 Apr 2025 10:56:52 -0500 Subject: [PATCH 2/7] minor quality issues `using` instead of `typedef` `[[noreturn]]` on a nonreturning function explicit `[[fallthrough]]` --- library/LuaWrapper.cpp | 6 +++--- library/include/LuaWrapper.h | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/library/LuaWrapper.cpp b/library/LuaWrapper.cpp index f9fd0e7832..8c4a17f8db 100644 --- a/library/LuaWrapper.cpp +++ b/library/LuaWrapper.cpp @@ -64,10 +64,10 @@ using namespace DFHack::LuaWrapper; /* */ -static int change_error(lua_State *state) +[[noreturn]] static int change_error(lua_State *state) { luaL_error(state, "Attempt to change a read-only table.\n"); - return 0; + std::abort(); // should never be reached but makes gcc happy } /** @@ -1642,7 +1642,7 @@ static void RenderType(lua_State *state, const compound_identity *node) case IDTYPE_UNION: // TODO: change this to union-type? what relies on this? lua_pushboolean(state, true); lua_setfield(state, ftable, "_union"); - // fall through + [[fallthrough]]; case IDTYPE_STRUCT: lua_pushstring(state, "struct-type"); lua_setfield(state, ftable, "_kind"); diff --git a/library/include/LuaWrapper.h b/library/include/LuaWrapper.h index b95713e572..6d77af87db 100644 --- a/library/include/LuaWrapper.h +++ b/library/include/LuaWrapper.h @@ -231,7 +231,8 @@ namespace LuaWrapper { /** * Wrap functions and add them to the table on the top of the stack. */ - typedef DFHack::FunctionReg FunctionReg; + using DFHack::FunctionReg; + void SetFunctionWrappers(lua_State *state, const FunctionReg *reg); int method_wrapper_core(lua_State *state, function_identity_base *id); From 00597e778e3c50976dab7b695565d9e2842de17c Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Mon, 28 Apr 2025 11:06:05 -0500 Subject: [PATCH 3/7] ColorText: `typedef` -> `using` --- library/include/ColorText.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/include/ColorText.h b/library/include/ColorText.h index f484e61d4b..f5768c0ffa 100644 --- a/library/include/ColorText.h +++ b/library/include/ColorText.h @@ -65,7 +65,7 @@ namespace DFHack class DFHACK_EXPORT color_ostream : public std::ostream { public: - typedef DFHack::color_value color_value; + using color_value = DFHack::color_value; private: color_value cur_color; From a012347210769b58ada362fd7fd77dc6bc734f2e Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Mon, 28 Apr 2025 11:39:08 -0500 Subject: [PATCH 4/7] Core.h: `typedef` -> `using` also this is C++, not C, so `typedef struct T T` doesn't belong here --- library/include/Core.h | 8 ++++---- library/include/DataDefs.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/library/include/Core.h b/library/include/Core.h index 9ef8fb8f0e..205b130b91 100644 --- a/library/include/Core.h +++ b/library/include/Core.h @@ -44,10 +44,6 @@ distribution. #include #include -#define DFH_MOD_SHIFT 1 -#define DFH_MOD_CTRL 2 -#define DFH_MOD_ALT 4 - struct WINDOW; struct lua_State; @@ -58,6 +54,10 @@ namespace df namespace DFHack { + constexpr auto DFH_MOD_SHIFT = 1; + constexpr auto DFH_MOD_CTRL = 2; + constexpr auto DFH_MOD_ALT = 4; + class Process; class Module; class Materials; diff --git a/library/include/DataDefs.h b/library/include/DataDefs.h index 59f47abcb6..e8e54fac41 100644 --- a/library/include/DataDefs.h +++ b/library/include/DataDefs.h @@ -35,7 +35,7 @@ distribution. #include "BitArray.h" #include "Export.h" -typedef struct lua_State lua_State; +struct lua_State; /* * Definitions of DFHack namespace structs used by generated headers. @@ -352,9 +352,9 @@ namespace DFHack }; #ifdef _MSC_VER - typedef void *virtual_ptr; + using virtual_ptr = void*; #else - typedef virtual_class *virtual_ptr; + using virtual_ptr = virtual_class*; #endif class DFHACK_EXPORT VMethodInterposeLinkBase; From aae16bd6578d1c9c2e24affd7e24ccfd5ba50a12 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Tue, 29 Apr 2025 10:59:06 -0500 Subject: [PATCH 5/7] DataIdentity: `typedef` -> `using` --- library/include/DataIdentity.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/library/include/DataIdentity.h b/library/include/DataIdentity.h index 7e1f8eaaea..5aa256809a 100644 --- a/library/include/DataIdentity.h +++ b/library/include/DataIdentity.h @@ -319,7 +319,7 @@ namespace df class DFHACK_EXPORT stl_ptr_vector_identity : public ptr_container_identity { public: - typedef std::vector container; + using container = std::vector; /* * This class assumes that std::vector is equivalent @@ -486,7 +486,7 @@ namespace df * in layout and behavior to BitArray for any T. */ - typedef BitArray container; + using container = BitArray; bit_array_identity(const enum_identity *ienum = NULL) : bit_container_identity(sizeof(container), &allocator_fn, ienum) @@ -516,7 +516,7 @@ namespace df class DFHACK_EXPORT stl_bit_vector_identity : public bit_container_identity { public: - typedef std::vector container; + using container = std::vector; stl_bit_vector_identity(const enum_identity *ienum = NULL) : bit_container_identity(sizeof(container), &df::allocator_fn, ienum) @@ -547,7 +547,7 @@ namespace df template class enum_list_attr_identity : public container_identity { public: - typedef enum_list_attr container; + using container = enum_list_attr; enum_list_attr_identity(const type_identity *item) : container_identity(sizeof(container), NULL, item, NULL) @@ -615,7 +615,7 @@ namespace df template struct DFHACK_EXPORT identity_traits> { static opaque_identity *get() { - typedef std::shared_ptr type; + using type = std::shared_ptr; static std::string name = std::string("shared_ptr<") + typeid(T).name() + ">"; static opaque_identity identity(sizeof(type), allocator_noassign_fn, name); return &identity; @@ -772,7 +772,7 @@ namespace df template inline const container_identity *identity_traits >::get() { - typedef std::vector container; + using container = std::vector; static const stl_container_identity identity("vector", identity_traits::get()); return &identity; } @@ -800,28 +800,28 @@ namespace df #ifdef BUILD_DFHACK_LIB template inline const container_identity *identity_traits >::get() { - typedef std::deque container; + using container = std::deque; static const stl_container_identity identity("deque", identity_traits::get()); return &identity; } template inline const container_identity *identity_traits >::get() { - typedef std::set container; + using container = std::set; static const ro_stl_container_identity identity("set", identity_traits::get()); return &identity; } template inline const container_identity *identity_traits>::get() { - typedef std::map container; + using container = std::map; static const ro_stl_assoc_container_identity identity("map", identity_traits::get(), identity_traits::get()); return &identity; } template inline const container_identity *identity_traits>::get() { - typedef std::unordered_map container; + using container = std::unordered_map; static const ro_stl_assoc_container_identity identity("unordered_map", identity_traits::get(), identity_traits::get()); return &identity; } @@ -834,7 +834,7 @@ namespace df template inline const container_identity *identity_traits >::get() { - typedef DfArray container; + using container = DfArray; static const stl_container_identity identity("DfArray", identity_traits::get()); return &identity; } From 5b5c5c6449cf983b92d9321ded86b09d3cc191a2 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Tue, 29 Apr 2025 11:00:33 -0500 Subject: [PATCH 6/7] LuaApi: template isntead of ad hoc macro can't get rid of the second one until c++26 --- library/LuaApi.cpp | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 228399c84f..077d8cd9c5 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -2667,20 +2667,17 @@ static const LuaWrapper::FunctionReg dfhack_world_module[] = { { NULL, NULL } }; -#define WORLD_GAMEMODE_WRAPPER(func) \ - static int world_gamemode_##func(lua_State *L) \ - { \ - int gametype = luaL_optint(L, 1, -1); \ - lua_pushboolean(L, World::func((df::game_type)gametype)); \ - return 1;\ - } -#define WORLD_GAMEMODE_FUNC(func) \ - {#func, world_gamemode_##func} +using gamemode_func = auto (df::game_type t) -> bool; +template +static int world_gamemode(lua_State* L) +{ + int gametype = luaL_optint(L, 1, -1); + lua_pushboolean(L, gmf((df::game_type)gametype)); + return 1; +} -WORLD_GAMEMODE_WRAPPER(isFortressMode); -WORLD_GAMEMODE_WRAPPER(isAdventureMode); -WORLD_GAMEMODE_WRAPPER(isArena); -WORLD_GAMEMODE_WRAPPER(isLegends); +#define WORLD_GAMEMODE_FUNC(func) \ + {#func, world_gamemode} static const luaL_Reg dfhack_world_funcs[] = { WORLD_GAMEMODE_FUNC(isFortressMode), From e803731cd14dbc8be19a473b09a8185c5b9dfabf Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Thu, 1 May 2025 20:33:55 -0500 Subject: [PATCH 7/7] LuaApi: templated lambda instead of macro --- library/LuaApi.cpp | 53 ++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 077d8cd9c5..927e2f6d72 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -3786,32 +3786,39 @@ static int internal_diffscan(lua_State *L) bool has_newv = !lua_isnil(L, 7); bool has_diffv = !lua_isnil(L, 8); -#define LOOP(esz, etype) \ - case esz: { \ - etype *pold = (etype*)old_data; \ - etype *pnew = (etype*)new_data; \ - etype oldv = (etype)luaL_optint(L, 6, 0); \ - etype newv = (etype)luaL_optint(L, 7, 0); \ - etype diffv = (etype)luaL_optint(L, 8, 0); \ - for (int i = start_idx; i < end_idx; i++) { \ - if (pold[i] == pnew[i]) continue; \ - if (has_oldv && pold[i] != oldv) continue; \ - if (has_newv && pnew[i] != newv) continue; \ - if (has_diffv && etype(pnew[i]-pold[i]) != diffv) continue; \ - lua_pushinteger(L, i); return 1; \ - } \ - break; \ - } + auto loop = [&]() -> std::optional + { + etype* pold = (etype*)old_data; + etype* pnew = (etype*)new_data; + etype oldv = (etype)luaL_optint(L, 6, 0); + etype newv = (etype)luaL_optint(L, 7, 0); + etype diffv = (etype)luaL_optint(L, 8, 0); + for (int i = start_idx; i < end_idx; i++) { + if (pold[i] == pnew[i]) continue; + if (has_oldv && pold[i] != oldv) continue; + if (has_newv && pnew[i] != newv) continue; + if (has_diffv && etype(pnew[i] - pold[i]) != diffv) continue; + return i; + } + return std::nullopt; + }; + + std::optional res; switch (eltsize) { - LOOP(1, uint8_t); - LOOP(2, uint16_t); - LOOP(4, uint32_t); - default: - luaL_argerror(L, 5, "invalid element size"); + case 1: + res = loop.operator()(); break; + case 2: + res = loop.operator()(); break; + case 4: + res = loop.operator()(); break; + default: + luaL_argerror(L, 5, "invalid element size"); } -#undef LOOP + if (res) + lua_pushinteger(L,*res); + else + lua_pushnil(L); - lua_pushnil(L); return 1; }