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:
ThePhD 2013-12-07 21:16:23 -05:00
parent a4a4d21376
commit 8c023c54a5
4 changed files with 39 additions and 14 deletions

View File

@ -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);
} }
}; };

View File

@ -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);

View File

@ -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;

View File

@ -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;
} }
}; };