mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Buh. Capturing the right semantics is always hard.
This commit is contained in:
parent
3a00ce0adf
commit
d88db0faff
|
@ -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.
|
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
|
.. _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
|
|
@ -46,6 +46,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
std::cout << "=== usertype_advanced example ===" << std::endl;
|
||||||
sol::state lua;
|
sol::state lua;
|
||||||
|
|
||||||
lua.open_libraries(sol::lib::base);
|
lua.open_libraries(sol::lib::base);
|
||||||
|
|
|
@ -60,14 +60,9 @@ int main() {
|
||||||
assert(s1.x == 1 && s1.y == -1);
|
assert(s1.x == 1 && s1.y == -1);
|
||||||
|
|
||||||
lua["a2"] = lua["a1"];
|
lua["a2"] = lua["a1"];
|
||||||
lua["a3"] = &a1;
|
|
||||||
|
|
||||||
lua.script(R"(
|
lua.script(R"(
|
||||||
-- automatic comparison generated for Lua:
|
|
||||||
-- pointers are equal
|
|
||||||
assert(a1 == a2)
|
assert(a1 == a2)
|
||||||
assert(a1 == a3)
|
|
||||||
assert(a2 == a3)
|
|
||||||
)");
|
)");
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
|
@ -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 2016-09-22 11:12:24.469225 UTC
|
// Generated 2016-09-22 15:48:51.139867 UTC
|
||||||
// This header was generated with sol v2.14.2 (revision 77a1ce7)
|
// This header was generated with sol v2.14.2 (revision 3a00ce0)
|
||||||
// https://github.com/ThePhD/sol2
|
// https://github.com/ThePhD/sol2
|
||||||
|
|
||||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||||
|
@ -4543,14 +4543,14 @@ namespace sol {
|
||||||
namespace sol {
|
namespace sol {
|
||||||
namespace stack {
|
namespace stack {
|
||||||
namespace stack_detail {
|
namespace stack_detail {
|
||||||
template <typename T>
|
template <typename T, bool poptable = true>
|
||||||
inline bool check_metatable(lua_State* L, int index = -2) {
|
inline bool check_metatable(lua_State* L, int index = -2) {
|
||||||
const auto& metakey = usertype_traits<T>::metatable;
|
const auto& metakey = usertype_traits<T>::metatable;
|
||||||
luaL_getmetatable(L, &metakey[0]);
|
luaL_getmetatable(L, &metakey[0]);
|
||||||
const type expectedmetatabletype = static_cast<type>(lua_type(L, -1));
|
const type expectedmetatabletype = static_cast<type>(lua_type(L, -1));
|
||||||
if (expectedmetatabletype != type::nil) {
|
if (expectedmetatabletype != type::nil) {
|
||||||
if (lua_rawequal(L, -1, index) == 1) {
|
if (lua_rawequal(L, -1, index) == 1) {
|
||||||
lua_pop(L, 2);
|
lua_pop(L, 1 + static_cast<int>(poptable));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10019,13 +10019,16 @@ 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) {}
|
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) {
|
inline int simple_metatable_newindex(lua_State* L) {
|
||||||
simple_map& sm = stack::get<user<simple_map>>(L, upvalue_index(1));
|
if (stack::stack_detail::check_metatable<T, false>(L, 1)) {
|
||||||
luaL_getmetatable(L, sm.metakey);
|
stack::set_field<false, true>(L, stack_reference(L, 2), stack_reference(L, 3), 1);
|
||||||
stack::set_field<false, true>(L, stack_reference(L, 2), stack_reference(L, 3), lua_gettop(L));
|
|
||||||
lua_settop(L, 0);
|
lua_settop(L, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return indexing_fail<false>(L);
|
||||||
|
}
|
||||||
|
|
||||||
template <bool is_index, bool toplevel = false>
|
template <bool is_index, bool toplevel = false>
|
||||||
inline int simple_core_indexing_call(lua_State* L) {
|
inline int simple_core_indexing_call(lua_State* L) {
|
||||||
|
@ -10228,7 +10231,7 @@ namespace sol {
|
||||||
template<std::size_t... I, typename Tuple>
|
template<std::size_t... I, typename Tuple>
|
||||||
simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
|
simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
|
||||||
: callconstructfunc(nil),
|
: 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>),
|
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>),
|
indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>),
|
||||||
baseclasscheck(nullptr), baseclasscast(nullptr),
|
baseclasscheck(nullptr), baseclasscast(nullptr),
|
||||||
|
|
|
@ -66,13 +66,16 @@ 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) {}
|
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) {
|
inline int simple_metatable_newindex(lua_State* L) {
|
||||||
simple_map& sm = stack::get<user<simple_map>>(L, upvalue_index(1));
|
if (stack::stack_detail::check_metatable<T, false>(L, 1)) {
|
||||||
luaL_getmetatable(L, sm.metakey);
|
stack::set_field<false, true>(L, stack_reference(L, 2), stack_reference(L, 3), 1);
|
||||||
stack::set_field<false, true>(L, stack_reference(L, 2), stack_reference(L, 3), lua_gettop(L));
|
|
||||||
lua_settop(L, 0);
|
lua_settop(L, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return indexing_fail<false>(L);
|
||||||
|
}
|
||||||
|
|
||||||
template <bool is_index, bool toplevel = false>
|
template <bool is_index, bool toplevel = false>
|
||||||
inline int simple_core_indexing_call(lua_State* L) {
|
inline int simple_core_indexing_call(lua_State* L) {
|
||||||
|
@ -275,7 +278,7 @@ namespace sol {
|
||||||
template<std::size_t... I, typename Tuple>
|
template<std::size_t... I, typename Tuple>
|
||||||
simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
|
simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
|
||||||
: callconstructfunc(nil),
|
: 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>),
|
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>),
|
indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>),
|
||||||
baseclasscheck(nullptr), baseclasscast(nullptr),
|
baseclasscheck(nullptr), baseclasscast(nullptr),
|
||||||
|
|
|
@ -32,14 +32,14 @@
|
||||||
namespace sol {
|
namespace sol {
|
||||||
namespace stack {
|
namespace stack {
|
||||||
namespace stack_detail {
|
namespace stack_detail {
|
||||||
template <typename T>
|
template <typename T, bool poptable = true>
|
||||||
inline bool check_metatable(lua_State* L, int index = -2) {
|
inline bool check_metatable(lua_State* L, int index = -2) {
|
||||||
const auto& metakey = usertype_traits<T>::metatable;
|
const auto& metakey = usertype_traits<T>::metatable;
|
||||||
luaL_getmetatable(L, &metakey[0]);
|
luaL_getmetatable(L, &metakey[0]);
|
||||||
const type expectedmetatabletype = static_cast<type>(lua_type(L, -1));
|
const type expectedmetatabletype = static_cast<type>(lua_type(L, -1));
|
||||||
if (expectedmetatabletype != type::nil) {
|
if (expectedmetatabletype != type::nil) {
|
||||||
if (lua_rawequal(L, -1, index) == 1) {
|
if (lua_rawequal(L, -1, index) == 1) {
|
||||||
lua_pop(L, 2);
|
lua_pop(L, 1 + static_cast<int>(poptable));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user