diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index 22c783c8..c5b26687 100644 --- a/single/sol/sol.hpp +++ b/single/sol/sol.hpp @@ -20,8 +20,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // This file was generated with a script. -// Generated 2017-04-21 00:18:17.116630 UTC -// This header was generated with sol v2.17.1 (revision 3d5f80e) +// Generated 2017-04-25 23:43:53.892903 UTC +// This header was generated with sol v2.17.1 (revision 0db6d99) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -8026,6 +8026,11 @@ namespace sol { return property_detail::property(std::true_type(), std::forward(f)); } + template + inline decltype(auto) writeonly_property(F&& f) { + return property_detail::property(std::false_type(), std::forward(f)); + } + // Allow someone to make a member variable readonly (const) template inline auto readonly(R T::* v) { @@ -8542,12 +8547,21 @@ namespace sol { struct lua_call_wrapper, is_index, is_variable, checked, boost, C> { typedef std::conditional_t P; typedef meta::unqualified_t

U; + typedef wrapper wrap; typedef lua_bind_traits traits_type; + typedef meta::unqualified_t> object_type; template - static int self_call(lua_State* L, F&& f) { - typedef wrapper wrap; - typedef meta::unqualified_t> object_type; + static int self_call(std::true_type, lua_State* L, F&& f) { + // The type being void means we don't have any arguments, so it might be a free functions? + typedef typename traits_type::free_args_list args_list; + typedef typename wrap::returns_list returns_list; + typedef typename wrap::caller caller; + return stack::call_into_lua(returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), f); + } + + template + static int self_call(std::false_type, lua_State* L, F&& f) { typedef meta::pop_front_type_t args_list; typedef T Ta; #ifdef SOL_SAFE_USERTYPE @@ -8569,7 +8583,7 @@ namespace sol { template static int defer_call(std::false_type, lua_State* L, F&& f, Args&&... args) { - return self_call(L, pick(meta::boolean(), f), std::forward(args)...); + return self_call(meta::any, meta::boolean>::value != type::userdata>>(), L, pick(meta::boolean(), f), std::forward(args)...); } template diff --git a/sol/call.hpp b/sol/call.hpp index db27c1d4..17ddc119 100644 --- a/sol/call.hpp +++ b/sol/call.hpp @@ -515,12 +515,21 @@ namespace sol { struct lua_call_wrapper, is_index, is_variable, checked, boost, C> { typedef std::conditional_t P; typedef meta::unqualified_t

U; + typedef wrapper wrap; typedef lua_bind_traits traits_type; + typedef meta::unqualified_t> object_type; template - static int self_call(lua_State* L, F&& f) { - typedef wrapper wrap; - typedef meta::unqualified_t> object_type; + static int self_call(std::true_type, lua_State* L, F&& f) { + // The type being void means we don't have any arguments, so it might be a free functions? + typedef typename traits_type::free_args_list args_list; + typedef typename wrap::returns_list returns_list; + typedef typename wrap::caller caller; + return stack::call_into_lua(returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), f); + } + + template + static int self_call(std::false_type, lua_State* L, F&& f) { typedef meta::pop_front_type_t args_list; typedef T Ta; #ifdef SOL_SAFE_USERTYPE @@ -542,7 +551,7 @@ namespace sol { template static int defer_call(std::false_type, lua_State* L, F&& f, Args&&... args) { - return self_call(L, pick(meta::boolean(), f), std::forward(args)...); + return self_call(meta::any, meta::boolean>::value != type::userdata>>(), L, pick(meta::boolean(), f), std::forward(args)...); } template diff --git a/sol/property.hpp b/sol/property.hpp index 703cac92..f1ed4bd6 100644 --- a/sol/property.hpp +++ b/sol/property.hpp @@ -76,6 +76,11 @@ namespace sol { return property_detail::property(std::true_type(), std::forward(f)); } + template + inline decltype(auto) writeonly_property(F&& f) { + return property_detail::property(std::false_type(), std::forward(f)); + } + // Allow someone to make a member variable readonly (const) template inline auto readonly(R T::* v) { diff --git a/test_simple_usertypes.cpp b/test_simple_usertypes.cpp index d08a3575..5f408c96 100644 --- a/test_simple_usertypes.cpp +++ b/test_simple_usertypes.cpp @@ -840,3 +840,39 @@ TEST_CASE("simple_usertype/meta-key-retrievals", "allow for special meta keys (_ REQUIRE(keys[3] == "__call"); } } + +TEST_CASE("simple_usertype/static-properties", "allow for static functions to get and set things as a property") { + static int b = 50; + struct test_t { + static double s_func() { + return b + 0.5; + } + + static void g_func(int v) { + b = v; + } + + std::size_t func() { + return 24; + } + }; + test_t manager; + + sol::state lua; + + lua.new_simple_usertype("test", + "f", std::function(std::bind(std::mem_fn(&test_t::func), &manager)), + "g", sol::property(&test_t::s_func, &test_t::g_func) + ); + + lua.script("v1 = test.f()"); + lua.script("v2 = test.g"); + lua.script("test.g = 60"); + lua.script("v2a = test.g"); + int v1 = lua["v1"]; + REQUIRE(v1 == 24); + double v2 = lua["v2"]; + REQUIRE(v2 == 50.5); + double v2a = lua["v2a"]; + REQUIRE(v2a == 60.5); +} diff --git a/test_usertypes.cpp b/test_usertypes.cpp index f0ce1129..fcad9cfc 100644 --- a/test_usertypes.cpp +++ b/test_usertypes.cpp @@ -1353,6 +1353,42 @@ print(test.ref_global2) REQUIRE(through_variable == 35); } +TEST_CASE("usertype/static-properties", "allow for static functions to get and set things as a property") { + static int b = 50; + struct test_t { + static double s_func() { + return b + 0.5; + } + + static void g_func(int v) { + b = v; + } + + std::size_t func() { + return 24; + } + }; + test_t manager; + + sol::state lua; + + lua.new_usertype("test", + "f", std::function(std::bind(std::mem_fn(&test_t::func), &manager)), + "g", sol::property(&test_t::s_func, &test_t::g_func) + ); + + lua.script("v1 = test.f()"); + lua.script("v2 = test.g"); + lua.script("test.g = 60"); + lua.script("v2a = test.g"); + int v1 = lua["v1"]; + REQUIRE(v1 == 24); + double v2 = lua["v2"]; + REQUIRE(v2 == 50.5); + double v2a = lua["v2a"]; + REQUIRE(v2a == 60.5); +} + TEST_CASE("usertype/var-and-property", "make sure const vars are readonly and properties can handle lambdas") { const static int arf = 20;