lm_message_handler.c
changeset 0 84fdfb0344c9
child 6 90073cbb535d
--- /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 <lua.h>
+#include <lauxlib.h>
+#include <glib.h>
+#include <loudmouth/loudmouth.h>
+
+#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;
+}
+