Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 29 additions & 30 deletions Distribution/LuaBridge/LuaBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -8003,8 +8003,7 @@ bool overload_check_args_impl(lua_State* L, int start, std::index_sequence<I...>
template <class ArgsPack>
bool overload_check_args(lua_State* L, int start)
{
return overload_check_args_impl<ArgsPack>(L, start,
std::make_index_sequence<std::tuple_size_v<ArgsPack>>{});
return overload_check_args_impl<ArgsPack>(L, start, std::make_index_sequence<std::tuple_size_v<ArgsPack>>{});
}

template <class ArgsPack>
Expand Down Expand Up @@ -8813,7 +8812,7 @@ int constructor_container_proxy(lua_State* L)
try
{
#endif
object = constructor<T, Args>::construct(detail::make_arguments_list<Args, 2>(L));
object = constructor<T, Args>::construct(detail::make_arguments_list<Args, 1>(L));

#if LUABRIDGE_HAS_EXCEPTIONS
}
Expand All @@ -8833,7 +8832,7 @@ int constructor_container_proxy(lua_State* L)
template <class T, class Args>
int constructor_placement_proxy(lua_State* L)
{
auto args = make_arguments_list<Args, 2>(L);
auto args = make_arguments_list<Args, 1>(L);

std::error_code ec;
auto* value = UserdataValue<T>::place(L, ec);
Expand Down Expand Up @@ -8873,7 +8872,7 @@ struct constructor_forwarder
using FnTraits = function_traits<F>;
using FnArgs = remove_first_type_t<typename FnTraits::argument_types>;

auto args = make_arguments_list<FnArgs, 2>(L);
auto args = make_arguments_list<FnArgs, 1>(L);

std::error_code ec;
auto* value = UserdataValue<T>::place(L, ec);
Expand Down Expand Up @@ -8988,7 +8987,7 @@ struct container_forwarder
try
{
#endif
object = container_constructor<C>::construct(m_func, make_arguments_list<FnArgs, 2>(L));
object = container_constructor<C>::construct(m_func, make_arguments_list<FnArgs, 1>(L));

#if LUABRIDGE_HAS_EXCEPTIONS
}
Expand Down Expand Up @@ -9408,7 +9407,7 @@ inline ClassInspectInfo inspectClassFromStaticTable(lua_State* L, int stIdx)
{
MemberInfo m;
m.name = key;
if (key == "__call")
if (key == "new")
m.kind = MemberKind::Constructor;
else if (key.size() >= 2 && key[0] == '_' && key[1] == '_')
m.kind = MemberKind::Metamethod;
Expand Down Expand Up @@ -10072,10 +10071,10 @@ class LuaProxyVisitor : public InspectVisitor
{
case MemberKind::Constructor:

out_ << "setmetatable(" << qname << ", {__call = function(t";
out_ << qname << ".new = function(";
if (!m.overloads[0].params.empty())
out_ << ", " << paramNames(m.overloads[0].params);
out_ << ")\n return setmetatable({}, t)\nend})\n\n";
out_ << paramNames(m.overloads[0].params);
out_ << ") end\n\n";
break;

case MemberKind::Method:
Expand Down Expand Up @@ -13370,13 +13369,13 @@ class Namespace : public detail::Registrar
entry.paramTypes = detail::reflect_param_type_names<ArgsPack>();
overload_set->entries.push_back(std::move(entry));

lua_pushcclosure_x(L, &detail::constructor_placement_proxy<T, ArgsPack>, className, 1);
lua_pushcclosure_x(L, &detail::constructor_placement_proxy<T, ArgsPack>, "new", 1);

} (), ...);
#else
([&]
{
lua_pushcclosure_x(L, &detail::constructor_placement_proxy<T, detail::function_arguments_t<Functions>>, className, 0);
lua_pushcclosure_x(L, &detail::constructor_placement_proxy<T, detail::function_arguments_t<Functions>>, "new", 0);

} (), ...);
#endif
Expand Down Expand Up @@ -13407,15 +13406,15 @@ class Namespace : public detail::Registrar

([&]
{
lua_pushcclosure_x(L, &detail::constructor_placement_proxy<T, detail::function_arguments_t<Functions>>, className, 0);
lua_pushcclosure_x(L, &detail::constructor_placement_proxy<T, detail::function_arguments_t<Functions>>, "new", 0);
lua_rawseti(L, -2, idx++);

} (), ...);

lua_pushcclosure_x(L, &detail::try_overload_functions<true>, className, 2);
lua_pushcclosure_x(L, &detail::try_overload_functions<false>, "new", 2);
}

rawsetfield(L, -2, "__call");
rawsetfield(L, -2, "new");

return *this;
}
Expand Down Expand Up @@ -13454,10 +13453,10 @@ class Namespace : public detail::Registrar
}

lua_newuserdata_aligned<F>(L, F(detail::get_underlying(std::move(functions))));
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F, 2>, className, 2);
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F, 2>, "new", 2);
#else
lua_newuserdata_aligned<F>(L, F(detail::get_underlying(std::move(functions))));
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, className, 1);
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, "new", 1);
#endif
} (), ...);
}
Expand Down Expand Up @@ -13504,15 +13503,15 @@ class Namespace : public detail::Registrar
using F = detail::constructor_forwarder<T, InnerF>;

lua_newuserdata_aligned<F>(L, F(detail::get_underlying(std::move(functions))));
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, className, 1);
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, "new", 1);
lua_rawseti(L, -2, idx++);

} (), ...);

lua_pushcclosure_x(L, &detail::try_overload_functions<true>, className, 2);
lua_pushcclosure_x(L, &detail::try_overload_functions<false>, "new", 2);
}

rawsetfield(L, -2, "__call");
rawsetfield(L, -2, "new");

return *this;
}
Expand All @@ -13527,7 +13526,7 @@ class Namespace : public detail::Registrar
{
([&]
{
lua_pushcclosure_x(L, &detail::constructor_container_proxy<C, detail::function_arguments_t<Functions>>, className, 0);
lua_pushcclosure_x(L, &detail::constructor_container_proxy<C, detail::function_arguments_t<Functions>>, "new", 0);

} (), ...);
}
Expand All @@ -13553,15 +13552,15 @@ class Namespace : public detail::Registrar

([&]
{
lua_pushcclosure_x(L, &detail::constructor_container_proxy<C, detail::function_arguments_t<Functions>>, className, 0);
lua_pushcclosure_x(L, &detail::constructor_container_proxy<C, detail::function_arguments_t<Functions>>, "new", 0);
lua_rawseti(L, -2, idx++);

} (), ...);

lua_pushcclosure_x(L, &detail::try_overload_functions<true>, className, 2);
lua_pushcclosure_x(L, &detail::try_overload_functions<false>, "new", 2);
}

rawsetfield(L, -2, "__call");
rawsetfield(L, -2, "new");

return *this;
}
Expand All @@ -13581,7 +13580,7 @@ class Namespace : public detail::Registrar
using F = detail::container_forwarder<C, Functions>;

lua_newuserdata_aligned<F>(L, F(std::move(functions)));
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, className, 1);
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, "new", 1);

} (), ...);
}
Expand Down Expand Up @@ -13618,15 +13617,15 @@ class Namespace : public detail::Registrar
using F = detail::container_forwarder<C, Functions>;

lua_newuserdata_aligned<F>(L, F(std::move(functions)));
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, className, 1);
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, "new", 1);
lua_rawseti(L, -2, idx++);

} (), ...);

lua_pushcclosure_x(L, &detail::try_overload_functions<true>, className, 2);
lua_pushcclosure_x(L, &detail::try_overload_functions<false>, "new", 2);
}

rawsetfield(L, -2, "__call");
rawsetfield(L, -2, "new");

return *this;
}
Expand Down Expand Up @@ -13658,8 +13657,8 @@ class Namespace : public detail::Registrar
using F = detail::factory_forwarder<T, Allocator, Deallocator>;

lua_newuserdata_aligned<F>(L, F(std::move(allocator), std::move(deallocator)));
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, className, 1);
rawsetfield(L, -2, "__call");
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, "new", 1);
rawsetfield(L, -2, "new");

return *this;
}
Expand Down
16 changes: 8 additions & 8 deletions Manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -732,12 +732,12 @@ luabridge::getGlobalNamespace (L)
.endNamespace ();
```

Constructors added in this fashion are called from Lua using the fully qualified name of the class. This Lua code will create instances of `A` and `B`.
Constructors added in this fashion are called from Lua using the `.new` field on the class. This Lua code will create instances of `A` and `B`.

```lua
a = test.A () -- Create a new A.
b = test.B ("hello", 5) -- Create a new B.
b = test.B () -- Error: expected string in argument 1
a = test.A.new () -- Create a new A.
b = test.B.new ("hello", 5) -- Create a new B.
b = test.B.new () -- Error: expected string in argument 1
```

### 2.6.1 - Constructor Proxies
Expand All @@ -764,16 +764,16 @@ luabridge::getGlobalNamespace (L)
Then in lua:

```lua
hard = test.HardToCreate (5) -- Create a new HardToCreate.
hard = test.HardToCreate.new (5) -- Create a new HardToCreate.
```

The `addConstructor` overload taking a generic functor also accepts a `lua_State*` as last parameter in order to be used for constructors that needs to be overloaded by different numbers of arguments (arguments will start at index 2 of the stack):
The `addConstructor` overload taking a generic functor also accepts a `lua_State*` as last parameter in order to be used for constructors that needs to be overloaded by different numbers of arguments (arguments will start at index 1 of the stack):

```cpp
luabridge::getGlobalNamespace (L)
.beginNamespace ("test")
.beginClass<HardToCreate> ("HardToCreate")
.addConstructor ([] (void* ptr, lua_State* L) { return new (ptr) HardToCreate (shouldNotSeeMe, lua_checkinteger (L, 2)); })
.addConstructor ([] (void* ptr, lua_State* L) { return new (ptr) HardToCreate (shouldNotSeeMe, lua_checkinteger (L, 1)); })
.endClass ()
.endNamespace ();
```
Expand Down Expand Up @@ -826,7 +826,7 @@ luabridge::getGlobalNamespace (L)
The object is the perfectly instantiable through lua:

```lua
a = test.Object () -- Create a new Object using objectFactoryAllocator
a = test.Object.new () -- Create a new Object using objectFactoryAllocator
a = nil -- Remove any reference count
collectgarbage ("collect") -- The object is garbage collected using objectFactoryDeallocator
```
Expand Down
12 changes: 6 additions & 6 deletions Source/LuaBridge/Inspect.h
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ inline ClassInspectInfo inspectClassFromStaticTable(lua_State* L, int stIdx)
{
MemberInfo m;
m.name = key;
if (key == "__call")
if (key == "new")
m.kind = MemberKind::Constructor;
else if (key.size() >= 2 && key[0] == '_' && key[1] == '_')
m.kind = MemberKind::Metamethod;
Expand Down Expand Up @@ -1008,7 +1008,7 @@ class LuaLSVisitor : public InspectVisitor
case MemberKind::Constructor:
{
// Represent the constructor as @overload annotations before the local declaration.
// LuaBridge constructors are called as ClassName(args), not ClassName.new(args).
// LuaBridge constructors are called as ClassName.new(args).
std::string qname = qualifiedName(cls.name);
for (const auto& ov : m.overloads)
out_ << "---@overload fun(" << overloadParams(ov.params) << "): " << qname << "\n";
Expand Down Expand Up @@ -1202,11 +1202,11 @@ class LuaProxyVisitor : public InspectVisitor
switch (m.kind)
{
case MemberKind::Constructor:
// LuaBridge constructors are called as ClassName(args) via __call metamethod.
out_ << "setmetatable(" << qname << ", {__call = function(t";
// LuaBridge constructors are called as ClassName.new(args).
out_ << qname << ".new = function(";
if (!m.overloads[0].params.empty())
out_ << ", " << paramNames(m.overloads[0].params);
out_ << ")\n return setmetatable({}, t)\nend})\n\n";
out_ << paramNames(m.overloads[0].params);
out_ << ") end\n\n";
break;

case MemberKind::Method:
Expand Down
13 changes: 5 additions & 8 deletions Source/LuaBridge/detail/CFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -1981,8 +1981,7 @@ bool overload_check_args_impl(lua_State* L, int start, std::index_sequence<I...>
template <class ArgsPack>
bool overload_check_args(lua_State* L, int start)
{
return overload_check_args_impl<ArgsPack>(L, start,
std::make_index_sequence<std::tuple_size_v<ArgsPack>>{});
return overload_check_args_impl<ArgsPack>(L, start, std::make_index_sequence<std::tuple_size_v<ArgsPack>>{});
}

/**
Expand All @@ -2009,8 +2008,6 @@ bool overload_type_checker(lua_State* L, int start)
* 2. Type check via Stack<T>::isInstance in C++ (no pcall) — skips clearly mismatched overloads.
* 3. Only calls lua_pcall for type-matched candidates, eliminating failed pcalls for type mismatches.
*/


template <bool Member>
inline int try_overload_functions(lua_State* L)
{
Expand Down Expand Up @@ -2890,7 +2887,7 @@ int constructor_container_proxy(lua_State* L)
try
{
#endif
object = constructor<T, Args>::construct(detail::make_arguments_list<Args, 2>(L));
object = constructor<T, Args>::construct(detail::make_arguments_list<Args, 1>(L));

#if LUABRIDGE_HAS_EXCEPTIONS
}
Expand All @@ -2913,7 +2910,7 @@ int constructor_container_proxy(lua_State* L)
template <class T, class Args>
int constructor_placement_proxy(lua_State* L)
{
auto args = make_arguments_list<Args, 2>(L);
auto args = make_arguments_list<Args, 1>(L);

std::error_code ec;
auto* value = UserdataValue<T>::place(L, ec);
Expand Down Expand Up @@ -2957,7 +2954,7 @@ struct constructor_forwarder
using FnTraits = function_traits<F>;
using FnArgs = remove_first_type_t<typename FnTraits::argument_types>;

auto args = make_arguments_list<FnArgs, 2>(L);
auto args = make_arguments_list<FnArgs, 1>(L);

std::error_code ec;
auto* value = UserdataValue<T>::place(L, ec);
Expand Down Expand Up @@ -3084,7 +3081,7 @@ struct container_forwarder
try
{
#endif
object = container_constructor<C>::construct(m_func, make_arguments_list<FnArgs, 2>(L));
object = container_constructor<C>::construct(m_func, make_arguments_list<FnArgs, 1>(L));

#if LUABRIDGE_HAS_EXCEPTIONS
}
Expand Down
Loading
Loading