2022-05-14 19:53:46 +02:00
|
|
|
/*
|
2025-07-05 19:24:10 +02:00
|
|
|
* Copyright (c) 2022-2025, Edoardo Lolletti (edo9300) <edoardo762@gmail.com>
|
2022-05-14 19:53:46 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
|
*/
|
|
|
|
|
#ifndef FUNCTION_ARRAY_HELPER_H
|
|
|
|
|
#define FUNCTION_ARRAY_HELPER_H
|
|
|
|
|
|
2025-07-05 19:24:10 +02:00
|
|
|
#include "scriptlib.h"
|
2023-11-21 11:56:23 +01:00
|
|
|
|
2025-07-05 19:24:10 +02:00
|
|
|
#include <meta>
|
|
|
|
|
#include <string_view>
|
2023-12-03 14:43:52 +01:00
|
|
|
|
2025-07-05 19:24:10 +02:00
|
|
|
#define LUA_NAMESPACE lua_functions
|
2025-07-05 19:50:36 +02:00
|
|
|
|
2025-07-05 19:24:10 +02:00
|
|
|
#define STR_HELPER(x) #x
|
|
|
|
|
#define STR(x) STR_HELPER(x)
|
2024-03-08 22:39:06 +01:00
|
|
|
|
2025-07-05 19:24:10 +02:00
|
|
|
#define MAKE_LUA_MODULE_IMPL(module) c_lua_##module##_
|
|
|
|
|
#define MAKE_LUA_MODULE(module) MAKE_LUA_MODULE_IMPL(module)
|
2024-03-08 22:39:06 +01:00
|
|
|
|
2025-07-05 19:24:10 +02:00
|
|
|
#define LUA_PREFIX STR(MAKE_LUA_MODULE(LUA_MODULE))
|
2024-03-08 22:39:06 +01:00
|
|
|
|
2025-07-05 19:24:10 +02:00
|
|
|
#define MAKE_LUA_NAME_IMPL(module, name) c_lua_##module##_##name
|
|
|
|
|
#define MAKE_LUA_NAME(module, name) MAKE_LUA_NAME_IMPL(module, name)
|
|
|
|
|
#define LUA_FUNCTION(name) [[maybe_unused]] static int32_t MAKE_LUA_NAME(LUA_MODULE,name) \
|
|
|
|
|
([[maybe_unused]] lua_State* const L, \
|
|
|
|
|
[[maybe_unused]] LUA_CLASS* const self, [[maybe_unused]] duel* const pduel)
|
2024-03-08 22:39:06 +01:00
|
|
|
|
2025-07-05 19:24:10 +02:00
|
|
|
#define LUA_STATIC_FUNCTION(name) [[maybe_unused]] static int32_t MAKE_LUA_NAME(LUA_MODULE,name) \
|
|
|
|
|
([[maybe_unused]] lua_State* const L, [[maybe_unused]] duel* const pduel)
|
2024-03-08 22:39:06 +01:00
|
|
|
|
2025-07-05 19:24:10 +02:00
|
|
|
#define LUA_FUNCTION_ALIAS(name) [[maybe_unused]] static lua_alias MAKE_LUA_NAME(LUA_MODULE,name)
|
2024-03-08 22:39:06 +01:00
|
|
|
|
2025-07-05 19:24:10 +02:00
|
|
|
#define LUA_FUNCTION_EXISTING(name,...) [[maybe_unused]] [[=aliases(__VA_ARGS__)]] static int32_t MAKE_LUA_NAME(LUA_MODULE,name) \
|
|
|
|
|
([[maybe_unused]] lua_State* const L)
|
2022-05-14 19:53:46 +02:00
|
|
|
|
2025-07-05 19:24:10 +02:00
|
|
|
namespace {
|
|
|
|
|
struct aliases { lua_CFunction field; };
|
|
|
|
|
|
|
|
|
|
struct lua_alias { };
|
|
|
|
|
template<std::meta::info Namespace>
|
|
|
|
|
constexpr auto get_lua_functions() {
|
|
|
|
|
constexpr auto lua_symbols = [] {
|
|
|
|
|
constexpr auto ctx = std::meta::access_context::current();
|
|
|
|
|
std::vector<std::meta::info> res;
|
|
|
|
|
template for (constexpr auto M : define_static_array(members_of(Namespace, ctx))) {
|
|
|
|
|
if constexpr(identifier_of(M).starts_with(LUA_PREFIX)) {
|
|
|
|
|
res.push_back(M);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return define_static_array(res);
|
|
|
|
|
}();
|
|
|
|
|
std::array<luaL_Reg, lua_symbols.size()+1> ret_array{};
|
|
|
|
|
int i = 0;
|
2026-02-23 23:45:52 +01:00
|
|
|
template for (constexpr auto M : define_static_array(lua_symbols)) {
|
2025-07-05 19:24:10 +02:00
|
|
|
constexpr auto identifier = identifier_of(M).substr(std::string_view{LUA_PREFIX}.size());
|
|
|
|
|
if constexpr(is_function(M)) {
|
2026-02-23 23:45:52 +01:00
|
|
|
constexpr auto annotations = define_static_array(annotations_of_with_type(M, ^^aliases));
|
2025-07-05 19:24:10 +02:00
|
|
|
static_assert(annotations.size() <= 1);
|
|
|
|
|
if constexpr(annotations.size() == 1) {
|
|
|
|
|
constexpr auto annotation = extract<aliases>(annotations[0]);
|
|
|
|
|
static_assert(annotation.field != nullptr);
|
|
|
|
|
ret_array[i] = luaL_Reg{identifier.data(), annotation.field};
|
|
|
|
|
} else {
|
|
|
|
|
static constexpr auto func_ptr = [:M:];
|
|
|
|
|
static constexpr auto parameters = define_static_array(parameters_of(M));
|
|
|
|
|
static constexpr auto num_of_parameters = parameters.size();
|
|
|
|
|
ret_array[i] = luaL_Reg{identifier.data(), [](lua_State* L) -> int {
|
|
|
|
|
using namespace scriptlib;
|
|
|
|
|
#if defined(LUA_CLASS)
|
|
|
|
|
if constexpr(num_of_parameters == 3) {
|
|
|
|
|
return func_ptr(L, lua_get<LUA_CLASS*, true>(L, 1), lua_get<duel*>(L));
|
|
|
|
|
} else
|
|
|
|
|
#endif
|
|
|
|
|
if constexpr(num_of_parameters == 2) {
|
|
|
|
|
return func_ptr(L, lua_get<duel*>(L));
|
|
|
|
|
}
|
|
|
|
|
}};
|
|
|
|
|
}
|
|
|
|
|
} else if constexpr(is_variable(M)) {
|
|
|
|
|
static_assert(type_of(M) == ^^lua_alias);
|
|
|
|
|
ret_array[i] = luaL_Reg{identifier.data(), ret_array[i - 1].func};
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
ret_array[i] = {nullptr,nullptr};
|
|
|
|
|
return ret_array;
|
2022-05-14 19:53:46 +02:00
|
|
|
}
|
2024-03-08 22:39:06 +01:00
|
|
|
}
|
|
|
|
|
|
2025-07-05 19:24:10 +02:00
|
|
|
#undef LUA_PREFIX
|
|
|
|
|
#undef STR
|
|
|
|
|
#undef STR_HELPER
|
|
|
|
|
#undef MAKE_LUA_MODULE_IMPL
|
|
|
|
|
#undef MAKE_LUA_MODULE
|
2022-05-14 19:53:46 +02:00
|
|
|
|
2025-07-05 19:24:10 +02:00
|
|
|
#define GET_LUA_FUNCTIONS_ARRAY() get_lua_functions<^^LUA_NAMESPACE>()
|
2022-05-14 19:53:46 +02:00
|
|
|
|
|
|
|
|
#endif // FUNCTION_ARRAY_HELPER_H
|