Switch to a custom event system, where SDL pumps into

To do this we needed to take ThreadVariant out of love.thread, and move it to common.
This also changes event names, instead of 1/2-letter abbreviations, full names!
This commit is contained in:
Bart van Strien
2011-12-13 17:50:38 +01:00
parent 91fefbd1ee
commit 083dd11185
13 changed files with 508 additions and 512 deletions
+68 -78
View File
@@ -42,35 +42,30 @@ namespace sdl
void Event::pump()
{
SDL_PumpEvents();
}
bool Event::poll(Message & message)
{
static SDL_Event e;
SDL_EnableUNICODE(1);
Message *msg;
while (SDL_PollEvent(&e))
{
if (convert(e, message))
return true;
msg = convert(e);
if (msg)
{
push(msg);
msg->release();
}
}
return false;
}
bool Event::wait(Message & message)
Message *Event::wait()
{
static SDL_Event e;
bool ok = (SDL_WaitEvent(&e) == 1);
return ok && convert(e, message);
}
bool Event::push(Message & message)
{
static SDL_Event e;
bool ok = convert(message, e);
return ok && (SDL_PushEvent(&e) == 0);
if (!ok)
return NULL;
return convert(e);
}
void Event::clear()
@@ -81,83 +76,78 @@ namespace sdl
{
// Do nothing with 'e' ...
}
while (!queue.empty())
{
queue.back()->release();
queue.pop();
}
}
bool Event::convert(SDL_Event & e, Message & m)
Message *Event::convert(SDL_Event & e)
{
Message *msg = NULL;
love::keyboard::Keyboard::Key key;
love::mouse::Mouse::Button button;
Variant *arg1, *arg2, *arg3;
const char *txt;
switch(e.type)
{
case SDL_KEYDOWN:
m.type = Event::TYPE_KEY_PRESSED;
m.keyboard.u = e.key.keysym.unicode;
return keys.find(e.key.keysym.sym, m.keyboard.k);
if (keys.find(e.key.keysym.sym, key) && love::event::Event::keys.find(key, txt))
{
arg1 = new Variant(txt, strlen(txt));
arg2 = new Variant((double) e.key.keysym.unicode);
msg = new Message("keypressed", 2, arg1, arg2);
arg1->release();
arg2->release();
}
break;
case SDL_KEYUP:
m.type = Event::TYPE_KEY_RELEASED;
return keys.find(e.key.keysym.sym, m.keyboard.k);
if (keys.find(e.key.keysym.sym, key) && love::event::Event::keys.find(key, txt))
{
arg1 = new Variant(txt, strlen(txt));
msg = new Message("keyreleased", 1, arg1);
arg1->release();
}
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
m.type = (e.type == SDL_MOUSEBUTTONDOWN) ? Event::TYPE_MOUSE_PRESSED : Event::TYPE_MOUSE_RELEASED;
m.mouse.x = e.button.x;
m.mouse.y = e.button.y;
return buttons.find(e.button.button, m.mouse.b);
if (buttons.find(e.button.button, button) && love::event::Event::buttons.find(button, txt))
{
arg1 = new Variant((double) e.button.x);
arg2 = new Variant((double) e.button.y);
arg3 = new Variant(txt, strlen(txt));
msg = new Message((e.type == SDL_MOUSEBUTTONDOWN) ?
"mousepressed" : "mousereleased", 3,
arg1, arg2, arg3);
arg1->release();
arg2->release();
arg3->release();
}
break;
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
m.type = (e.type == SDL_JOYBUTTONDOWN) ? Event::TYPE_JOYSTICK_PRESSED : Event::TYPE_JOYSTICK_RELEASED;
m.joystick.button = e.jbutton.button;
m.joystick.index = e.jbutton.which;
return true;
arg1 = new Variant((double) (e.jbutton.which+1));
arg2 = new Variant((double) (e.jbutton.button+1));
msg = new Message((e.type == SDL_JOYBUTTONDOWN) ?
"joystickpressed" : "joystickreleased", 2,
arg1, arg2);
arg1->release();
arg2->release();
break;
case SDL_ACTIVEEVENT:
arg1 = new Variant(e.active.gain != 0);
if (e.active.state & SDL_APPINPUTFOCUS)
{
m.type = Event::TYPE_FOCUS;
m.focus.f = (e.active.gain != 0);
return true;
}
else
break;
msg = new Message("focus", 1, arg1);
arg1->release();
break;
case SDL_QUIT:
m.type = Event::TYPE_QUIT;
return true;
msg = new Message("quit", 0);
break;
}
return false;
}
bool Event::convert(Message & m, SDL_Event & e)
{
switch(m.type)
{
case Event::TYPE_KEY_PRESSED:
e.type = SDL_KEYDOWN;
e.key.keysym.unicode = (Uint16)m.keyboard.u;
return keys.find(m.keyboard.k, e.key.keysym.sym);
case Event::TYPE_KEY_RELEASED:
e.type = SDL_KEYUP;
return keys.find(m.keyboard.k, e.key.keysym.sym);
case Event::TYPE_MOUSE_PRESSED:
case Event::TYPE_MOUSE_RELEASED:
e.type = (m.type == Event::TYPE_MOUSE_PRESSED) ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP;
e.button.x = m.mouse.x;
e.button.y = m.mouse.y;
return buttons.find(m.mouse.b, e.button.button);
case Event::TYPE_JOYSTICK_PRESSED:
case Event::TYPE_JOYSTICK_RELEASED:
e.type = (m.type == Event::TYPE_JOYSTICK_PRESSED) ? SDL_JOYBUTTONDOWN : SDL_JOYBUTTONUP;
e.jbutton.which = m.joystick.index;
e.jbutton.button = m.joystick.button;
return true;
case Event::TYPE_FOCUS:
e.type = SDL_ACTIVEEVENT;
e.active.state = SDL_APPINPUTFOCUS;
e.active.gain = m.focus.f;
case Event::TYPE_QUIT:
e.type = SDL_QUIT;
return true;
default:
return true;
}
return true;
return msg;
}
EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM>::Entry Event::keyEntries[] =
+2 -19
View File
@@ -51,28 +51,12 @@ namespace sdl
**/
void pump();
/**
* Checks if there are messages in the queue.
*
* @param message The next message in the queue, if the return value is true.
* @return True if there a message was found, false otherwise.
**/
bool poll(Message & message);
/**
* Waits for the next event (indefinitely). Useful for creating games where
* the screen and game state only needs updating when the user interacts with
* the window.
**/
bool wait(Message & message);
/**
* Push a message onto the event queue.
*
* @param message The message to push onto the queue.
* @return True on success, false if the queue was full.
**/
bool push(Message & message);
Message *wait();
/**
* Clears the event queue.
@@ -81,8 +65,7 @@ namespace sdl
private:
bool convert(SDL_Event & e, Message & m);
bool convert(Message & m, SDL_Event & e);
Message *convert(SDL_Event & e);
static EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM>::Entry keyEntries[];
static EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM> keys;
+16 -103
View File
@@ -34,104 +34,15 @@ namespace sdl
{
static Event * instance = 0;
static bool to_message(lua_State * L, Event::Message & msg)
{
const char * str = luaL_checkstring(L, 1);
if (!Event::getConstant(str, msg.type))
return false;
switch(msg.type)
{
case Event::TYPE_KEY_PRESSED:
if (!Event::getConstant(luaL_checkstring(L, 2), msg.keyboard.k))
return false;
msg.keyboard.u = (unsigned short)luaL_optint(L, 3, 0);
return true;
case Event::TYPE_KEY_RELEASED:
if (!Event::getConstant(luaL_checkstring(L, 2), msg.keyboard.k))
return false;
return true;
case Event::TYPE_MOUSE_PRESSED:
case Event::TYPE_MOUSE_RELEASED:
if (!Event::getConstant(luaL_checkstring(L, 2), msg.mouse.b))
return false;
msg.mouse.x = luaL_checkint(L, 3);
msg.mouse.y = luaL_checkint(L, 4);
return true;
case Event::TYPE_JOYSTICK_PRESSED:
case Event::TYPE_JOYSTICK_RELEASED:
msg.joystick.index = luaL_checkint(L, 2);
msg.joystick.button = luaL_checkint(L, 3);
return true;
case Event::TYPE_FOCUS:
msg.focus.f = luax_toboolean(L, 2);
return true;
case Event::TYPE_QUIT:
return true;
default:
return false;
}
return false;
}
static int push_message(lua_State * L, const Event::Message & msg)
{
const char * str = 0;
if (!Event::getConstant(msg.type, str))
return 0;
lua_pushstring(L, str);
switch(msg.type)
{
case Event::TYPE_KEY_PRESSED:
if (!Event::getConstant(msg.keyboard.k, str))
return 0;
lua_pushstring(L, str);
lua_pushinteger(L, msg.keyboard.u);
return 3;
case Event::TYPE_KEY_RELEASED:
if (!Event::getConstant(msg.keyboard.k, str))
return 0;
lua_pushstring(L, str);
return 2;
case Event::TYPE_MOUSE_PRESSED:
case Event::TYPE_MOUSE_RELEASED:
if (!Event::getConstant(msg.mouse.b, str))
return 0;
lua_pushinteger(L, msg.mouse.x);
lua_pushinteger(L, msg.mouse.y);
lua_pushstring(L, str);
return 4;
case Event::TYPE_JOYSTICK_PRESSED:
case Event::TYPE_JOYSTICK_RELEASED:
lua_pushinteger(L, msg.joystick.index+1);
lua_pushinteger(L, msg.joystick.button+1);
return 3;
case Event::TYPE_FOCUS:
lua_pushboolean(L, msg.focus.f);
return 2;
case Event::TYPE_QUIT:
return 1;
default:
return 0;
}
return 0;
}
static int poll_i(lua_State * L)
{
static Event::Message m;
Message *m;
while (instance->poll(m))
{
int args = push_message(L, m);
if (args > 0)
return args;
int args = m->toLua(L);
m->release();
return args;
}
// No pending events.
@@ -152,11 +63,13 @@ namespace sdl
int w_wait(lua_State * L)
{
static Event::Message m;
static Message *m;
if (instance->wait(m))
if ((m = instance->wait()))
{
return push_message(L, m);
int args = m->toLua(L);
m->release();
return args;
}
return 0;
@@ -164,17 +77,18 @@ namespace sdl
int w_push(lua_State * L)
{
static Event::Message m;
static Message *m;
if (!to_message(L, m))
if (!(m = Message::fromLua(L, 1)))
{
luax_pushboolean(L, false);
return 1;
}
luax_pushboolean(L, instance->push(m));
instance->push(m);
m->release();
return 1;
return 0;
}
int w_clear(lua_State *)
@@ -185,9 +99,8 @@ namespace sdl
int w_quit(lua_State * L)
{
static Event::Message m;
m.type = Event::TYPE_QUIT;
luax_pushboolean(L, instance->push(m));
Message *m = new Message("quit", 0);
instance->push(m);
return 1;
}