diff -r 000000000000 -r 84fdfb0344c9 lm_message_handler.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lm_message_handler.c Sun Feb 01 21:28:57 2009 +0200 @@ -0,0 +1,138 @@ + +#include +#include +#include +#include + +#include "lm_types.h" +#include "util.h" + +/// lm.message_handler +/// Module, representing message handling functions. + +/// message handler callback function +/// Callback function, used on incoming messages. +/// Should return true if message has been fully handled and no more +/// handlers should be called. +/// A: lm connection object, lm message object +/// R: boolean +LmHandlerResult llm_message_handler_callback (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, llm_callback_t *cb) +{ + int ret; + lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->reference); + llm_connection_bless (cb->L, connection); + // XXX lm_connection_unref (connection); + llm_message_bless (cb->L, message); + // XXX lm_message_unref (message); + if (lua_pcall (cb->L, 2, 1, 0)) { + // XXX lua_error (cb->L); + lua_pop (cb->L, 1); + return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + } + ret = lua_toboolean (cb->L, -1); + lua_pop (cb->L, 1); + if (ret) + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + else + return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; +} + +/// lm.message_handler.new +/// Creates new message handler object. +/// A: message handler callback function +/// R: lm message handler object +static int llm_message_handler_new (lua_State *L) +{ + llm_callback_t *cb; + LmMessageHandler *handler; + luaL_argcheck (L, lua_isfunction (L, 1), 1, "function expected"); + + cb = luaL_malloc (L, sizeof (llm_callback_t)); + cb->reference = luaL_ref (L, LUA_REGISTRYINDEX); + cb->L = L; + + handler = lm_message_handler_new ((LmHandleMessageFunction)llm_message_handler_callback, + cb, (GDestroyNotify)llm_callback_destroy); + llm_message_handler_bless (L, handler); + lm_message_handler_unref (handler); // XXX + return 1; +} + +/// lm.message_handler.bless +/// Blesses given pointer to lm message handler object. +/// A: lightuserdata (C lm message handler object) +/// R: lm message handler object +static int llm_message_handler_bless_lua (lua_State *L) +{ + luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "loudmouth message handler pointer expected"); + llm_message_handler_bless (L, lua_touserdata (L, 1)); + lua_remove (L, -2); + return 1; +} + +/// message_handler:invalidate +/// Invalidates handler. +static int llm_message_handler_invalidate (lua_State *L) +{ + llm_message_handler_t *object = luaL_checklm_message_handler (L, 1); + lm_message_handler_invalidate (object->message_handler); + lua_pop (L, 1); + return 0; +} + +/// message_handler:valid +/// Returns true if message handler is still valid. +/// R: boolean +static int llm_message_handler_valid (lua_State *L) +{ + llm_message_handler_t *object = luaL_checklm_message_handler (L, 1); + lua_pushboolean (L, lm_message_handler_is_valid (object->message_handler)); + lua_remove (L, -2); + return 1; +} + +/// message_handler:pointer +/// Returns pointer to underlying C loudmouth structure. +/// R: lightuserdata +static int llm_message_handler_pointer (lua_State *L) +{ + llm_message_handler_t *object = luaL_checklm_message_handler (L, 1); + lua_pushlightuserdata (L, object->message_handler); + lua_remove (L, -2); + return 1; +} + +static int llm_message_handler_gc (lua_State *L) +{ + llm_message_handler_t *object = luaL_checklm_message_handler (L, 1); + lm_message_handler_unref (object->message_handler); + lua_pop (L, 1); + return 0; +} + +static const luaL_Reg llm_message_handler_reg_f[] = { + { "new", llm_message_handler_new }, + { "bless", llm_message_handler_bless_lua }, + { NULL, NULL }, +}; + +static const luaL_Reg llm_message_handler_reg_m[] = { + { "invalidate", llm_message_handler_invalidate }, + { "valid", llm_message_handler_valid }, + { "pointer", llm_message_handler_pointer }, + { "__gc", llm_message_handler_gc }, + { NULL, NULL }, +}; + +int luaopen_lm_message_handler (lua_State *L) +{ + luaL_newmetatable (L, "loudmouth.message_handler"); + lua_pushstring (L, "__index"); + lua_pushvalue (L, -2); + lua_settable (L, -3); + luaL_register (L, NULL, llm_message_handler_reg_m); + lua_pop (L, 1); + luaL_register (L, "lm.message_handler", llm_message_handler_reg_f); + return 1; +} +