mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
This properly pushes a local function to the table. However, we're having issues because the tables are being constructed without an attachment to sol::state, making it impossible to keep std::shared_ptr's alive that contain the virtual interfaces necessary to handle those goddamn lambdas.
This commit is contained in:
parent
a4a4d21376
commit
8c023c54a5
|
@ -85,7 +85,7 @@ struct explicit_lua_func : public lua_func {
|
||||||
template<typename... TRn, typename... Args>
|
template<typename... TRn, typename... Args>
|
||||||
int operator()(types<TRn...>, types<Args...> t, lua_State* L) {
|
int operator()(types<TRn...>, types<Args...> t, lua_State* L) {
|
||||||
auto r = stack::pop_call(L, fx, t);
|
auto r = stack::pop_call(L, fx, t);
|
||||||
stack::push(L, r);
|
stack::push(L, std::move( r ));
|
||||||
return sizeof...(TRn);
|
return sizeof...(TRn);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -143,6 +143,14 @@ inline void push(lua_State* L, lua_CFunction func) {
|
||||||
lua_pushcfunction( L, func );
|
lua_pushcfunction( L, func );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void push( lua_State* L, lua_CFunction func, int n ) {
|
||||||
|
lua_pushcclosure( L, func, n );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void push( lua_State* L, void* userdata ) {
|
||||||
|
lua_pushlightuserdata( L, userdata );
|
||||||
|
}
|
||||||
|
|
||||||
template<size_t N>
|
template<size_t N>
|
||||||
inline void push(lua_State* L, const char (&str)[N]) {
|
inline void push(lua_State* L, const char (&str)[N]) {
|
||||||
lua_pushlstring(L, str, N - 1);
|
lua_pushlstring(L, str, N - 1);
|
||||||
|
|
|
@ -35,7 +35,8 @@ template<class T, class U, class... Args>
|
||||||
struct are_same<T, U, Args...> : std::integral_constant<bool, std::is_same<T, U>::value && are_same<T, Args...>::value> {};
|
struct are_same<T, U, Args...> : std::integral_constant<bool, std::is_same<T, U>::value && are_same<T, Args...>::value> {};
|
||||||
|
|
||||||
int atpanic(lua_State* L) {
|
int atpanic(lua_State* L) {
|
||||||
throw sol_error(lua_tostring(L, -1));
|
std::string err = lua_tostring( L, -1 );
|
||||||
|
throw sol_error( err );
|
||||||
}
|
}
|
||||||
} // detail
|
} // detail
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ public:
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
void open_libraries(Args&&... args) {
|
void open_libraries(Args&&... args) {
|
||||||
static_assert(detail::are_same<lib, Args...>{}, "all types must be libraries");
|
static_assert(detail::are_same<lib, Args...>::value, "all types must be libraries");
|
||||||
if(sizeof...(args) == 0) {
|
if(sizeof...(args) == 0) {
|
||||||
luaL_openlibs(L.get());
|
luaL_openlibs(L.get());
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -32,8 +32,8 @@ class table : virtual public reference {
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, std::shared_ptr<detail::lua_func>> funcs;
|
std::unordered_map<std::string, std::shared_ptr<detail::lua_func>> funcs;
|
||||||
public:
|
public:
|
||||||
table() noexcept: reference{} {}
|
table() noexcept: reference(), funcs() {}
|
||||||
table(lua_State* L, int index = -1): reference(L, index) {
|
table(lua_State* L, int index = -1): reference(L, index), funcs() {
|
||||||
type_assert(L, index, type::table);
|
type_assert(L, index, type::table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,21 +92,37 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
table& set_fx(T&& key, std::unique_ptr<detail::lua_func> funcptr) {
|
table& set_fx(T&& key, std::unique_ptr<detail::lua_func> luafunc) {
|
||||||
std::string fkey(key);
|
std::string fkey(key);
|
||||||
auto hint = funcs.find(fkey);
|
auto hint = funcs.find(fkey);
|
||||||
if (hint == funcs.end()) {
|
if (hint == funcs.end()) {
|
||||||
std::shared_ptr<detail::lua_func> sptr(funcptr.release());
|
std::shared_ptr<detail::lua_func> sptr(luafunc.release());
|
||||||
hint = funcs.emplace_hint(hint, fkey, std::move(sptr));
|
hint = funcs.emplace_hint(hint, fkey, std::move(sptr));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
hint->second.reset(funcptr.release());
|
hint->second.reset(luafunc.release());
|
||||||
}
|
}
|
||||||
detail::lua_func* target = hint->second.get();
|
detail::lua_func* target = hint->second.get();
|
||||||
|
void* userdata = static_cast<void*>( target );
|
||||||
lua_CFunction freefunc = &detail::lua_cfun;
|
lua_CFunction freefunc = &detail::lua_cfun;
|
||||||
lua_pushlightuserdata(state(), static_cast<void*>(target));
|
const char* freefuncname = hint->first.c_str( );
|
||||||
lua_pushcclosure(state(), freefunc, 1);
|
const luaL_Reg funcreg[ 2 ] = {
|
||||||
lua_setglobal(state(), fkey.c_str());
|
{ freefuncname, freefunc },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
push( );
|
||||||
|
|
||||||
|
/*//lua_pushlightuserdata( state(), userdata );
|
||||||
|
lua_pushstring( state(), freefuncname ); // push key onto stack
|
||||||
|
lua_pushcclosure( state(), freefunc, 1 ); // push value onto stack
|
||||||
|
lua_settable( state(), -3 );
|
||||||
|
*/
|
||||||
|
|
||||||
|
lua_pushlightuserdata( state( ), userdata );
|
||||||
|
luaL_setfuncs( state( ), funcreg, 1 );
|
||||||
|
|
||||||
|
lua_pop( state( ), 1 );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user