Skip to content

Commit

Permalink
support call-by-reference in wrapped functions
Browse files Browse the repository at this point in the history
this should allow a function (or method) with call-by-reference parameters to be wrapped and exported to lua. the wrapper will translate an equivalent pointer type to the reference type (and throw if the pointer is null)
  • Loading branch information
ab9rf committed Jan 9, 2025
1 parent 0a8b233 commit a356ba6
Showing 1 changed file with 22 additions and 3 deletions.
25 changes: 22 additions & 3 deletions library/include/DataFuncs.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,28 @@ namespace df {
template<typename RT>
concept isPrimitive = identity_traits<RT>::is_primitive || std::is_enum_v<RT> || std::is_void_v<RT>;

template<typename T>
T get_from_lua_state(lua_State* L, int idx) {
T val;
// handle call-by-reference function arguments by converting pointers to a reference
// will throw if lua code tries to pass a null pointer
template<typename T> requires std::is_reference_v<T>
T get_from_lua_state(lua_State* L, int idx)
{
using DFHack::LuaWrapper::field_error;
using Ptr = std::add_pointer_t<std::remove_reference_t<T>>;
Ptr ptr{};
df::identity_traits<Ptr>::get()->lua_write(L, UPVAL_METHOD_NAME, &ptr, idx);
if (ptr == nullptr)
{
field_error(L, UPVAL_METHOD_NAME, "cannot convert null pointer to reference", "call");
}
return *ptr;
}

// handle call-by-value function arguments. only semi-regular types are allowed
// (semi-regular covers copyable and default-constructible)
template<std::semiregular T>
T get_from_lua_state(lua_State* L, int idx)
{
T val{};
df::identity_traits<T>::get()->lua_write(L, UPVAL_METHOD_NAME, &val, idx);
return val;
}
Expand Down

0 comments on commit a356ba6

Please sign in to comment.