mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Fix #398 by ensuring proper usertype propagation.
This commit is contained in:
parent
eebda40507
commit
c124d51353
|
@ -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-19 19:28:54.081352 UTC
|
||||
// This header was generated with sol v2.17.1 (revision a1e3dab)
|
||||
// Generated 2017-04-21 00:18:17.116630 UTC
|
||||
// This header was generated with sol v2.17.1 (revision 3d5f80e)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||
|
@ -10493,15 +10493,50 @@ namespace sol {
|
|||
typedef int(*member_search)(lua_State*, void*, int);
|
||||
|
||||
struct call_information {
|
||||
member_search first;
|
||||
member_search second;
|
||||
member_search index;
|
||||
member_search new_index;
|
||||
int runtime_target;
|
||||
|
||||
call_information(member_search first, member_search second) : call_information(first, second, -1) {}
|
||||
call_information(member_search first, member_search second, int runtimetarget) : first(first), second(second), runtime_target(runtimetarget) {}
|
||||
call_information(member_search index, member_search newindex) : call_information(index, newindex, -1) {}
|
||||
call_information(member_search index, member_search newindex, int runtimetarget) : index(index), new_index(newindex), runtime_target(runtimetarget) {}
|
||||
};
|
||||
|
||||
typedef std::unordered_map<std::string, call_information> mapping_t;
|
||||
|
||||
struct variable_wrapper {
|
||||
virtual int index(lua_State* L) = 0;
|
||||
virtual int new_index(lua_State* L) = 0;
|
||||
virtual ~variable_wrapper() {};
|
||||
};
|
||||
|
||||
template <typename T, typename F>
|
||||
struct callable_binding : variable_wrapper {
|
||||
F fx;
|
||||
|
||||
template <typename Arg>
|
||||
callable_binding(Arg&& arg) : fx(std::forward<Arg>(arg)) {}
|
||||
|
||||
virtual int index(lua_State* L) override {
|
||||
return call_detail::call_wrapped<T, true, true>(L, fx);
|
||||
}
|
||||
|
||||
virtual int new_index(lua_State* L) override {
|
||||
return call_detail::call_wrapped<T, false, true>(L, fx);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::unordered_map<std::string, std::unique_ptr<variable_wrapper>> variable_map;
|
||||
typedef std::unordered_map<std::string, object> function_map;
|
||||
|
||||
struct simple_map {
|
||||
const char* metakey;
|
||||
variable_map variables;
|
||||
function_map functions;
|
||||
base_walk indexbaseclasspropogation;
|
||||
base_walk newindexbaseclasspropogation;
|
||||
|
||||
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) {}
|
||||
};
|
||||
}
|
||||
|
||||
struct usertype_metatable_core {
|
||||
|
@ -10626,7 +10661,8 @@ namespace sol {
|
|||
inline int runtime_object_call(lua_State* L, void*, int runtimetarget) {
|
||||
usertype_metatable_core& umc = stack::get<light<usertype_metatable_core>>(L, upvalue_index(2));
|
||||
std::vector<object>& runtime = umc.runtime;
|
||||
return stack::push(L, runtime[runtimetarget]);
|
||||
object& runtimeobj = runtime[runtimetarget];
|
||||
return stack::push(L, runtimeobj);
|
||||
}
|
||||
|
||||
template <typename T, bool is_index>
|
||||
|
@ -10657,34 +10693,55 @@ namespace sol {
|
|||
}
|
||||
}
|
||||
|
||||
int runtime_new_index(lua_State* L, void*, int runtimetarget);
|
||||
|
||||
template <typename T, bool is_simple>
|
||||
inline int metatable_newindex(lua_State* L) {
|
||||
int isnum = 0;
|
||||
lua_Integer magic = lua_tointegerx(L, upvalue_index(4), &isnum);
|
||||
if (isnum != 0 && magic == toplevel_magic) {
|
||||
auto non_simple = [&L]() {
|
||||
if (is_simple)
|
||||
auto non_indexable = [&L]() {
|
||||
if (is_simple) {
|
||||
simple_map& sm = stack::get<user<simple_map>>(L, upvalue_index(1));
|
||||
function_map& functions = sm.functions;
|
||||
sol::optional<std::string> maybeaccessor = stack::get<sol::optional<std::string>>(L, 2);
|
||||
if (!maybeaccessor) {
|
||||
return;
|
||||
}
|
||||
std::string& accessor = maybeaccessor.value();
|
||||
auto preexistingit = functions.find(accessor);
|
||||
if (preexistingit == functions.cend()) {
|
||||
functions.emplace_hint(preexistingit, std::move(accessor), sol::object(L, 3));
|
||||
}
|
||||
else {
|
||||
preexistingit->second = sol::object(L, 3);
|
||||
}
|
||||
return;
|
||||
}
|
||||
usertype_metatable_core& umc = stack::get<light<usertype_metatable_core>>(L, upvalue_index(2));
|
||||
bool mustindex = umc.mustindex;
|
||||
if (!mustindex)
|
||||
return;
|
||||
std::string accessor = stack::get<std::string>(L, 2);
|
||||
sol::optional<std::string> maybeaccessor = stack::get<sol::optional<std::string>>(L, 2);
|
||||
if (!maybeaccessor) {
|
||||
return;
|
||||
}
|
||||
std::string& accessor = maybeaccessor.value();
|
||||
mapping_t& mapping = umc.mapping;
|
||||
std::vector<object>& runtime = umc.runtime;
|
||||
int target = static_cast<int>(runtime.size());
|
||||
auto preexistingit = mapping.find(accessor);
|
||||
if (preexistingit == mapping.cend()) {
|
||||
runtime.emplace_back(L, 3);
|
||||
mapping.emplace_hint(mapping.cend(), accessor, call_information(&runtime_object_call, &runtime_object_call, target));
|
||||
mapping.emplace_hint(mapping.cend(), accessor, call_information(&runtime_object_call, &runtime_new_index, target));
|
||||
}
|
||||
else {
|
||||
target = preexistingit->second.runtime_target;
|
||||
runtime[target] = sol::object(L, 3);
|
||||
preexistingit->second = call_information(&runtime_object_call, &runtime_object_call, target);
|
||||
preexistingit->second = call_information(&runtime_object_call, &runtime_new_index, target);
|
||||
}
|
||||
};
|
||||
non_simple();
|
||||
non_indexable();
|
||||
for (std::size_t i = 0; i < 4; lua_settop(L, 3), ++i) {
|
||||
const char* metakey = nullptr;
|
||||
switch (i) {
|
||||
|
@ -10720,6 +10777,14 @@ namespace sol {
|
|||
}
|
||||
return indexing_fail<T, false>(L);
|
||||
}
|
||||
|
||||
inline int runtime_new_index(lua_State* L, void*, int runtimetarget) {
|
||||
usertype_metatable_core& umc = stack::get<light<usertype_metatable_core>>(L, upvalue_index(2));
|
||||
std::vector<object>& runtime = umc.runtime;
|
||||
object& runtimeobj = runtime[runtimetarget];
|
||||
runtimeobj = object(L, 3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <bool is_index, typename Base>
|
||||
static void walk_single_base(lua_State* L, bool& found, int& ret, string_detail::string_shim&) {
|
||||
|
@ -10876,6 +10941,7 @@ namespace sol {
|
|||
|
||||
template <std::size_t, typename... Bases>
|
||||
void make_regs(regs_t&, int&, base_classes_tag, bases<Bases...>) {
|
||||
static_assert(!meta::any_same<T, Bases...>::value, "base classes cannot list the original class as part of the bases");
|
||||
if (sizeof...(Bases) < 1) {
|
||||
return;
|
||||
}
|
||||
|
@ -10937,8 +11003,8 @@ namespace sol {
|
|||
hasequals(false), hasless(false), haslessequals(false) {
|
||||
std::initializer_list<typename usertype_detail::mapping_t::value_type> ilist{ {
|
||||
std::pair<std::string, usertype_detail::call_information>( usertype_detail::make_string(std::get<I * 2>(functions)),
|
||||
usertype_detail::call_information(&usertype_metatable::real_find_call<I * 2, I * 2 + 1, false>,
|
||||
&usertype_metatable::real_find_call<I * 2, I * 2 + 1, true>)
|
||||
usertype_detail::call_information(&usertype_metatable::real_find_call<I * 2, I * 2 + 1, true>,
|
||||
&usertype_metatable::real_find_call<I * 2, I * 2 + 1, false>)
|
||||
)
|
||||
}... };
|
||||
this->mapping.insert(ilist);
|
||||
|
@ -10981,7 +11047,7 @@ namespace sol {
|
|||
auto memberit = f.mapping.find(name);
|
||||
if (memberit != f.mapping.cend()) {
|
||||
const usertype_detail::call_information& ci = memberit->second;
|
||||
const usertype_detail::member_search& member = is_index ? ci.second : ci.first;
|
||||
const usertype_detail::member_search& member = is_index ? ci.index: ci.new_index;
|
||||
return (member)(L, static_cast<void*>(&f), ci.runtime_target);
|
||||
}
|
||||
string_detail::string_shim accessor = name;
|
||||
|
@ -11200,41 +11266,6 @@ namespace sol {
|
|||
namespace sol {
|
||||
|
||||
namespace usertype_detail {
|
||||
struct variable_wrapper {
|
||||
virtual int index(lua_State* L) = 0;
|
||||
virtual int new_index(lua_State* L) = 0;
|
||||
virtual ~variable_wrapper() {};
|
||||
};
|
||||
|
||||
template <typename T, typename F>
|
||||
struct callable_binding : variable_wrapper {
|
||||
F fx;
|
||||
|
||||
template <typename Arg>
|
||||
callable_binding(Arg&& arg) : fx(std::forward<Arg>(arg)) {}
|
||||
|
||||
virtual int index(lua_State* L) override {
|
||||
return call_detail::call_wrapped<T, true, true>(L, fx);
|
||||
}
|
||||
|
||||
virtual int new_index(lua_State* L) override {
|
||||
return call_detail::call_wrapped<T, false, true>(L, fx);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::unordered_map<std::string, std::unique_ptr<variable_wrapper>> variable_map;
|
||||
typedef std::unordered_map<std::string, object> function_map;
|
||||
|
||||
struct simple_map {
|
||||
const char* metakey;
|
||||
variable_map variables;
|
||||
function_map functions;
|
||||
base_walk indexbaseclasspropogation;
|
||||
base_walk newindexbaseclasspropogation;
|
||||
|
||||
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 <bool is_index, bool toplevel = false>
|
||||
inline int simple_core_indexing_call(lua_State* L) {
|
||||
simple_map& sm = toplevel ? stack::get<user<simple_map>>(L, upvalue_index(1)) : stack::pop<user<simple_map>>(L);
|
||||
|
@ -11259,8 +11290,14 @@ namespace sol {
|
|||
}
|
||||
auto fit = functions.find(accessorkey);
|
||||
if (fit != functions.cend()) {
|
||||
auto& func = (fit->second);
|
||||
return stack::push(L, func);
|
||||
sol::object& func = fit->second;
|
||||
if (is_index) {
|
||||
return stack::push(L, func);
|
||||
}
|
||||
else {
|
||||
lua_CFunction indexingfunc = is_index ? stack::get<lua_CFunction>(L, upvalue_index(2)) : stack::get<lua_CFunction>(L, upvalue_index(3));
|
||||
return indexingfunc(L);
|
||||
}
|
||||
}
|
||||
// Check table storage first for a method that works
|
||||
luaL_getmetatable(L, sm.metakey);
|
||||
|
@ -11440,6 +11477,7 @@ namespace sol {
|
|||
template <typename... Bases>
|
||||
void add(lua_State*, base_classes_tag, bases<Bases...>) {
|
||||
static_assert(sizeof(usertype_detail::base_walk) <= sizeof(void*), "size of function pointer is greater than sizeof(void*); cannot work on this platform. Please file a bug report.");
|
||||
static_assert(!meta::any_same<T, Bases...>::value, "base classes cannot list the original class as part of the bases");
|
||||
if (sizeof...(Bases) < 1) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -31,41 +31,6 @@
|
|||
namespace sol {
|
||||
|
||||
namespace usertype_detail {
|
||||
struct variable_wrapper {
|
||||
virtual int index(lua_State* L) = 0;
|
||||
virtual int new_index(lua_State* L) = 0;
|
||||
virtual ~variable_wrapper() {};
|
||||
};
|
||||
|
||||
template <typename T, typename F>
|
||||
struct callable_binding : variable_wrapper {
|
||||
F fx;
|
||||
|
||||
template <typename Arg>
|
||||
callable_binding(Arg&& arg) : fx(std::forward<Arg>(arg)) {}
|
||||
|
||||
virtual int index(lua_State* L) override {
|
||||
return call_detail::call_wrapped<T, true, true>(L, fx);
|
||||
}
|
||||
|
||||
virtual int new_index(lua_State* L) override {
|
||||
return call_detail::call_wrapped<T, false, true>(L, fx);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::unordered_map<std::string, std::unique_ptr<variable_wrapper>> variable_map;
|
||||
typedef std::unordered_map<std::string, object> function_map;
|
||||
|
||||
struct simple_map {
|
||||
const char* metakey;
|
||||
variable_map variables;
|
||||
function_map functions;
|
||||
base_walk indexbaseclasspropogation;
|
||||
base_walk newindexbaseclasspropogation;
|
||||
|
||||
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 <bool is_index, bool toplevel = false>
|
||||
inline int simple_core_indexing_call(lua_State* L) {
|
||||
simple_map& sm = toplevel ? stack::get<user<simple_map>>(L, upvalue_index(1)) : stack::pop<user<simple_map>>(L);
|
||||
|
@ -90,8 +55,14 @@ namespace sol {
|
|||
}
|
||||
auto fit = functions.find(accessorkey);
|
||||
if (fit != functions.cend()) {
|
||||
auto& func = (fit->second);
|
||||
return stack::push(L, func);
|
||||
sol::object& func = fit->second;
|
||||
if (is_index) {
|
||||
return stack::push(L, func);
|
||||
}
|
||||
else {
|
||||
lua_CFunction indexingfunc = is_index ? stack::get<lua_CFunction>(L, upvalue_index(2)) : stack::get<lua_CFunction>(L, upvalue_index(3));
|
||||
return indexingfunc(L);
|
||||
}
|
||||
}
|
||||
// Check table storage first for a method that works
|
||||
luaL_getmetatable(L, sm.metakey);
|
||||
|
@ -271,6 +242,7 @@ namespace sol {
|
|||
template <typename... Bases>
|
||||
void add(lua_State*, base_classes_tag, bases<Bases...>) {
|
||||
static_assert(sizeof(usertype_detail::base_walk) <= sizeof(void*), "size of function pointer is greater than sizeof(void*); cannot work on this platform. Please file a bug report.");
|
||||
static_assert(!meta::any_same<T, Bases...>::value, "base classes cannot list the original class as part of the bases");
|
||||
if (sizeof...(Bases) < 1) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -40,15 +40,50 @@ namespace sol {
|
|||
typedef int(*member_search)(lua_State*, void*, int);
|
||||
|
||||
struct call_information {
|
||||
member_search first;
|
||||
member_search second;
|
||||
member_search index;
|
||||
member_search new_index;
|
||||
int runtime_target;
|
||||
|
||||
call_information(member_search first, member_search second) : call_information(first, second, -1) {}
|
||||
call_information(member_search first, member_search second, int runtimetarget) : first(first), second(second), runtime_target(runtimetarget) {}
|
||||
call_information(member_search index, member_search newindex) : call_information(index, newindex, -1) {}
|
||||
call_information(member_search index, member_search newindex, int runtimetarget) : index(index), new_index(newindex), runtime_target(runtimetarget) {}
|
||||
};
|
||||
|
||||
typedef std::unordered_map<std::string, call_information> mapping_t;
|
||||
|
||||
struct variable_wrapper {
|
||||
virtual int index(lua_State* L) = 0;
|
||||
virtual int new_index(lua_State* L) = 0;
|
||||
virtual ~variable_wrapper() {};
|
||||
};
|
||||
|
||||
template <typename T, typename F>
|
||||
struct callable_binding : variable_wrapper {
|
||||
F fx;
|
||||
|
||||
template <typename Arg>
|
||||
callable_binding(Arg&& arg) : fx(std::forward<Arg>(arg)) {}
|
||||
|
||||
virtual int index(lua_State* L) override {
|
||||
return call_detail::call_wrapped<T, true, true>(L, fx);
|
||||
}
|
||||
|
||||
virtual int new_index(lua_State* L) override {
|
||||
return call_detail::call_wrapped<T, false, true>(L, fx);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::unordered_map<std::string, std::unique_ptr<variable_wrapper>> variable_map;
|
||||
typedef std::unordered_map<std::string, object> function_map;
|
||||
|
||||
struct simple_map {
|
||||
const char* metakey;
|
||||
variable_map variables;
|
||||
function_map functions;
|
||||
base_walk indexbaseclasspropogation;
|
||||
base_walk newindexbaseclasspropogation;
|
||||
|
||||
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) {}
|
||||
};
|
||||
}
|
||||
|
||||
struct usertype_metatable_core {
|
||||
|
@ -173,7 +208,8 @@ namespace sol {
|
|||
inline int runtime_object_call(lua_State* L, void*, int runtimetarget) {
|
||||
usertype_metatable_core& umc = stack::get<light<usertype_metatable_core>>(L, upvalue_index(2));
|
||||
std::vector<object>& runtime = umc.runtime;
|
||||
return stack::push(L, runtime[runtimetarget]);
|
||||
object& runtimeobj = runtime[runtimetarget];
|
||||
return stack::push(L, runtimeobj);
|
||||
}
|
||||
|
||||
template <typename T, bool is_index>
|
||||
|
@ -204,34 +240,55 @@ namespace sol {
|
|||
}
|
||||
}
|
||||
|
||||
int runtime_new_index(lua_State* L, void*, int runtimetarget);
|
||||
|
||||
template <typename T, bool is_simple>
|
||||
inline int metatable_newindex(lua_State* L) {
|
||||
int isnum = 0;
|
||||
lua_Integer magic = lua_tointegerx(L, upvalue_index(4), &isnum);
|
||||
if (isnum != 0 && magic == toplevel_magic) {
|
||||
auto non_simple = [&L]() {
|
||||
if (is_simple)
|
||||
auto non_indexable = [&L]() {
|
||||
if (is_simple) {
|
||||
simple_map& sm = stack::get<user<simple_map>>(L, upvalue_index(1));
|
||||
function_map& functions = sm.functions;
|
||||
sol::optional<std::string> maybeaccessor = stack::get<sol::optional<std::string>>(L, 2);
|
||||
if (!maybeaccessor) {
|
||||
return;
|
||||
}
|
||||
std::string& accessor = maybeaccessor.value();
|
||||
auto preexistingit = functions.find(accessor);
|
||||
if (preexistingit == functions.cend()) {
|
||||
functions.emplace_hint(preexistingit, std::move(accessor), sol::object(L, 3));
|
||||
}
|
||||
else {
|
||||
preexistingit->second = sol::object(L, 3);
|
||||
}
|
||||
return;
|
||||
}
|
||||
usertype_metatable_core& umc = stack::get<light<usertype_metatable_core>>(L, upvalue_index(2));
|
||||
bool mustindex = umc.mustindex;
|
||||
if (!mustindex)
|
||||
return;
|
||||
std::string accessor = stack::get<std::string>(L, 2);
|
||||
sol::optional<std::string> maybeaccessor = stack::get<sol::optional<std::string>>(L, 2);
|
||||
if (!maybeaccessor) {
|
||||
return;
|
||||
}
|
||||
std::string& accessor = maybeaccessor.value();
|
||||
mapping_t& mapping = umc.mapping;
|
||||
std::vector<object>& runtime = umc.runtime;
|
||||
int target = static_cast<int>(runtime.size());
|
||||
auto preexistingit = mapping.find(accessor);
|
||||
if (preexistingit == mapping.cend()) {
|
||||
runtime.emplace_back(L, 3);
|
||||
mapping.emplace_hint(mapping.cend(), accessor, call_information(&runtime_object_call, &runtime_object_call, target));
|
||||
mapping.emplace_hint(mapping.cend(), accessor, call_information(&runtime_object_call, &runtime_new_index, target));
|
||||
}
|
||||
else {
|
||||
target = preexistingit->second.runtime_target;
|
||||
runtime[target] = sol::object(L, 3);
|
||||
preexistingit->second = call_information(&runtime_object_call, &runtime_object_call, target);
|
||||
preexistingit->second = call_information(&runtime_object_call, &runtime_new_index, target);
|
||||
}
|
||||
};
|
||||
non_simple();
|
||||
non_indexable();
|
||||
for (std::size_t i = 0; i < 4; lua_settop(L, 3), ++i) {
|
||||
const char* metakey = nullptr;
|
||||
switch (i) {
|
||||
|
@ -267,6 +324,14 @@ namespace sol {
|
|||
}
|
||||
return indexing_fail<T, false>(L);
|
||||
}
|
||||
|
||||
inline int runtime_new_index(lua_State* L, void*, int runtimetarget) {
|
||||
usertype_metatable_core& umc = stack::get<light<usertype_metatable_core>>(L, upvalue_index(2));
|
||||
std::vector<object>& runtime = umc.runtime;
|
||||
object& runtimeobj = runtime[runtimetarget];
|
||||
runtimeobj = object(L, 3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <bool is_index, typename Base>
|
||||
static void walk_single_base(lua_State* L, bool& found, int& ret, string_detail::string_shim&) {
|
||||
|
@ -423,6 +488,7 @@ namespace sol {
|
|||
|
||||
template <std::size_t, typename... Bases>
|
||||
void make_regs(regs_t&, int&, base_classes_tag, bases<Bases...>) {
|
||||
static_assert(!meta::any_same<T, Bases...>::value, "base classes cannot list the original class as part of the bases");
|
||||
if (sizeof...(Bases) < 1) {
|
||||
return;
|
||||
}
|
||||
|
@ -484,8 +550,8 @@ namespace sol {
|
|||
hasequals(false), hasless(false), haslessequals(false) {
|
||||
std::initializer_list<typename usertype_detail::mapping_t::value_type> ilist{ {
|
||||
std::pair<std::string, usertype_detail::call_information>( usertype_detail::make_string(std::get<I * 2>(functions)),
|
||||
usertype_detail::call_information(&usertype_metatable::real_find_call<I * 2, I * 2 + 1, false>,
|
||||
&usertype_metatable::real_find_call<I * 2, I * 2 + 1, true>)
|
||||
usertype_detail::call_information(&usertype_metatable::real_find_call<I * 2, I * 2 + 1, true>,
|
||||
&usertype_metatable::real_find_call<I * 2, I * 2 + 1, false>)
|
||||
)
|
||||
}... };
|
||||
this->mapping.insert(ilist);
|
||||
|
@ -528,7 +594,7 @@ namespace sol {
|
|||
auto memberit = f.mapping.find(name);
|
||||
if (memberit != f.mapping.cend()) {
|
||||
const usertype_detail::call_information& ci = memberit->second;
|
||||
const usertype_detail::member_search& member = is_index ? ci.second : ci.first;
|
||||
const usertype_detail::member_search& member = is_index ? ci.index: ci.new_index;
|
||||
return (member)(L, static_cast<void*>(&f), ci.runtime_target);
|
||||
}
|
||||
string_detail::string_shim accessor = name;
|
||||
|
|
|
@ -698,27 +698,81 @@ end
|
|||
}
|
||||
|
||||
TEST_CASE("simple_usertype/runtime-replacement", "ensure that functions can be properly replaced at runtime for non-indexed things") {
|
||||
struct heart_t {};
|
||||
struct heart_base_t {};
|
||||
struct heart_t : heart_base_t {
|
||||
void func() {}
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
SECTION("plain") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.new_usertype<heart_t>("a");
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("obj = a.new()");
|
||||
lua.script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.script("v1 = obj:heartbeat()");
|
||||
lua.script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.script("v2 = obj:heartbeat()");
|
||||
lua.script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.script("v3 = obj:heartbeat()");
|
||||
}());
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
int v3 = lua["v3"];
|
||||
REQUIRE(v1 == 1);
|
||||
REQUIRE(v2 == 2);
|
||||
REQUIRE(v3 == 3);
|
||||
lua.new_simple_usertype<heart_t>("a");
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("obj = a.new()");
|
||||
lua.script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.script("v1 = obj:heartbeat()");
|
||||
lua.script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.script("v2 = obj:heartbeat()");
|
||||
lua.script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.script("v3 = obj:heartbeat()");
|
||||
}());
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
int v3 = lua["v3"];
|
||||
REQUIRE(v1 == 1);
|
||||
REQUIRE(v2 == 2);
|
||||
REQUIRE(v3 == 3);
|
||||
}
|
||||
SECTION("variables") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.new_simple_usertype<heart_t>("a",
|
||||
sol::base_classes, sol::bases<heart_base_t>()
|
||||
);
|
||||
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("obj = a.new()");
|
||||
lua.script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.script("v1 = obj:heartbeat()");
|
||||
lua.script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.script("v2 = obj:heartbeat()");
|
||||
lua.script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.script("v3 = obj:heartbeat()");
|
||||
}());
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
int v3 = lua["v3"];
|
||||
REQUIRE(v1 == 1);
|
||||
REQUIRE(v2 == 2);
|
||||
REQUIRE(v3 == 3);
|
||||
}
|
||||
SECTION("methods") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.new_simple_usertype<heart_t>("a",
|
||||
"func", &heart_t::func,
|
||||
sol::base_classes, sol::bases<heart_base_t>()
|
||||
);
|
||||
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("obj = a.new()");
|
||||
lua.script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.script("v1 = obj:heartbeat()");
|
||||
lua.script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.script("v2 = obj:heartbeat()");
|
||||
lua.script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.script("v3 = obj:heartbeat()");
|
||||
}());
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
int v3 = lua["v3"];
|
||||
REQUIRE(v1 == 1);
|
||||
REQUIRE(v2 == 2);
|
||||
REQUIRE(v3 == 3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("simple_usertype/meta-key-retrievals", "allow for special meta keys (__index, __newindex) to trigger methods even if overwritten directly") {
|
||||
|
|
|
@ -1623,27 +1623,81 @@ end
|
|||
}
|
||||
|
||||
TEST_CASE("usertype/runtime-replacement", "ensure that functions can be properly replaced at runtime for non-indexed things") {
|
||||
struct heart_t {};
|
||||
struct heart_base_t {};
|
||||
struct heart_t : heart_base_t {
|
||||
void func() {}
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
SECTION("plain") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.new_usertype<heart_t>("a");
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("obj = a.new()");
|
||||
lua.script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.script("v1 = obj:heartbeat()");
|
||||
lua.script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.script("v2 = obj:heartbeat()");
|
||||
lua.script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.script("v3 = obj:heartbeat()");
|
||||
}());
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
int v3 = lua["v3"];
|
||||
REQUIRE(v1 == 1);
|
||||
REQUIRE(v2 == 2);
|
||||
REQUIRE(v3 == 3);
|
||||
lua.new_usertype<heart_t>("a");
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("obj = a.new()");
|
||||
lua.script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.script("v1 = obj:heartbeat()");
|
||||
lua.script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.script("v2 = obj:heartbeat()");
|
||||
lua.script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.script("v3 = obj:heartbeat()");
|
||||
}());
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
int v3 = lua["v3"];
|
||||
REQUIRE(v1 == 1);
|
||||
REQUIRE(v2 == 2);
|
||||
REQUIRE(v3 == 3);
|
||||
}
|
||||
SECTION("variables") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.new_usertype<heart_t>("a",
|
||||
sol::base_classes, sol::bases<heart_base_t>()
|
||||
);
|
||||
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("obj = a.new()");
|
||||
lua.script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.script("v1 = obj:heartbeat()");
|
||||
lua.script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.script("v2 = obj:heartbeat()");
|
||||
lua.script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.script("v3 = obj:heartbeat()");
|
||||
}());
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
int v3 = lua["v3"];
|
||||
REQUIRE(v1 == 1);
|
||||
REQUIRE(v2 == 2);
|
||||
REQUIRE(v3 == 3);
|
||||
}
|
||||
SECTION("methods") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.new_usertype<heart_t>("a",
|
||||
"func", &heart_t::func,
|
||||
sol::base_classes, sol::bases<heart_base_t>()
|
||||
);
|
||||
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("obj = a.new()");
|
||||
lua.script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.script("v1 = obj:heartbeat()");
|
||||
lua.script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.script("v2 = obj:heartbeat()");
|
||||
lua.script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.script("v3 = obj:heartbeat()");
|
||||
}());
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
int v3 = lua["v3"];
|
||||
REQUIRE(v1 == 1);
|
||||
REQUIRE(v2 == 2);
|
||||
REQUIRE(v3 == 3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/meta-key-retrievals", "allow for special meta keys (__index, __newindex) to trigger methods even if overwritten directly") {
|
||||
|
|
Loading…
Reference in New Issue
Block a user