diff options
-rw-r--r-- | src/FbTk/Luamm.cc | 11 | ||||
-rw-r--r-- | src/FbTk/Luamm.hh | 49 |
2 files changed, 36 insertions, 24 deletions
diff --git a/src/FbTk/Luamm.cc b/src/FbTk/Luamm.cc index a4a6eca..81a8fb3 100644 --- a/src/FbTk/Luamm.cc +++ b/src/FbTk/Luamm.cc | |||
@@ -30,7 +30,7 @@ namespace lua { | |||
30 | const char cpp_exception_metatable[] = "lua::cpp_exception_metatable"; | 30 | const char cpp_exception_metatable[] = "lua::cpp_exception_metatable"; |
31 | const char cpp_function_metatable [] = "lua::cpp_function_metatable"; | 31 | const char cpp_function_metatable [] = "lua::cpp_function_metatable"; |
32 | const char lua_exception_namespace[] = "lua::lua_exception_namespace"; | 32 | const char lua_exception_namespace[] = "lua::lua_exception_namespace"; |
33 | const char this_cpp_object [] = "lua::this_cpp_object"; | 33 | const char this_cpp_object [] = "lua::this_cpp_object"; |
34 | 34 | ||
35 | // converts C++ exceptions to strings, so lua can do something with them | 35 | // converts C++ exceptions to strings, so lua can do something with them |
36 | int exception_to_string(lua_State *l) | 36 | int exception_to_string(lua_State *l) |
@@ -245,7 +245,7 @@ namespace lua { | |||
245 | newmetatable(cpp_function_metatable); | 245 | newmetatable(cpp_function_metatable); |
246 | pushboolean(false); | 246 | pushboolean(false); |
247 | rawsetfield(-2, "__metatable"); | 247 | rawsetfield(-2, "__metatable"); |
248 | pushdestructor<cpp_function>(); | 248 | pushdestructor<FbTk::Slot<int, state *> >(); |
249 | rawsetfield(-2, "__gc"); | 249 | rawsetfield(-2, "__gc"); |
250 | pop(); | 250 | pop(); |
251 | 251 | ||
@@ -399,16 +399,13 @@ namespace lua { | |||
399 | return r; | 399 | return r; |
400 | } | 400 | } |
401 | 401 | ||
402 | void state::pushclosure(const cpp_function &fn, int n) | 402 | void state::do_pushclosure(int n) |
403 | { | 403 | { |
404 | checkstack(2); | ||
405 | |||
406 | createuserdata<cpp_function>(fn); | ||
407 | rawgetfield(REGISTRYINDEX, cpp_function_metatable); | 404 | rawgetfield(REGISTRYINDEX, cpp_function_metatable); |
408 | setmetatable(-2); | 405 | setmetatable(-2); |
409 | 406 | ||
410 | insert(-n-1); | 407 | insert(-n-1); |
411 | lua_pushcclosure(cobj.get(), &closure_trampoline, n+1); | 408 | lua_pushcclosure(cobj, &closure_trampoline, n+1); |
412 | } | 409 | } |
413 | 410 | ||
414 | void state::rawgetfield(int index, const char *k) throw(std::bad_alloc) | 411 | void state::rawgetfield(int index, const char *k) throw(std::bad_alloc) |
diff --git a/src/FbTk/Luamm.hh b/src/FbTk/Luamm.hh index 1df5825..5c8d382 100644 --- a/src/FbTk/Luamm.hh +++ b/src/FbTk/Luamm.hh | |||
@@ -27,13 +27,15 @@ | |||
27 | #include <stdexcept> | 27 | #include <stdexcept> |
28 | 28 | ||
29 | #include <lua.h> | 29 | #include <lua.h> |
30 | #include <lauxlib.h> | ||
31 | |||
32 | #include "Slot.hh" | ||
30 | 33 | ||
31 | namespace lua { | 34 | namespace lua { |
32 | class state; | 35 | class state; |
33 | 36 | ||
34 | typedef lua_Integer integer; | 37 | typedef lua_Integer integer; |
35 | typedef lua_Number number; | 38 | typedef lua_Number number; |
36 | typedef std::function<int(state *)> cpp_function; | ||
37 | 39 | ||
38 | enum { | 40 | enum { |
39 | ENVIRONINDEX = LUA_ENVIRONINDEX, | 41 | ENVIRONINDEX = LUA_ENVIRONINDEX, |
@@ -175,7 +177,9 @@ namespace lua { | |||
175 | } | 177 | } |
176 | 178 | ||
177 | bool safe_compare(lua_CFunction trampoline, int index1, int index2); | 179 | bool safe_compare(lua_CFunction trampoline, int index1, int index2); |
178 | public: | 180 | void do_pushclosure(int n); |
181 | |||
182 | public: | ||
179 | state(); | 183 | state(); |
180 | 184 | ||
181 | /* | 185 | /* |
@@ -244,10 +248,12 @@ namespace lua { | |||
244 | bool newmetatable(const char *tname) { return luaL_newmetatable(cobj.get(), tname); } | 248 | bool newmetatable(const char *tname) { return luaL_newmetatable(cobj.get(), tname); } |
245 | void newtable() { lua_newtable(cobj.get()); } | 249 | void newtable() { lua_newtable(cobj.get()); } |
246 | void *newuserdata(size_t size) { return lua_newuserdata(cobj.get(), size); } | 250 | void *newuserdata(size_t size) { return lua_newuserdata(cobj.get(), size); } |
247 | // cpp_function can be anything that std::function can handle, everything else remains | 251 | // Functor can be anything that FbTk::Slot can handle, everything else remains |
248 | // identical | 252 | // identical |
249 | void pushclosure(const cpp_function &fn, int n); | 253 | template<typename Functor> |
250 | void pushfunction(const cpp_function &fn) { pushclosure(fn, 0); } | 254 | void pushclosure(const Functor &fn, int n); |
255 | template<typename Functor> | ||
256 | void pushfunction(const Functor &fn) { pushclosure(fn, 0); } | ||
251 | void pushstring(const char *s) { lua_pushstring(cobj.get(), s); } | 257 | void pushstring(const char *s) { lua_pushstring(cobj.get(), s); } |
252 | void pushstring(const char *s, size_t len) { lua_pushlstring(cobj.get(), s, len); } | 258 | void pushstring(const char *s, size_t len) { lua_pushlstring(cobj.get(), s, len); } |
253 | void pushstring(const std::string &s) { lua_pushlstring(cobj.get(), s.c_str(), s.size()); } | 259 | void pushstring(const std::string &s) { lua_pushlstring(cobj.get(), s.c_str(), s.size()); } |
@@ -262,8 +268,7 @@ namespace lua { | |||
262 | // std::function before we get a chance to call it. This pushes a function that simply | 268 | // std::function before we get a chance to call it. This pushes a function that simply |
263 | // calls ~T when the time comes. Only set it as __gc on userdata of type T. | 269 | // calls ~T when the time comes. Only set it as __gc on userdata of type T. |
264 | template<typename T> | 270 | template<typename T> |
265 | void pushdestructor() | 271 | void pushdestructor() { lua_pushcfunction(cobj.get(), &destroy_cpp_object<T>); } |
266 | { lua_pushcfunction(cobj.get(), &destroy_cpp_object<T>); } | ||
267 | 272 | ||
268 | // type c, throw everything but the kitchen sink | 273 | // type c, throw everything but the kitchen sink |
269 | // call() is a protected mode call, we don't allow unprotected calls | 274 | // call() is a protected mode call, we don't allow unprotected calls |
@@ -279,7 +284,8 @@ namespace lua { | |||
279 | void loadstring(const char *s) throw(lua::syntax_error, std::bad_alloc); | 284 | void loadstring(const char *s) throw(lua::syntax_error, std::bad_alloc); |
280 | bool next(int index); | 285 | bool next(int index); |
281 | // register is a reserved word :/ | 286 | // register is a reserved word :/ |
282 | void register_fn(const char *name, const cpp_function &f) { pushfunction(f); setglobal(name); } | 287 | template<typename Functor> |
288 | void register_fn(const char *name, const Functor &f) { pushfunction(f); setglobal(name); } | ||
283 | void setfield(int index, const char *k); | 289 | void setfield(int index, const char *k); |
284 | void setglobal(const char *name) { setfield(GLOBALSINDEX, name); } | 290 | void setglobal(const char *name) { setfield(GLOBALSINDEX, name); } |
285 | void settable(int index); | 291 | void settable(int index); |
@@ -327,15 +333,24 @@ namespace lua { | |||
327 | }; | 333 | }; |
328 | 334 | ||
329 | template<typename T, typename... Args> | 335 | template<typename T, typename... Args> |
330 | T* state::createuserdata(Args&&... args) | 336 | T* state::createuserdata(Args&&... args) |
331 | { | 337 | { |
332 | stack_sentry s(*this); | 338 | stack_sentry s(*this); |
333 | 339 | ||
334 | void *t = newuserdata(sizeof(T)); | 340 | void *t = newuserdata(sizeof(T)); |
335 | new(t) T(std::forward<Args>(args)...); | 341 | new(t) T(std::forward<Args>(args)...); |
336 | ++s; | 342 | ++s; |
337 | return static_cast<T *>(t); | 343 | return static_cast<T *>(t); |
338 | } | 344 | } |
345 | |||
346 | template<typename Functor> | ||
347 | void state::pushclosure(const Functor &fn, int n) | ||
348 | { | ||
349 | checkstack(2); | ||
350 | |||
351 | createuserdata<FbTk::SlotImpl<Functor, int, state *> >(fn); | ||
352 | do_pushclosure(n); | ||
353 | } | ||
339 | } | 354 | } |
340 | 355 | ||
341 | #endif // FBTK_LUAMM_HH | 356 | #endif // FBTK_LUAMM_HH |