mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Merge remote-tracking branch 'root/classes'
This commit is contained in:
commit
4d6d39be88
|
@ -28,7 +28,7 @@
|
|||
namespace sol {
|
||||
|
||||
template<typename Function>
|
||||
struct static_lua_func {
|
||||
struct static_function {
|
||||
typedef typename std::remove_pointer<typename std::decay<Function>::type>::type function_type;
|
||||
typedef function_traits<function_type> traits_type;
|
||||
|
||||
|
@ -64,7 +64,7 @@ struct static_lua_func {
|
|||
};
|
||||
|
||||
template<typename T, typename Function>
|
||||
struct static_object_lua_func {
|
||||
struct static_member_function {
|
||||
typedef typename std::remove_pointer<typename std::decay<Function>::type>::type function_type;
|
||||
typedef function_traits<function_type> traits_type;
|
||||
|
||||
|
@ -103,15 +103,15 @@ struct static_object_lua_func {
|
|||
}
|
||||
};
|
||||
|
||||
struct lua_func {
|
||||
struct base_function {
|
||||
static int call(lua_State* L) {
|
||||
void** pinheritancedata = static_cast<void**>(stack::get<lightuserdata_t>(L, 1).value);
|
||||
void* inheritancedata = *pinheritancedata;
|
||||
if (inheritancedata == nullptr) {
|
||||
throw sol_error("call from Lua to C++ function has null data");
|
||||
}
|
||||
lua_func* pfx = static_cast<lua_func*>(inheritancedata);
|
||||
lua_func& fx = *pfx;
|
||||
base_function* pfx = static_cast<base_function*>(inheritancedata);
|
||||
base_function& fx = *pfx;
|
||||
int r = fx(L);
|
||||
return r;
|
||||
}
|
||||
|
@ -119,8 +119,8 @@ struct lua_func {
|
|||
static int gc(lua_State* L) {
|
||||
void** puserdata = static_cast<void**>(stack::get<userdata_t>(L, 1).value);
|
||||
void* userdata = *puserdata;
|
||||
lua_func* ptr = static_cast<lua_func*>(userdata);
|
||||
std::default_delete<lua_func> dx{};
|
||||
base_function* ptr = static_cast<base_function*>(userdata);
|
||||
std::default_delete<base_function> dx{};
|
||||
dx(ptr);
|
||||
return 0;
|
||||
}
|
||||
|
@ -129,17 +129,17 @@ struct lua_func {
|
|||
throw sol_error("failure to call specialized wrapped C++ function from Lua");
|
||||
}
|
||||
|
||||
virtual ~lua_func() {}
|
||||
virtual ~base_function() {}
|
||||
};
|
||||
|
||||
template<typename Function>
|
||||
struct functor_lua_func : public lua_func {
|
||||
struct functor_function : public base_function {
|
||||
typedef decltype(&Function::operator()) function_type;
|
||||
typedef function_traits<function_type> traits_type;
|
||||
Function fx;
|
||||
|
||||
template<typename... FxArgs>
|
||||
functor_lua_func(FxArgs&&... fxargs): fx(std::forward<FxArgs>(fxargs)...) {}
|
||||
functor_function(FxArgs&&... fxargs): fx(std::forward<FxArgs>(fxargs)...) {}
|
||||
|
||||
template<typename... Args>
|
||||
int operator()(types<void>, types<Args...> t, lua_State* L) {
|
||||
|
@ -165,41 +165,8 @@ struct functor_lua_func : public lua_func {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename Function, typename T = Function, bool is_member_pointer = std::is_member_function_pointer<Function>::value>
|
||||
struct function_lua_func : public lua_func {
|
||||
typedef typename std::remove_pointer<typename std::decay<Function>::type>::type function_type;
|
||||
typedef function_traits<function_type> traits_type;
|
||||
function_type fx;
|
||||
|
||||
template<typename... FxArgs>
|
||||
function_lua_func(FxArgs&&... fxargs): fx(std::forward<FxArgs>(fxargs)...) {}
|
||||
|
||||
template<typename... Args>
|
||||
int operator()(types<void>, types<Args...> t, lua_State* L) {
|
||||
stack::pop_call(L, fx, t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
int operator()(types<>, types<Args...> t, lua_State* L) {
|
||||
return (*this)(types<void>(), t, L);
|
||||
}
|
||||
|
||||
template<typename... Ret, typename... Args>
|
||||
int operator()(types<Ret...>, types<Args...> t, lua_State* L) {
|
||||
typedef typename multi_return<Ret...>::type return_type;
|
||||
return_type r = stack::pop_call(L, fx, t);
|
||||
stack::push(L, std::move(r));
|
||||
return sizeof...(Ret);
|
||||
}
|
||||
|
||||
virtual int operator()(lua_State* L) override {
|
||||
return (*this)(tuple_types<typename traits_type::return_type>(), typename traits_type::args_type(), L);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Function, typename T>
|
||||
struct function_lua_func<Function, T, true> : public lua_func {
|
||||
struct member_function : public base_function {
|
||||
typedef typename std::remove_pointer<typename std::decay<Function>::type>::type function_type;
|
||||
typedef function_traits<function_type> traits_type;
|
||||
struct functor {
|
||||
|
@ -216,7 +183,7 @@ struct function_lua_func<Function, T, true> : public lua_func {
|
|||
} fx;
|
||||
|
||||
template<typename... FxArgs>
|
||||
function_lua_func(T m, FxArgs&&... fxargs): fx(std::move(m), std::forward<FxArgs>(fxargs)...) {}
|
||||
member_function(T m, FxArgs&&... fxargs): fx(std::move(m), std::forward<FxArgs>(fxargs)...) {}
|
||||
|
||||
template<typename... Args>
|
||||
int operator()(types<void>, types<Args...> t, lua_State* L) {
|
||||
|
@ -243,7 +210,7 @@ struct function_lua_func<Function, T, true> : public lua_func {
|
|||
};
|
||||
|
||||
template<typename Function, typename T>
|
||||
struct class_lua_func : public lua_func {
|
||||
struct userdata_function : public base_function {
|
||||
typedef typename std::remove_pointer<typename std::decay<Function>::type>::type function_type;
|
||||
typedef function_traits<function_type> traits_type;
|
||||
struct functor {
|
||||
|
@ -266,7 +233,7 @@ struct class_lua_func : public lua_func {
|
|||
} fx;
|
||||
|
||||
template<typename... FxArgs>
|
||||
class_lua_func(FxArgs&&... fxargs): fx(std::forward<FxArgs>(fxargs)...) {}
|
||||
userdata_function(FxArgs&&... fxargs): fx(std::forward<FxArgs>(fxargs)...) {}
|
||||
|
||||
template<typename... Args>
|
||||
int operator()(types<void>, types<Args...> t, lua_State* L) {
|
|
@ -50,10 +50,6 @@ public:
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
|
||||
}
|
||||
|
||||
void pop() const noexcept {
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
reference(reference&& o) noexcept {
|
||||
L = o.L;
|
||||
ref = o.ref;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include "proxy.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "lua_function.hpp"
|
||||
#include "function_types.hpp"
|
||||
#include "userdata.hpp"
|
||||
|
||||
namespace sol {
|
||||
|
@ -168,6 +168,9 @@ public:
|
|||
return proxy<const table, T>(*this, std::forward<T>(key));
|
||||
}
|
||||
|
||||
void pop(int n = 1) const noexcept {
|
||||
lua_pop(state(), n);
|
||||
}
|
||||
private:
|
||||
template<typename T, typename TFx>
|
||||
table& set_isfunction_fx(std::true_type, T&& key, TFx&& fx) {
|
||||
|
@ -192,7 +195,7 @@ private:
|
|||
template<typename T, typename TFx>
|
||||
table& set_isconvertible_fx(std::false_type, T&& key, TFx&& fx) {
|
||||
typedef typename std::remove_pointer<Decay<TFx>>::type clean_fx;
|
||||
std::unique_ptr<lua_func> sptr(new functor_lua_func<clean_fx>(std::forward<TFx>(fx)));
|
||||
std::unique_ptr<base_function> sptr(new functor_function<clean_fx>(std::forward<TFx>(fx)));
|
||||
return set_fx(std::forward<T>(key), std::move(sptr));
|
||||
}
|
||||
|
||||
|
@ -204,7 +207,7 @@ private:
|
|||
template<typename T, typename TFx, typename TObj>
|
||||
table& set_lvalue_fx(std::false_type, T&& key, TFx&& fx, TObj&& obj) {
|
||||
typedef typename std::remove_pointer<Decay<TFx>>::type clean_fx;
|
||||
std::unique_ptr<lua_func> sptr(new function_lua_func<clean_fx, TObj>(std::forward<TObj>(obj), std::forward<TFx>(fx)));
|
||||
std::unique_ptr<base_function> sptr(new member_function<clean_fx, TObj>(std::forward<TObj>(obj), std::forward<TFx>(fx)));
|
||||
return set_fx(std::forward<T>(key), std::move(sptr));
|
||||
}
|
||||
|
||||
|
@ -219,7 +222,7 @@ private:
|
|||
// with the same member function pointer type
|
||||
Decay<TFx> fxptr(std::forward<TFx>(fx));
|
||||
void* userobjdata = static_cast<void*>(detail::get_ptr(obj));
|
||||
lua_CFunction freefunc = &static_object_lua_func<Decay<TObj>, TFx>::call;
|
||||
lua_CFunction freefunc = &static_member_function<Decay<TObj>, TFx>::call;
|
||||
const char* freefuncname = fkey.c_str();
|
||||
const luaL_Reg funcreg[2] = {
|
||||
{ freefuncname, freefunc },
|
||||
|
@ -241,7 +244,7 @@ private:
|
|||
table& set_fx(std::false_type, T&& key, TFx&& fx) {
|
||||
std::string fkey(key);
|
||||
Decay<TFx> target(std::forward<TFx>(fx));
|
||||
lua_CFunction freefunc = &static_lua_func<TFx>::call;
|
||||
lua_CFunction freefunc = &static_function<TFx>::call;
|
||||
const char* freefuncname = fkey.c_str();
|
||||
const luaL_Reg funcreg[2] = {
|
||||
{ freefuncname, freefunc },
|
||||
|
@ -257,14 +260,14 @@ private:
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
table& set_fx(T&& key, std::unique_ptr<lua_func> luafunc) {
|
||||
table& set_fx(T&& key, std::unique_ptr<base_function> luafunc) {
|
||||
std::string fkey(key);
|
||||
std::string metakey("sol.stateful.");
|
||||
metakey += fkey;
|
||||
metakey += ".meta";
|
||||
lua_func* target = luafunc.release();
|
||||
base_function* target = luafunc.release();
|
||||
void* userdata = reinterpret_cast<void*>(target);
|
||||
lua_CFunction freefunc = &lua_func::call;
|
||||
lua_CFunction freefunc = &base_function::call;
|
||||
const char* freefuncname = fkey.c_str();
|
||||
const char* metatablename = metakey.c_str();
|
||||
const luaL_Reg funcreg[2] = {
|
||||
|
@ -274,7 +277,7 @@ private:
|
|||
|
||||
if (luaL_newmetatable(state(), metatablename) == 1) {
|
||||
lua_pushstring(state(), "__gc");
|
||||
lua_pushcclosure(state(), &lua_func::gc, 0);
|
||||
lua_pushcclosure(state(), &base_function::gc, 0);
|
||||
lua_settable(state(), -3);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#define SOL_USERDATA_HPP
|
||||
|
||||
#include "state.hpp"
|
||||
#include "lua_function.hpp"
|
||||
#include "function_types.hpp"
|
||||
#include "demangle.hpp"
|
||||
#include <vector>
|
||||
|
||||
|
@ -44,7 +44,7 @@ private:
|
|||
|
||||
std::string luaname;
|
||||
std::vector<std::string> functionnames;
|
||||
std::vector<std::unique_ptr<lua_func>> functions;
|
||||
std::vector<std::unique_ptr<base_function>> functions;
|
||||
std::vector<luaL_Reg> functiontable;
|
||||
std::vector<luaL_Reg> metatable;
|
||||
|
||||
|
@ -128,8 +128,8 @@ private:
|
|||
void* inheritancedata = stack::get<lightuserdata_t>(L, i + 1);
|
||||
if (inheritancedata == nullptr)
|
||||
throw sol_error("call from Lua to C++ function has null data");
|
||||
lua_func* pfx = static_cast<lua_func*>(inheritancedata);
|
||||
lua_func& fx = *pfx;
|
||||
base_function* pfx = static_cast<base_function*>(inheritancedata);
|
||||
base_function& fx = *pfx;
|
||||
int r = fx(L);
|
||||
return r;
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ private:
|
|||
void build_function_tables(Ret(T::* func)(MArgs...), std::string name, Args&&... args) {
|
||||
typedef typename std::decay<decltype(func)>::type fx_t;
|
||||
functionnames.push_back(std::move(name));
|
||||
functions.emplace_back(detail::make_unique<class_lua_func<fx_t, T>>(std::move(func)));
|
||||
functions.emplace_back(detail::make_unique<userdata_function<fx_t, T>>(std::move(func)));
|
||||
functiontable.push_back({ functionnames.back().c_str(), &class_func<n>::call });
|
||||
build_function_tables<n + 1>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
|
|
@ -354,8 +354,7 @@ TEST_CASE( "tables/userdata", "Show that we can create classes from userdata and
|
|||
|
||||
lua.script("a = fuser:new()\n"
|
||||
"b = a:add(1)\n"
|
||||
"c = a:add2(1)\n"
|
||||
"\n" );
|
||||
"c = a:add2(1)\n");
|
||||
|
||||
sol::object a = lua.get<sol::object>("a");
|
||||
sol::object b = lua.get<sol::object>("b");
|
||||
|
|
Loading…
Reference in New Issue
Block a user