From d88db0faff46b6f561c03188005d24ed71f95804 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Thu, 22 Sep 2016 11:49:29 -0400 Subject: [PATCH] Buh. Capturing the right semantics is always hard. --- docs/source/api/simple_usertype.rst | 2 +- examples/usertype_advanced.cpp | 1 + examples/usertype_special_functions.cpp | 5 ----- single/sol/sol.hpp | 23 +++++++++++++---------- sol/simple_usertype_metatable.hpp | 15 +++++++++------ sol/stack_check.hpp | 4 ++-- 6 files changed, 26 insertions(+), 24 deletions(-) diff --git a/docs/source/api/simple_usertype.rst b/docs/source/api/simple_usertype.rst index 1aefce75..e030ed92 100644 --- a/docs/source/api/simple_usertype.rst +++ b/docs/source/api/simple_usertype.rst @@ -13,4 +13,4 @@ Some developers used ``simple_usertype`` to have variables automatically be func The performance `seems to be good enough`_ to not warn about any implications of having to serialize things at runtime. You do run the risk of using (slightly?) more memory, however, since variables and functions need to be stored differently and separately from the metatable data itself like with a regular ``usertype``. The goal here was to avoid compiler complaints about too-large usertypes (some individuals needed to register 190+ functions, and the compiler choked from the templated implementation of ``usertype``). As of Sol 2.14, this implementation has been heavily refactored to allow for all the same syntax and uses of usertype to apply here, with no caveats/exceptions. .. _seems to be good enough: https://github.com/ThePhD/sol2/issues/202#issuecomment-246767629 -.. _this example: .. _ usertype examples: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_simple.cpp \ No newline at end of file +.. _this example: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_simple.cpp \ No newline at end of file diff --git a/examples/usertype_advanced.cpp b/examples/usertype_advanced.cpp index 752bef18..32679089 100644 --- a/examples/usertype_advanced.cpp +++ b/examples/usertype_advanced.cpp @@ -46,6 +46,7 @@ private: }; int main() { + std::cout << "=== usertype_advanced example ===" << std::endl; sol::state lua; lua.open_libraries(sol::lib::base); diff --git a/examples/usertype_special_functions.cpp b/examples/usertype_special_functions.cpp index 50421036..7121fe9c 100644 --- a/examples/usertype_special_functions.cpp +++ b/examples/usertype_special_functions.cpp @@ -60,14 +60,9 @@ int main() { assert(s1.x == 1 && s1.y == -1); lua["a2"] = lua["a1"]; - lua["a3"] = &a1; lua.script(R"( - -- automatic comparison generated for Lua: - -- pointers are equal assert(a1 == a2) - assert(a1 == a3) - assert(a2 == a3) )"); std::cout << std::endl; diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index 1f79f0ae..499d537d 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 2016-09-22 11:12:24.469225 UTC -// This header was generated with sol v2.14.2 (revision 77a1ce7) +// Generated 2016-09-22 15:48:51.139867 UTC +// This header was generated with sol v2.14.2 (revision 3a00ce0) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -4543,14 +4543,14 @@ namespace sol { namespace sol { namespace stack { namespace stack_detail { - template + template inline bool check_metatable(lua_State* L, int index = -2) { const auto& metakey = usertype_traits::metatable; luaL_getmetatable(L, &metakey[0]); const type expectedmetatabletype = static_cast(lua_type(L, -1)); if (expectedmetatabletype != type::nil) { if (lua_rawequal(L, -1, index) == 1) { - lua_pop(L, 2); + lua_pop(L, 1 + static_cast(poptable)); return true; } } @@ -10019,12 +10019,15 @@ namespace sol { simple_map(const char* mkey, base_walk index, base_walk newindex, variable_map&& vars, function_map&& funcs) : metakey(mkey), variables(std::move(vars)), functions(std::move(funcs)), indexbaseclasspropogation(index), newindexbaseclasspropogation(newindex) {} }; + template inline int simple_metatable_newindex(lua_State* L) { - simple_map& sm = stack::get>(L, upvalue_index(1)); - luaL_getmetatable(L, sm.metakey); - stack::set_field(L, stack_reference(L, 2), stack_reference(L, 3), lua_gettop(L)); - lua_settop(L, 0); - return 0; + if (stack::stack_detail::check_metatable(L, 1)) { + stack::set_field(L, stack_reference(L, 2), stack_reference(L, 3), 1); + lua_settop(L, 0); + return 0; + } + lua_pop(L, 1); + return indexing_fail(L); } template @@ -10228,7 +10231,7 @@ namespace sol { template simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence, lua_State* L, Tuple&& args) : callconstructfunc(nil), - indexfunc(&usertype_detail::indexing_fail), newindexfunc(&usertype_detail::simple_metatable_newindex), + indexfunc(&usertype_detail::indexing_fail), newindexfunc(&usertype_detail::simple_metatable_newindex), indexbase(&usertype_detail::simple_core_indexing_call), newindexbase(&usertype_detail::simple_core_indexing_call), indexbaseclasspropogation(usertype_detail::walk_all_bases), newindexbaseclasspropogation(&usertype_detail::walk_all_bases), baseclasscheck(nullptr), baseclasscast(nullptr), diff --git a/sol/simple_usertype_metatable.hpp b/sol/simple_usertype_metatable.hpp index 2d11ed44..0969e972 100644 --- a/sol/simple_usertype_metatable.hpp +++ b/sol/simple_usertype_metatable.hpp @@ -66,12 +66,15 @@ namespace sol { simple_map(const char* mkey, base_walk index, base_walk newindex, variable_map&& vars, function_map&& funcs) : metakey(mkey), variables(std::move(vars)), functions(std::move(funcs)), indexbaseclasspropogation(index), newindexbaseclasspropogation(newindex) {} }; + template inline int simple_metatable_newindex(lua_State* L) { - simple_map& sm = stack::get>(L, upvalue_index(1)); - luaL_getmetatable(L, sm.metakey); - stack::set_field(L, stack_reference(L, 2), stack_reference(L, 3), lua_gettop(L)); - lua_settop(L, 0); - return 0; + if (stack::stack_detail::check_metatable(L, 1)) { + stack::set_field(L, stack_reference(L, 2), stack_reference(L, 3), 1); + lua_settop(L, 0); + return 0; + } + lua_pop(L, 1); + return indexing_fail(L); } template @@ -275,7 +278,7 @@ namespace sol { template simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence, lua_State* L, Tuple&& args) : callconstructfunc(nil), - indexfunc(&usertype_detail::indexing_fail), newindexfunc(&usertype_detail::simple_metatable_newindex), + indexfunc(&usertype_detail::indexing_fail), newindexfunc(&usertype_detail::simple_metatable_newindex), indexbase(&usertype_detail::simple_core_indexing_call), newindexbase(&usertype_detail::simple_core_indexing_call), indexbaseclasspropogation(usertype_detail::walk_all_bases), newindexbaseclasspropogation(&usertype_detail::walk_all_bases), baseclasscheck(nullptr), baseclasscast(nullptr), diff --git a/sol/stack_check.hpp b/sol/stack_check.hpp index b4b977cc..03a71d38 100644 --- a/sol/stack_check.hpp +++ b/sol/stack_check.hpp @@ -32,14 +32,14 @@ namespace sol { namespace stack { namespace stack_detail { - template + template inline bool check_metatable(lua_State* L, int index = -2) { const auto& metakey = usertype_traits::metatable; luaL_getmetatable(L, &metakey[0]); const type expectedmetatabletype = static_cast(lua_type(L, -1)); if (expectedmetatabletype != type::nil) { if (lua_rawequal(L, -1, index) == 1) { - lua_pop(L, 2); + lua_pop(L, 1 + static_cast(poptable)); return true; } }