diff options
author | Nicolas "Pixel" Noble <pixel@nobis-crew.org> | 2013-07-25 10:58:33 +0200 |
---|---|---|
committer | Nicolas "Pixel" Noble <pixel@nobis-crew.org> | 2013-07-25 10:58:33 +0200 |
commit | 8bb55a25830c3f7d2c67c8571786b6806fb8f515 (patch) | |
tree | 9ff9531f33c82fa1dd23695982c8d1f53dcbd1ad /includes | |
parent | b92f0cee87ae48608c279d7192872b83a29b8fc5 (diff) |
Lua now properly yields when an operation throws EAgain.
Diffstat (limited to 'includes')
-rw-r--r-- | includes/BLua.h | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/includes/BLua.h b/includes/BLua.h index bf7caae..e11c3fb 100644 --- a/includes/BLua.h +++ b/includes/BLua.h @@ -1,5 +1,7 @@ #pragma once +#include <functional> + extern "C" { #include <lua.h> #include <lauxlib.h> @@ -7,6 +9,7 @@ extern "C" { #include <Exceptions.h> #include <Handle.h> +#include <Task.h> namespace Balau { @@ -271,8 +274,16 @@ template <class T> T * LuaObjectFactory::getMe(Lua & L, int idx) { return L.recast<T>(idx); } class LuaHelpersBase { + public: + static bool resume(Lua & L); + static Events::BaseEvent * getEvent(Lua & L); protected: static void validate(const lua_functypes_t & entry, bool method, int n, Lua & L, const char * className); + static void pushContext(Lua & L, std::function<int(Lua & L)> context, Events::BaseEvent * evt); + private: + LuaHelpersBase(std::function<int(Lua & L)> context, Events::BaseEvent * evt) : m_context(context), m_evt(evt) { } + std::function<int(Lua & L)> m_context; + Events::BaseEvent * m_evt; }; template <class T> @@ -280,6 +291,39 @@ class LuaHelpers : public LuaHelpersBase { public: static int method_multiplex(int caller, lua_State * __L, int (*proceed)(Lua & L, int n, T * obj, int caller), int (*proceed_static)(Lua & L, int n, int caller), lua_functypes_t * tab, bool method) { Lua L(__L); + return method_multiplex(caller, L, proceed, proceed_static, tab, method); + } + + private: + static int method_multiplex(int caller, Lua & L, int (*proceed)(Lua & L, int n, T * obj, int caller), int (*proceed_static)(Lua & L, int n, int caller), lua_functypes_t * tab, bool method) { + int r; + + try { + r = method_multiplex_internal(caller, L, proceed, proceed_static, tab, method); + } + catch (EAgain e) { + pushContext(L, [caller, proceed, proceed_static, tab, method](Lua & L) -> int { return method_multiplex_resume(caller, L, proceed, proceed_static, tab, method); }, e.getEvent()); + r = L.yield(L.gettop()); + } + + return r; + } + + static int method_multiplex_resume(int caller, Lua & L, int (*proceed)(Lua & L, int n, T * obj, int caller), int (*proceed_static)(Lua & L, int n, int caller), lua_functypes_t * tab, bool method) { + int r; + + try { + r = method_multiplex_internal(caller, L, proceed, proceed_static, tab, method); + } + catch (EAgain e) { + pushContext(L, [caller, proceed, proceed_static, tab, method](Lua & L) -> int { return method_multiplex_resume(caller, L, proceed, proceed_static, tab, method); }, e.getEvent()); + r = -1; + } + + return r; + } + + static int method_multiplex_internal(int caller, Lua & L, int (*proceed)(Lua & L, int n, T * obj, int caller), int (*proceed_static)(Lua & L, int n, int caller), lua_functypes_t * tab, bool method) { int add = method ? 1 : 0; int n = L.gettop() - add; T * obj = 0; |