You would think that we'd have accounted for this earlier...

Fixes #405
This commit is contained in:
ThePhD 2017-05-16 06:12:28 -04:00
parent 34b81bef6b
commit 51d6f6fa54
4 changed files with 96 additions and 7 deletions

View File

@ -61,7 +61,7 @@ struct vec {
return sol::object(L, sol::in_place, sol::lua_nil); return sol::object(L, sol::in_place, sol::lua_nil);
} }
void setter(sol::stack_object key, sol::stack_object value, sol::this_state L) { void setter(sol::stack_object key, sol::stack_object value, sol::this_state) {
// we use stack_object for the arguments because we know // we use stack_object for the arguments because we know
// the values from Lua will remain on Lua's stack, // the values from Lua will remain on Lua's stack,
// so long we we don't mess with it // so long we we don't mess with it

View File

@ -20,8 +20,8 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script. // This file was generated with a script.
// Generated 2017-05-15 14:41:13.667703 UTC // Generated 2017-05-16 10:11:15.504731 UTC
// This header was generated with sol v2.17.3 (revision 7eccb58) // This header was generated with sol v2.17.3 (revision 34b81be)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP #ifndef SOL_SINGLE_INCLUDE_HPP
@ -9357,11 +9357,16 @@ namespace sol {
stack::push(L, f); stack::push(L, f);
} }
template <typename Fx, typename... Args> template <typename Fx, typename... Args, meta::disable<meta::any<std::is_base_of<reference, meta::unqualified_t<Fx>>, std::is_base_of<stack_reference, meta::unqualified_t<Fx>>>> = meta::enabler>
static void select(lua_State* L, Fx&& fx, Args&&... args) { static void select(lua_State* L, Fx&& fx, Args&&... args) {
select_function(std::is_function<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...); select_function(std::is_function<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
} }
template <typename Fx, meta::enable<meta::any<std::is_base_of<reference, meta::unqualified_t<Fx>>, std::is_base_of<stack_reference, meta::unqualified_t<Fx>>>> = meta::enabler>
static void select(lua_State* L, Fx&& fx) {
stack::push(L, std::forward<Fx>(fx));
}
template <typename Fx, typename... Args> template <typename Fx, typename... Args>
static void set_fx(lua_State* L, Args&&... args) { static void set_fx(lua_State* L, Args&&... args) {
lua_CFunction freefunc = function_detail::call<meta::unqualified_t<Fx>, 2>; lua_CFunction freefunc = function_detail::call<meta::unqualified_t<Fx>, 2>;
@ -9398,7 +9403,11 @@ namespace sol {
template<typename Signature> template<typename Signature>
struct pusher<std::function<Signature>> { struct pusher<std::function<Signature>> {
static int push(lua_State* L, std::function<Signature> fx) { static int push(lua_State* L, const std::function<Signature>& fx) {
return pusher<function_sig<Signature>>{}.push(L, fx);
}
static int push(lua_State* L, std::function<Signature>&& fx) {
return pusher<function_sig<Signature>>{}.push(L, std::move(fx)); return pusher<function_sig<Signature>>{}.push(L, std::move(fx));
} }
}; };

View File

@ -190,11 +190,16 @@ namespace sol {
stack::push(L, f); stack::push(L, f);
} }
template <typename Fx, typename... Args> template <typename Fx, typename... Args, meta::disable<meta::any<std::is_base_of<reference, meta::unqualified_t<Fx>>, std::is_base_of<stack_reference, meta::unqualified_t<Fx>>>> = meta::enabler>
static void select(lua_State* L, Fx&& fx, Args&&... args) { static void select(lua_State* L, Fx&& fx, Args&&... args) {
select_function(std::is_function<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...); select_function(std::is_function<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
} }
template <typename Fx, meta::enable<meta::any<std::is_base_of<reference, meta::unqualified_t<Fx>>, std::is_base_of<stack_reference, meta::unqualified_t<Fx>>>> = meta::enabler>
static void select(lua_State* L, Fx&& fx) {
stack::push(L, std::forward<Fx>(fx));
}
template <typename Fx, typename... Args> template <typename Fx, typename... Args>
static void set_fx(lua_State* L, Args&&... args) { static void set_fx(lua_State* L, Args&&... args) {
lua_CFunction freefunc = function_detail::call<meta::unqualified_t<Fx>, 2>; lua_CFunction freefunc = function_detail::call<meta::unqualified_t<Fx>, 2>;
@ -231,7 +236,11 @@ namespace sol {
template<typename Signature> template<typename Signature>
struct pusher<std::function<Signature>> { struct pusher<std::function<Signature>> {
static int push(lua_State* L, std::function<Signature> fx) { static int push(lua_State* L, const std::function<Signature>& fx) {
return pusher<function_sig<Signature>>{}.push(L, fx);
}
static int push(lua_State* L, std::function<Signature>&& fx) {
return pusher<function_sig<Signature>>{}.push(L, std::move(fx)); return pusher<function_sig<Signature>>{}.push(L, std::move(fx));
} }
}; };

View File

@ -1064,3 +1064,74 @@ TEST_CASE("functions/overloaded-variadic", "make sure variadics work to some deg
REQUIRE(b == 3); REQUIRE(b == 3);
REQUIRE(c == 2.2); REQUIRE(c == 2.2);
} }
TEST_CASE("functions/set_function-already-wrapped", "setting a function returned from Lua code that is already wrapped into a sol::function or similar") {
SECTION("test different types") {
sol::state lua;
lua.open_libraries(sol::lib::base);
sol::function fn = lua.script("return function() return 5 end");
sol::protected_function pfn = fn;
std::function<int()> sfn = fn;
lua.set_function("test", fn);
lua.set_function("test2", pfn);
lua.set_function("test3", sfn);
REQUIRE_NOTHROW(lua.script("assert(type(test) == 'function')"));
REQUIRE_NOTHROW(lua.script("assert(test() ~= nil)"));
REQUIRE_NOTHROW(lua.script("assert(test() == 5)"));
REQUIRE_NOTHROW(lua.script("assert(type(test2) == 'function')"));
REQUIRE_NOTHROW(lua.script("assert(test2() ~= nil)"));
REQUIRE_NOTHROW(lua.script("assert(test2() == 5)"));
REQUIRE_NOTHROW(lua.script("assert(type(test3) == 'function')"));
REQUIRE_NOTHROW(lua.script("assert(test3() ~= nil)"));
REQUIRE_NOTHROW(lua.script("assert(test3() == 5)"));
}
SECTION("getting the value from C++") {
sol::state lua;
lua.open_libraries(sol::lib::base);
sol::function fn = lua.script("return function() return 5 end");
int result = fn();
REQUIRE(result == 5);
}
SECTION("setting the function directly") {
sol::state lua;
lua.open_libraries(sol::lib::base);
sol::function fn = lua.script("return function() return 5 end");
lua.set_function("test", fn);
REQUIRE_NOTHROW(lua.script("assert(type(test) == 'function')"));
REQUIRE_NOTHROW(lua.script("assert(test() ~= nil)"));
REQUIRE_NOTHROW(lua.script("assert(test() == 5)"));
}
SECTION("does the function actually get executed?") {
sol::state lua;
lua.open_libraries(sol::lib::base);
sol::function fn2 = lua.script("return function() print('this was executed') end");
lua.set_function("test", fn2);
REQUIRE_NOTHROW(lua.script("assert(type(test) == 'function')"));
REQUIRE_NOTHROW(lua.script("test()"));
}
SECTION("setting the function indirectly, with the return value cast explicitly") {
sol::state lua;
lua.open_libraries(sol::lib::base);
sol::function fn = lua.script("return function() return 5 end");
lua.set_function("test", [&fn]() { return fn.call<int>(); });
REQUIRE_NOTHROW(lua.script("assert(type(test) == 'function')"));
REQUIRE_NOTHROW(lua.script("assert(test() ~= nil)"));
REQUIRE_NOTHROW(lua.script("assert(test() == 5)"));
}
}