Buh. Capturing the right semantics is always hard.

This commit is contained in:
ThePhD 2016-09-22 11:49:29 -04:00
parent 3a00ce0adf
commit d88db0faff
6 changed files with 26 additions and 24 deletions

View File

@ -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
.. _this example: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_simple.cpp

View File

@ -46,6 +46,7 @@ private:
};
int main() {
std::cout << "=== usertype_advanced example ===" << std::endl;
sol::state lua;
lua.open_libraries(sol::lib::base);

View File

@ -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;

View File

@ -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 <typename T>
template <typename T, bool poptable = true>
inline bool check_metatable(lua_State* L, int index = -2) {
const auto& metakey = usertype_traits<T>::metatable;
luaL_getmetatable(L, &metakey[0]);
const type expectedmetatabletype = static_cast<type>(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<int>(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 <typename T>
inline int simple_metatable_newindex(lua_State* L) {
simple_map& sm = stack::get<user<simple_map>>(L, upvalue_index(1));
luaL_getmetatable(L, sm.metakey);
stack::set_field<false, true>(L, stack_reference(L, 2), stack_reference(L, 3), lua_gettop(L));
lua_settop(L, 0);
return 0;
if (stack::stack_detail::check_metatable<T, false>(L, 1)) {
stack::set_field<false, true>(L, stack_reference(L, 2), stack_reference(L, 3), 1);
lua_settop(L, 0);
return 0;
}
lua_pop(L, 1);
return indexing_fail<false>(L);
}
template <bool is_index, bool toplevel = false>
@ -10228,7 +10231,7 @@ namespace sol {
template<std::size_t... I, typename Tuple>
simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
: callconstructfunc(nil),
indexfunc(&usertype_detail::indexing_fail<true>), newindexfunc(&usertype_detail::simple_metatable_newindex),
indexfunc(&usertype_detail::indexing_fail<true>), newindexfunc(&usertype_detail::simple_metatable_newindex<T>),
indexbase(&usertype_detail::simple_core_indexing_call<true>), newindexbase(&usertype_detail::simple_core_indexing_call<false>),
indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>),
baseclasscheck(nullptr), baseclasscast(nullptr),

View File

@ -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 <typename T>
inline int simple_metatable_newindex(lua_State* L) {
simple_map& sm = stack::get<user<simple_map>>(L, upvalue_index(1));
luaL_getmetatable(L, sm.metakey);
stack::set_field<false, true>(L, stack_reference(L, 2), stack_reference(L, 3), lua_gettop(L));
lua_settop(L, 0);
return 0;
if (stack::stack_detail::check_metatable<T, false>(L, 1)) {
stack::set_field<false, true>(L, stack_reference(L, 2), stack_reference(L, 3), 1);
lua_settop(L, 0);
return 0;
}
lua_pop(L, 1);
return indexing_fail<false>(L);
}
template <bool is_index, bool toplevel = false>
@ -275,7 +278,7 @@ namespace sol {
template<std::size_t... I, typename Tuple>
simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
: callconstructfunc(nil),
indexfunc(&usertype_detail::indexing_fail<true>), newindexfunc(&usertype_detail::simple_metatable_newindex),
indexfunc(&usertype_detail::indexing_fail<true>), newindexfunc(&usertype_detail::simple_metatable_newindex<T>),
indexbase(&usertype_detail::simple_core_indexing_call<true>), newindexbase(&usertype_detail::simple_core_indexing_call<false>),
indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>),
baseclasscheck(nullptr), baseclasscast(nullptr),

View File

@ -32,14 +32,14 @@
namespace sol {
namespace stack {
namespace stack_detail {
template <typename T>
template <typename T, bool poptable = true>
inline bool check_metatable(lua_State* L, int index = -2) {
const auto& metakey = usertype_traits<T>::metatable;
luaL_getmetatable(L, &metakey[0]);
const type expectedmetatabletype = static_cast<type>(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<int>(poptable));
return true;
}
}