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>
int operator()(types<TRn...>, types<Args...> t, lua_State* L) {
auto r = stack::pop_call(L, fx, t);
stack::push(L, r);
stack::push(L, std::move( r ));
return sizeof...(TRn);
}
};

View File

@ -139,8 +139,16 @@ inline void push(lua_State* L, const nil_t&) {
lua_pushnil(L);
}
inline void push(lua_State* L, lua_CFunction func) {
lua_pushcfunction(L, func);
inline void push( lua_State* L, lua_CFunction 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>

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> {};
int atpanic(lua_State* L) {
throw sol_error(lua_tostring(L, -1));
std::string err = lua_tostring( L, -1 );
throw sol_error( err );
}
} // detail
@ -76,7 +77,7 @@ public:
template<typename... 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) {
luaL_openlibs(L.get());
return;

View File

@ -32,8 +32,8 @@ class table : virtual public reference {
private:
std::unordered_map<std::string, std::shared_ptr<detail::lua_func>> funcs;
public:
table() noexcept: reference{} {}
table(lua_State* L, int index = -1): reference(L, index) {
table() noexcept: reference(), funcs() {}
table(lua_State* L, int index = -1): reference(L, index), funcs() {
type_assert(L, index, type::table);
}
@ -92,22 +92,38 @@ private:
}
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);
auto hint = funcs.find(fkey);
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));
}
else {
hint->second.reset(funcptr.release());
hint->second.reset(luafunc.release());
}
detail::lua_func* target = hint->second.get();
void* userdata = static_cast<void*>( target );
lua_CFunction freefunc = &detail::lua_cfun;
lua_pushlightuserdata(state(), static_cast<void*>(target));
lua_pushcclosure(state(), freefunc, 1);
lua_setglobal(state(), fkey.c_str());
return *this;
const char* freefuncname = hint->first.c_str( );
const luaL_Reg funcreg[ 2 ] = {
{ 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;
}
};
} // sol