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
|
#define XLUA_BUFFER_METATABLE "buffer" ///< Identifier for the Lua metatable
|
||||||
|
|
||||||
struct lua_buffer
|
struct lua_buffer
|
||||||
|
@ -8409,6 +8586,32 @@ lua_buffer_gc (lua_State *L)
|
||||||
return 0;
|
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
|
static int
|
||||||
lua_buffer_get_server (lua_State *L)
|
lua_buffer_get_server (lua_State *L)
|
||||||
{
|
{
|
||||||
|
@ -8450,11 +8653,13 @@ lua_buffer_execute (lua_State *L)
|
||||||
static luaL_Reg lua_buffer_table[] =
|
static luaL_Reg lua_buffer_table[] =
|
||||||
{
|
{
|
||||||
// TODO: some useful methods or values
|
// TODO: some useful methods or values
|
||||||
{ "__gc", lua_buffer_gc },
|
{ "__gc", lua_buffer_gc },
|
||||||
{ "get_server", lua_buffer_get_server },
|
{ "get_user", lua_buffer_get_user },
|
||||||
{ "log", lua_buffer_log },
|
{ "get_channel", lua_buffer_get_channel },
|
||||||
{ "execute", lua_buffer_execute },
|
{ "get_server", lua_buffer_get_server },
|
||||||
{ NULL, NULL }
|
{ "log", lua_buffer_log },
|
||||||
|
{ "execute", lua_buffer_execute },
|
||||||
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -8472,6 +8677,19 @@ lua_server_gc (lua_State *L)
|
||||||
return 0;
|
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
|
static int
|
||||||
lua_server_get_buffer (lua_State *L)
|
lua_server_get_buffer (lua_State *L)
|
||||||
{
|
{
|
||||||
|
@ -8500,6 +8718,7 @@ static luaL_Reg lua_server_table[] =
|
||||||
{
|
{
|
||||||
// TODO: some useful methods or values
|
// TODO: some useful methods or values
|
||||||
{ "__gc", lua_server_gc },
|
{ "__gc", lua_server_gc },
|
||||||
|
{ "get_user", lua_server_get_user },
|
||||||
{ "get_buffer", lua_server_get_buffer },
|
{ "get_buffer", lua_server_get_buffer },
|
||||||
{ "send", lua_server_send },
|
{ "send", lua_server_send },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
|
@ -9631,6 +9850,8 @@ lua_plugin_load (struct app_context *ctx, const char *filename,
|
||||||
|
|
||||||
// Create metatables for our objects
|
// Create metatables for our objects
|
||||||
lua_plugin_create_meta (L, XLUA_HOOK_METATABLE, lua_hook_table);
|
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_BUFFER_METATABLE, lua_buffer_table);
|
||||||
lua_plugin_create_meta (L, XLUA_SERVER_METATABLE, lua_server_table);
|
lua_plugin_create_meta (L, XLUA_SERVER_METATABLE, lua_server_table);
|
||||||
lua_plugin_create_meta (L, XLUA_SCHEMA_METATABLE, lua_schema_table);
|
lua_plugin_create_meta (L, XLUA_SCHEMA_METATABLE, lua_schema_table);
|
||||||
|
|
Loading…
Reference in New Issue