mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Okay, cleaned up includes and now the newest feature:
STATEFUL FUNCTIONS! Any stateful function now works and is properly cleaned up, thanks to some additional metatables that are associated with the function values. This lays the ground work for class bindings, but that's a far off dream. For now, table retrieval and `operator[]` is what's for dinner.
This commit is contained in:
parent
21142e7e7d
commit
19d01ecd1d
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "functional.hpp"
|
#include "functional.hpp"
|
||||||
#include "stack.hpp"
|
#include "stack.hpp"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
|
|
||||||
|
@ -112,14 +113,25 @@ struct static_object_lua_func {
|
||||||
|
|
||||||
struct lua_func {
|
struct lua_func {
|
||||||
static int call(lua_State* L) {
|
static int call(lua_State* L) {
|
||||||
void* inheritancedata = lua_touserdata(L, lua_upvalueindex(1));
|
void** pinheritancedata = static_cast<void**>(lua_touserdata(L, lua_upvalueindex(1)));
|
||||||
|
void* inheritancedata = *pinheritancedata;
|
||||||
if (inheritancedata == nullptr)
|
if (inheritancedata == nullptr)
|
||||||
throw sol_error("call from lua to c++ function has null data");
|
throw sol_error("call from lua to c++ function has null data");
|
||||||
lua_func& fx = *static_cast<lua_func*>(inheritancedata);
|
lua_func* pfx = static_cast<lua_func*>(inheritancedata);
|
||||||
|
lua_func& fx = *pfx;
|
||||||
int r = fx(L);
|
int r = fx(L);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int gc(lua_State* L) {
|
||||||
|
void** puserdata = static_cast<void**>(lua_touserdata(L, 1));
|
||||||
|
void* userdata = *puserdata;
|
||||||
|
lua_func* ptr = static_cast<lua_func*>(userdata);
|
||||||
|
std::default_delete<lua_func> dx{ };
|
||||||
|
dx(ptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
virtual int operator()(lua_State*) {
|
virtual int operator()(lua_State*) {
|
||||||
throw sol_error("Failure to call specialized wrapped C++ function from lua");
|
throw sol_error("Failure to call specialized wrapped C++ function from lua");
|
||||||
}
|
}
|
||||||
|
@ -152,6 +164,10 @@ struct lambda_lua_func : public lua_func {
|
||||||
stack::push(L, r);
|
stack::push(L, r);
|
||||||
return sizeof...(TRn);
|
return sizeof...(TRn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~lambda_lua_func() {
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TFx, typename T = TFx, bool is_member_pointer = std::is_member_function_pointer<TFx>::value>
|
template<typename TFx, typename T = TFx, bool is_member_pointer = std::is_member_function_pointer<TFx>::value>
|
||||||
|
@ -179,6 +195,10 @@ struct explicit_lua_func : public lua_func {
|
||||||
stack::push(L, std::move(r));
|
stack::push(L, std::move(r));
|
||||||
return sizeof...(TRn);
|
return sizeof...(TRn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~explicit_lua_func() {
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TFx, typename T>
|
template<typename TFx, typename T>
|
||||||
|
@ -199,7 +219,7 @@ struct explicit_lua_func<TFx, T, true> : public lua_func {
|
||||||
} fx;
|
} fx;
|
||||||
|
|
||||||
template<typename... FxArgs>
|
template<typename... FxArgs>
|
||||||
explicit_lua_func(T m, FxArgs&&... fxargs): fx(std::move( m ), std::forward<FxArgs>(fxargs)...) {}
|
explicit_lua_func(T m, FxArgs&&... fxargs): fx(std::move(m), std::forward<FxArgs>(fxargs)...) {}
|
||||||
|
|
||||||
virtual int operator()(lua_State* L) override {
|
virtual int operator()(lua_State* L) override {
|
||||||
return (*this)(tuple_types<typename fx_traits::return_type>(), typename fx_traits::args_type(), L);
|
return (*this)(tuple_types<typename fx_traits::return_type>(), typename fx_traits::args_type(), L);
|
||||||
|
@ -217,6 +237,10 @@ struct explicit_lua_func<TFx, T, true> : public lua_func {
|
||||||
stack::push(L, r);
|
stack::push(L, r);
|
||||||
return sizeof...(TRn);
|
return sizeof...(TRn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~explicit_lua_func() {
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // sol
|
} // sol
|
||||||
|
|
|
@ -165,6 +165,17 @@ inline void push(lua_State* L, const std::string& str) {
|
||||||
lua_pushlstring(L, str.c_str(), str.size());
|
lua_pushlstring(L, str.c_str(), str.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline void push_user(lua_State* L, T& userdata, const char* metatablekey) {
|
||||||
|
T* pdatum = static_cast<T*>(lua_newuserdata(L, sizeof(T)));
|
||||||
|
T& datum = *pdatum;
|
||||||
|
datum = userdata;
|
||||||
|
if (metatablekey != nullptr) {
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, metatablekey);
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T, size_t N>
|
template<typename T, size_t N>
|
||||||
inline void push(lua_State* L, const std::array<T, N>& data) {
|
inline void push(lua_State* L, const std::array<T, N>& data) {
|
||||||
for (auto&& i : data) {
|
for (auto&& i : data) {
|
||||||
|
|
|
@ -24,9 +24,7 @@
|
||||||
|
|
||||||
#include "stack.hpp"
|
#include "stack.hpp"
|
||||||
#include "lua_function.hpp"
|
#include "lua_function.hpp"
|
||||||
#include <unordered_map>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
|
@ -122,7 +120,7 @@ private:
|
||||||
template<typename T, typename TFx, typename TObj>
|
template<typename T, typename TFx, typename TObj>
|
||||||
table& set_lvalue_fx(std::false_type, T&& key, TFx&& fx, TObj&& obj) {
|
table& set_lvalue_fx(std::false_type, T&& key, TFx&& fx, TObj&& obj) {
|
||||||
typedef typename std::remove_pointer<typename std::decay<TFx>::type>::type clean_fx;
|
typedef typename std::remove_pointer<typename std::decay<TFx>::type>::type clean_fx;
|
||||||
std::unique_ptr<lua_func> sptr(new explicit_lua_func<clean_fx, TObj>(std::forward<TObj>( obj ), std::forward<TFx>(fx)));
|
std::unique_ptr<lua_func> sptr(new explicit_lua_func<clean_fx, TObj>(std::forward<TObj>(obj), std::forward<TFx>(fx)));
|
||||||
return set_fx(std::forward<T>(key), std::move(sptr));
|
return set_fx(std::forward<T>(key), std::move(sptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,33 +186,31 @@ private:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
table& set_fx(T&& key, std::unique_ptr<lua_func> luafunc) {
|
table& set_fx(T&& key, std::unique_ptr<lua_func> luafunc) {
|
||||||
std::string fkey(key);
|
std::string fkey(key);
|
||||||
|
std::string metakey("sol.stateful.");
|
||||||
|
metakey += fkey;
|
||||||
|
metakey += ".meta";
|
||||||
lua_func* target = luafunc.release();
|
lua_func* target = luafunc.release();
|
||||||
void* userdata = reinterpret_cast<void*>(target);
|
void* userdata = reinterpret_cast<void*>(target);
|
||||||
lua_CFunction freefunc = &lua_func::call;
|
lua_CFunction freefunc = &lua_func::call;
|
||||||
const char* freefuncname = fkey.c_str();
|
const char* freefuncname = fkey.c_str();
|
||||||
|
const char* metatablename = metakey.c_str();
|
||||||
const luaL_Reg funcreg[2] = {
|
const luaL_Reg funcreg[2] = {
|
||||||
{ freefuncname, freefunc },
|
{ freefuncname, freefunc },
|
||||||
{ nullptr, nullptr }
|
{ nullptr, nullptr }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int exists = luaL_newmetatable(state(), metatablename);
|
||||||
|
lua_pushstring(state(), "__gc");
|
||||||
|
lua_pushcclosure(state(), &lua_func::gc, 0);
|
||||||
|
lua_settable(state(), -3);
|
||||||
push();
|
push();
|
||||||
|
|
||||||
// Actual function call we want
|
stack::push_user(state(), userdata, metatablename);
|
||||||
stack::push( state(), userdata );
|
|
||||||
luaL_setfuncs(state(), funcreg, 1);
|
luaL_setfuncs(state(), funcreg, 1);
|
||||||
|
|
||||||
lua_pop(state(), 1);
|
lua_pop(state(), 1);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int destroyfunc( lua_State* L ) {
|
|
||||||
void* userdata = lua_touserdata( L, 1 );
|
|
||||||
lua_func* ptr = static_cast<lua_func*>( userdata );
|
|
||||||
std::default_delete<lua_func> dx{ };
|
|
||||||
dx( ptr );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
} // sol
|
} // sol
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user