From e1281bde1781c5c8fcf1aff31be104628d754618 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 20 Oct 2009 02:19:43 +0000 Subject: [PATCH] added registerEventHandler() and clearEventHandler() Engine functions with ag:: lua interfaces git-svn-id: svn://anubis/anaglym/trunk@115 99a6e188-d820-4881-8870-2d33a10e2619 --- Engine.cc | 75 +++++++++++++++++++++++++++++++++++++++----- Engine.h | 4 +++ ag.cc | 12 +++++++ ag.h | 2 ++ tests/cratestack.lua | 8 +++++ 5 files changed, 93 insertions(+), 8 deletions(-) diff --git a/Engine.cc b/Engine.cc index 50c558e..4933cc6 100644 --- a/Engine.cc +++ b/Engine.cc @@ -17,9 +17,16 @@ #include using namespace std; -#define checkForFunction(lua_name, event) \ - checkForFunctionFull(lua_name, #event, m_event_ ## event ## _present) #define AG_EVENT_PREFIX "__ag_event_" +#define EVENT_PRESENT_FLAG(event) m_event_ ## event ## _present +#define EVENT_HANDLER_AG_NAME(event) AG_EVENT_PREFIX #event +#define checkForFunction(lua_name, event) \ + checkForFunctionFull(lua_name, #event, EVENT_PRESENT_FLAG(event)) +#define doRegisterHandler(index, event) \ + doRegisterHandlerFull(index, EVENT_HANDLER_AG_NAME(event), \ + EVENT_PRESENT_FLAG(event)) +#define doClearHandler(event) \ + do { EVENT_PRESENT_FLAG(event) = false; } while(0) Engine * g_engine; @@ -250,6 +257,50 @@ int Engine::setCamera(lua_State * L) return 0; } +int Engine::registerEventHandler(lua_State * L) +{ + int argc = lua_gettop(L); + if (argc == 2 && lua_isfunction(L, 1) && lua_isstring(L, 2)) + { + string event = lua_tostring(L, 2); + if (event == "update") + doRegisterHandler(1, update); + else if (event == "key_down") + doRegisterHandler(1, key_down); + else if (event == "key_up") + doRegisterHandler(1, key_up); + else if (event == "mousebutton_down") + doRegisterHandler(1, mousebutton_down); + else if (event == "mousebutton_up") + doRegisterHandler(1, mousebutton_up); + else if (event == "mouse_motion") + doRegisterHandler(1, mouse_motion); + } + return 0; +} + +int Engine::clearEventHandler(lua_State * L) +{ + int argc = lua_gettop(L); + if (argc == 1 && lua_isstring(L, 1)) + { + string event = lua_tostring(L, 1); + if (event == "update") + doClearHandler(update); + else if (event == "key_down") + doClearHandler(key_down); + else if (event == "key_up") + doClearHandler(key_up); + else if (event == "mousebutton_down") + doClearHandler(mousebutton_down); + else if (event == "mousebutton_up") + doClearHandler(mousebutton_up); + else if (event == "mouse_motion") + doClearHandler(mouse_motion); + } + return 0; +} + int Engine::loadModel(const string & name, bool static_data, float scale) { size_t pos = name.find_first_not_of(FILENAME_SAFE_CHARS); @@ -377,7 +428,7 @@ void Engine::update_event() if (m_event_update_present) { lua_getfield(m_luaState, LUA_GLOBALSINDEX, - AG_EVENT_PREFIX "update_event"); + EVENT_HANDLER_AG_NAME(update_event)); /* call the update function - pops the function ref from the stack */ int s = lua_pcall(m_luaState, 0, LUA_MULTRET, 0); reportErrors(s); @@ -395,7 +446,7 @@ void Engine::key_down_event(int keysym) if (m_event_key_down_present) { lua_getfield(m_luaState, LUA_GLOBALSINDEX, - AG_EVENT_PREFIX "key_down"); + EVENT_HANDLER_AG_NAME(key_down)); lua_pushstring(m_luaState, sdl_keymap[keysym]); /* call the key down event function * This pops the function ref and arguments from the stack */ @@ -410,7 +461,7 @@ void Engine::key_up_event(int keysym) if (m_event_key_up_present) { lua_getfield(m_luaState, LUA_GLOBALSINDEX, - AG_EVENT_PREFIX "key_up"); + EVENT_HANDLER_AG_NAME(key_up)); lua_pushstring(m_luaState, sdl_keymap[keysym]); /* call the key up event function * This pops the function ref and arguments from the stack */ @@ -424,7 +475,7 @@ void Engine::mousebutton_down_event(int button, int x, int y) if (m_event_mousebutton_down_present) { lua_getfield(m_luaState, LUA_GLOBALSINDEX, - AG_EVENT_PREFIX "mousebutton_down"); + EVENT_HANDLER_AG_NAME(mousebutton_down)); lua_pushinteger(m_luaState, button); lua_pushnumber(m_luaState, x); lua_pushnumber(m_luaState, y); @@ -440,7 +491,7 @@ void Engine::mousebutton_up_event(int button, int x, int y) if (m_event_mousebutton_up_present) { lua_getfield(m_luaState, LUA_GLOBALSINDEX, - AG_EVENT_PREFIX "mousebutton_up"); + EVENT_HANDLER_AG_NAME(mousebutton_up)); lua_pushinteger(m_luaState, button); lua_pushnumber(m_luaState, x); lua_pushnumber(m_luaState, y); @@ -456,7 +507,7 @@ void Engine::mouse_motion_event(int x, int y, int xrel, int yrel) if (m_event_mouse_motion_present) { lua_getfield(m_luaState, LUA_GLOBALSINDEX, - AG_EVENT_PREFIX "mouse_motion"); + EVENT_HANDLER_AG_NAME(mouse_motion)); lua_pushnumber(m_luaState, x); lua_pushnumber(m_luaState, y); lua_pushnumber(m_luaState, xrel); @@ -485,6 +536,14 @@ void Engine::checkForFunctionFull(const std::string & lua_fn_name, } } +void Engine::doRegisterHandlerFull(int index, + const std::string & event_name, bool & presentFlag) +{ + lua_pushvalue(m_luaState, index); + lua_setfield(m_luaState, LUA_GLOBALSINDEX, event_name.c_str()); + presentFlag = true; +} + void Engine::doPhysics() { static Uint32 last_updated = 0; diff --git a/Engine.h b/Engine.h index 7898ed8..4ee07d2 100644 --- a/Engine.h +++ b/Engine.h @@ -109,6 +109,8 @@ class Engine /* lua services */ int setCamera(lua_State * L); + int registerEventHandler(lua_State * L); + int clearEventHandler(lua_State * L); protected: static Uint32 updateCallback(Uint32 interval, void * param); @@ -130,6 +132,8 @@ class Engine } void checkForFunctionFull(const std::string & lua_fn_name, const std::string & event_name, bool & presentFlag); + void doRegisterHandlerFull(int index, + const std::string & event_name, bool & presentFlag); Video & m_video; TextureCache m_textureCache; diff --git a/ag.cc b/ag.cc index 9ceea78..e59b0bc 100644 --- a/ag.cc +++ b/ag.cc @@ -37,6 +37,8 @@ namespace ag { "setAutoEndFrame", setAutoEndFrame }, { "setAutoDrawObjects", setAutoDrawObjects }, { "isKeyDown", isKeyDown }, + { "registerEventHandler", registerEventHandler }, + { "clearEventHandler", clearEventHandler }, { NULL, NULL } }; luaL_register(L, "ag", functions); @@ -266,6 +268,16 @@ namespace ag return 1; } + int registerEventHandler(lua_State * L) + { + return g_engine->registerEventHandler(L); + } + + int clearEventHandler(lua_State * L) + { + return g_engine->clearEventHandler(L); + } + namespace object { static Engine::Object * getObject(lua_State * L, int index) diff --git a/ag.h b/ag.h index 409a63e..0c26af3 100644 --- a/ag.h +++ b/ag.h @@ -23,6 +23,8 @@ namespace ag int setAutoEndFrame(lua_State * L); int setAutoDrawObjects(lua_State * L); int isKeyDown(lua_State * L); + int registerEventHandler(lua_State * L); + int clearEventHandler(lua_State * L); namespace object { diff --git a/tests/cratestack.lua b/tests/cratestack.lua index 499a7e3..2b2e8f7 100644 --- a/tests/cratestack.lua +++ b/tests/cratestack.lua @@ -32,5 +32,13 @@ function key_down_event(key) crates[cratenum] = nil cratenum = cratenum - 1 end + elseif (key == "m") then + ag.registerEventHandler(mouse_moves, "mouse_motion") + elseif (key == "n") then + ag.clearEventHandler("mouse_motion") end end + +function mouse_moves(x, y, xrel, yrel) + ag.println("mouse_moves ", x, ", ", y) +end