diff options
Diffstat (limited to 'src/FbTk/Luamm.hh')
-rw-r--r-- | src/FbTk/Luamm.hh | 49 |
1 files changed, 32 insertions, 17 deletions
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 |