degesch: expose channels and users to Lua
This commit is contained in:
parent
29418e5e55
commit
a9b77b3206
231
degesch.c
231
degesch.c
|
@ -8322,6 +8322,183 @@ lua_plugin_parse (lua_State *L)
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
#define XLUA_USER_METATABLE "user" ///< Identifier for the Lua metatable
|
||||
|
||||
struct lua_user
|
||||
{
|
||||
struct lua_plugin *plugin; ///< The plugin we belong to
|
||||
struct user *user; ///< The user
|
||||
struct weak_ref_link *weak_ref; ///< A weak reference link
|
||||
};
|
||||
|
||||
static void
|
||||
lua_user_invalidate (void *object, void *user_data)
|
||||
{
|
||||
struct lua_user *wrapper = user_data;
|
||||
wrapper->user = NULL;
|
||||
wrapper->weak_ref = NULL;
|
||||
// This can in theory call the GC, order isn't arbitrary here
|
||||
lua_cache_invalidate (wrapper->plugin->L, object);
|
||||
}
|
||||
|
||||
static void
|
||||
lua_plugin_push_user (struct lua_plugin *plugin, struct user *user)
|
||||
{
|
||||
lua_State *L = plugin->L;
|
||||
if (lua_cache_get (L, user))
|
||||
return;
|
||||
|
||||
struct lua_user *wrapper = lua_newuserdata (L, sizeof *wrapper);
|
||||
luaL_setmetatable (L, XLUA_USER_METATABLE);
|
||||
wrapper->plugin = plugin;
|
||||
wrapper->user = user;
|
||||
wrapper->weak_ref = user_weak_ref (user, lua_user_invalidate, wrapper);
|
||||
lua_cache_store (L, user, -1);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
/// Identifier for the Lua metatable
|
||||
#define XLUA_CHANNEL_METATABLE "channel"
|
||||
|
||||
struct lua_channel
|
||||
{
|
||||
struct lua_plugin *plugin; ///< The plugin we belong to
|
||||
struct channel *channel; ///< The channel
|
||||
struct weak_ref_link *weak_ref; ///< A weak reference link
|
||||
};
|
||||
|
||||
static void
|
||||
lua_channel_invalidate (void *object, void *user_data)
|
||||
{
|
||||
struct lua_channel *wrapper = user_data;
|
||||
wrapper->channel = NULL;
|
||||
wrapper->weak_ref = NULL;
|
||||
// This can in theory call the GC, order isn't arbitrary here
|
||||
lua_cache_invalidate (wrapper->plugin->L, object);
|
||||
}
|
||||
|
||||
static void
|
||||
lua_plugin_push_channel (struct lua_plugin *plugin, struct channel *channel)
|
||||
{
|
||||
lua_State *L = plugin->L;
|
||||
if (lua_cache_get (L, channel))
|
||||
return;
|
||||
|
||||
struct lua_channel *wrapper = lua_newuserdata (L, sizeof *wrapper);
|
||||
luaL_setmetatable (L, XLUA_CHANNEL_METATABLE);
|
||||
wrapper->plugin = plugin;
|
||||
wrapper->channel = channel;
|
||||
wrapper->weak_ref = channel_weak_ref
|
||||
(channel, lua_channel_invalidate, wrapper);
|
||||
lua_cache_store (L, channel, -1);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
static int
|
||||
lua_user_gc (lua_State *L)
|
||||
{
|
||||
struct lua_user *wrapper = luaL_checkudata (L, 1, XLUA_USER_METATABLE);
|
||||
if (wrapper->user)
|
||||
{
|
||||
lua_cache_invalidate (L, wrapper->user);
|
||||
user_weak_unref (wrapper->user, &wrapper->weak_ref);
|
||||
wrapper->user = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lua_user_get_nickname (lua_State *L)
|
||||
{
|
||||
struct lua_user *wrapper = luaL_checkudata (L, 1, XLUA_USER_METATABLE);
|
||||
luaL_argcheck (L, wrapper->user, 1, "dead reference used");
|
||||
lua_pushstring (L, wrapper->user->nickname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
lua_user_get_channels (lua_State *L)
|
||||
{
|
||||
struct lua_user *wrapper = luaL_checkudata (L, 1, XLUA_USER_METATABLE);
|
||||
luaL_argcheck (L, wrapper->user, 1, "dead reference used");
|
||||
|
||||
int i = 1;
|
||||
lua_newtable (L);
|
||||
LIST_FOR_EACH (struct user_channel, iter, wrapper->user->channels)
|
||||
{
|
||||
lua_plugin_push_channel (wrapper->plugin, iter->channel);
|
||||
lua_rawseti (L, -2, i++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static luaL_Reg lua_user_table[] =
|
||||
{
|
||||
{ "__gc", lua_user_gc },
|
||||
{ "get_nickname", lua_user_get_nickname },
|
||||
{ "get_channels", lua_user_get_channels },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
static int
|
||||
lua_channel_gc (lua_State *L)
|
||||
{
|
||||
struct lua_channel *wrapper =
|
||||
luaL_checkudata (L, 1, XLUA_CHANNEL_METATABLE);
|
||||
if (wrapper->channel)
|
||||
{
|
||||
lua_cache_invalidate (L, wrapper->channel);
|
||||
channel_weak_unref (wrapper->channel, &wrapper->weak_ref);
|
||||
wrapper->channel = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lua_channel_get_name (lua_State *L)
|
||||
{
|
||||
struct lua_channel *wrapper =
|
||||
luaL_checkudata (L, 1, XLUA_CHANNEL_METATABLE);
|
||||
luaL_argcheck (L, wrapper->channel, 1, "dead reference used");
|
||||
lua_pushstring (L, wrapper->channel->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
lua_channel_get_users (lua_State *L)
|
||||
{
|
||||
struct lua_channel *wrapper =
|
||||
luaL_checkudata (L, 1, XLUA_CHANNEL_METATABLE);
|
||||
luaL_argcheck (L, wrapper->channel, 1, "dead reference used");
|
||||
|
||||
int i = 1;
|
||||
lua_newtable (L);
|
||||
LIST_FOR_EACH (struct channel_user, iter, wrapper->channel->users)
|
||||
{
|
||||
lua_createtable (L, 0, 2);
|
||||
lua_plugin_push_user (wrapper->plugin, iter->user);
|
||||
lua_setfield (L, -2, "user");
|
||||
lua_plugin_kv (L, "prefixes", iter->prefixes.str);
|
||||
|
||||
lua_rawseti (L, -2, i++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static luaL_Reg lua_channel_table[] =
|
||||
{
|
||||
{ "__gc", lua_channel_gc },
|
||||
{ "get_name", lua_channel_get_name },
|
||||
{ "get_users", lua_channel_get_users },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
#define XLUA_BUFFER_METATABLE "buffer" ///< Identifier for the Lua metatable
|
||||
|
||||
struct lua_buffer
|
||||
|
@ -8409,6 +8586,32 @@ lua_buffer_gc (lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lua_buffer_get_user (lua_State *L)
|
||||
{
|
||||
struct lua_buffer *wrapper = luaL_checkudata (L, 1, XLUA_BUFFER_METATABLE);
|
||||
luaL_argcheck (L, wrapper->buffer, 1, "dead reference used");
|
||||
|
||||
if (wrapper->buffer->user)
|
||||
lua_plugin_push_user (wrapper->plugin, wrapper->buffer->user);
|
||||
else
|
||||
lua_pushnil (L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
lua_buffer_get_channel (lua_State *L)
|
||||
{
|
||||
struct lua_buffer *wrapper = luaL_checkudata (L, 1, XLUA_BUFFER_METATABLE);
|
||||
luaL_argcheck (L, wrapper->buffer, 1, "dead reference used");
|
||||
|
||||
if (wrapper->buffer->channel)
|
||||
lua_plugin_push_channel (wrapper->plugin, wrapper->buffer->channel);
|
||||
else
|
||||
lua_pushnil (L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
lua_buffer_get_server (lua_State *L)
|
||||
{
|
||||
|
@ -8450,11 +8653,13 @@ lua_buffer_execute (lua_State *L)
|
|||
static luaL_Reg lua_buffer_table[] =
|
||||
{
|
||||
// TODO: some useful methods or values
|
||||
{ "__gc", lua_buffer_gc },
|
||||
{ "get_server", lua_buffer_get_server },
|
||||
{ "log", lua_buffer_log },
|
||||
{ "execute", lua_buffer_execute },
|
||||
{ NULL, NULL }
|
||||
{ "__gc", lua_buffer_gc },
|
||||
{ "get_user", lua_buffer_get_user },
|
||||
{ "get_channel", lua_buffer_get_channel },
|
||||
{ "get_server", lua_buffer_get_server },
|
||||
{ "log", lua_buffer_log },
|
||||
{ "execute", lua_buffer_execute },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -8472,6 +8677,19 @@ lua_server_gc (lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lua_server_get_user (lua_State *L)
|
||||
{
|
||||
struct lua_server *wrapper = luaL_checkudata (L, 1, XLUA_SERVER_METATABLE);
|
||||
luaL_argcheck (L, wrapper->server, 1, "dead reference used");
|
||||
|
||||
if (wrapper->server->irc_user)
|
||||
lua_plugin_push_user (wrapper->plugin, wrapper->server->irc_user);
|
||||
else
|
||||
lua_pushnil (L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
lua_server_get_buffer (lua_State *L)
|
||||
{
|
||||
|
@ -8500,6 +8718,7 @@ static luaL_Reg lua_server_table[] =
|
|||
{
|
||||
// TODO: some useful methods or values
|
||||
{ "__gc", lua_server_gc },
|
||||
{ "get_user", lua_server_get_user },
|
||||
{ "get_buffer", lua_server_get_buffer },
|
||||
{ "send", lua_server_send },
|
||||
{ NULL, NULL }
|
||||
|
@ -9631,6 +9850,8 @@ lua_plugin_load (struct app_context *ctx, const char *filename,
|
|||
|
||||
// Create metatables for our objects
|
||||
lua_plugin_create_meta (L, XLUA_HOOK_METATABLE, lua_hook_table);
|
||||
lua_plugin_create_meta (L, XLUA_USER_METATABLE, lua_user_table);
|
||||
lua_plugin_create_meta (L, XLUA_CHANNEL_METATABLE, lua_channel_table);
|
||||
lua_plugin_create_meta (L, XLUA_BUFFER_METATABLE, lua_buffer_table);
|
||||
lua_plugin_create_meta (L, XLUA_SERVER_METATABLE, lua_server_table);
|
||||
lua_plugin_create_meta (L, XLUA_SCHEMA_METATABLE, lua_schema_table);
|
||||
|
|
Loading…
Reference in New Issue