|
@@ -25,6 +25,11 @@
|
|
|
|
|
|
#include "sdl/Event.h"
|
|
#include "sdl/Event.h"
|
|
|
|
|
|
|
|
+// Put the Lua code directly into a raw string literal.
|
|
|
|
+static const char event_lua[] =
|
|
|
|
+#include "wrap_Event.lua"
|
|
|
|
+;
|
|
|
|
+
|
|
namespace love
|
|
namespace love
|
|
{
|
|
{
|
|
namespace event
|
|
namespace event
|
|
@@ -32,55 +37,82 @@ namespace event
|
|
|
|
|
|
#define instance() (Module::getInstance<Event>(Module::M_EVENT))
|
|
#define instance() (Module::getInstance<Event>(Module::M_EVENT))
|
|
|
|
|
|
-static int poll_i(lua_State *L)
|
|
|
|
|
|
+static const char *listenersKey = "_listeners";
|
|
|
|
+
|
|
|
|
+static int processMessage(lua_State *L, Message *m)
|
|
{
|
|
{
|
|
- Message *m;
|
|
|
|
|
|
+ if (m == nullptr)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ int args = m->toLua(L);
|
|
|
|
+
|
|
|
|
+ // Push the love.event[listenersKey][eventname] table onto the stack.
|
|
|
|
+ lua_getfield(L, lua_upvalueindex(1), listenersKey);
|
|
|
|
+ lua_getfield(L, -1, m->getName().c_str());
|
|
|
|
|
|
- while (instance()->poll(m))
|
|
|
|
|
|
+ if (lua_istable(L, -1))
|
|
{
|
|
{
|
|
- int args = m->toLua(L);
|
|
|
|
- m->release();
|
|
|
|
- return args;
|
|
|
|
|
|
+ int len = (int) luax_objlen(L, -1);
|
|
|
|
+
|
|
|
|
+ // Each array entry in the table is a listener function we should call.
|
|
|
|
+ for (int i = 1; i <= len; i++)
|
|
|
|
+ {
|
|
|
|
+ lua_rawgeti(L, -1, i);
|
|
|
|
+
|
|
|
|
+ // Push all message args (including the event name), in order.
|
|
|
|
+ for (int j = 1; j <= args; j++)
|
|
|
|
+ lua_pushvalue(L, -(args + 3));
|
|
|
|
+
|
|
|
|
+ lua_call(L, args, 0);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- // No pending events.
|
|
|
|
- return 0;
|
|
|
|
|
|
+ lua_pop(L, 2);
|
|
|
|
+
|
|
|
|
+ m->release();
|
|
|
|
+
|
|
|
|
+ // Leave the message's args on the stack.
|
|
|
|
+ return args;
|
|
}
|
|
}
|
|
|
|
|
|
-int w_pump(lua_State *)
|
|
|
|
|
|
+static int w_poll_i(lua_State *L)
|
|
{
|
|
{
|
|
- instance()->pump();
|
|
|
|
|
|
+ Message *m = nullptr;
|
|
|
|
+
|
|
|
|
+ if (instance()->poll(m))
|
|
|
|
+ return processMessage(L, m);
|
|
|
|
+
|
|
|
|
+ // No pending events.
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
int w_poll(lua_State *L)
|
|
int w_poll(lua_State *L)
|
|
{
|
|
{
|
|
- lua_pushcclosure(L, &poll_i, 0);
|
|
|
|
|
|
+ // w_poll_i needs access to the love.event table via an upvalue.
|
|
|
|
+ lua_pushvalue(L, lua_upvalueindex(1));
|
|
|
|
+ lua_pushcclosure(L, w_poll_i, 1);
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
-int w_wait(lua_State *L)
|
|
|
|
|
|
+int w_pump(lua_State *)
|
|
{
|
|
{
|
|
- Message *m;
|
|
|
|
-
|
|
|
|
- if ((m = instance()->wait()))
|
|
|
|
- {
|
|
|
|
- int args = m->toLua(L);
|
|
|
|
- m->release();
|
|
|
|
- return args;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ instance()->pump();
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+int w_wait(lua_State *L)
|
|
|
|
+{
|
|
|
|
+ Message *m = instance()->wait();
|
|
|
|
+ return processMessage(L, m);
|
|
|
|
+}
|
|
|
|
+
|
|
int w_push(lua_State *L)
|
|
int w_push(lua_State *L)
|
|
{
|
|
{
|
|
- Message *m;
|
|
|
|
|
|
+ Message *m = Message::fromLua(L, 1);
|
|
|
|
|
|
- bool success = (m = Message::fromLua(L, 1)) != NULL;
|
|
|
|
- luax_pushboolean(L, success);
|
|
|
|
|
|
+ luax_pushboolean(L, m != nullptr);
|
|
|
|
|
|
- if (!success)
|
|
|
|
|
|
+ if (m == nullptr)
|
|
return 1;
|
|
return 1;
|
|
|
|
|
|
instance()->push(m);
|
|
instance()->push(m);
|
|
@@ -117,6 +149,7 @@ int w_quit(lua_State *L)
|
|
// List of functions to wrap.
|
|
// List of functions to wrap.
|
|
static const luaL_Reg functions[] =
|
|
static const luaL_Reg functions[] =
|
|
{
|
|
{
|
|
|
|
+ // addListener and removeListener are defined in wrap_Event.lua
|
|
{ "pump", w_pump },
|
|
{ "pump", w_pump },
|
|
{ "poll", w_poll },
|
|
{ "poll", w_poll },
|
|
{ "wait", w_wait },
|
|
{ "wait", w_wait },
|
|
@@ -143,7 +176,19 @@ extern "C" int luaopen_love_event(lua_State *L)
|
|
w.functions = functions;
|
|
w.functions = functions;
|
|
w.types = nullptr;
|
|
w.types = nullptr;
|
|
|
|
|
|
- return luax_register_module(L, w);
|
|
|
|
|
|
+ int ret = luax_register_module(L, w);
|
|
|
|
+
|
|
|
|
+ // love.event[listenersKey] = {}
|
|
|
|
+ lua_newtable(L);
|
|
|
|
+ lua_setfield(L, -2, listenersKey);
|
|
|
|
+
|
|
|
|
+ // Execute wrap_Event.lua, sending the event and listeners tables as args.
|
|
|
|
+ luaL_loadbuffer(L, event_lua, sizeof(event_lua), "wrap_Event.lua");
|
|
|
|
+ lua_pushvalue(L, -2);
|
|
|
|
+ lua_getfield(L, -1, listenersKey);
|
|
|
|
+ lua_call(L, 2, 0);
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
} // event
|
|
} // event
|