aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/FbTk/Luamm.cc11
-rw-r--r--src/FbTk/Luamm.hh49
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
31namespace lua { 34namespace 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