diff options
Diffstat (limited to 'degesch.c')
-rw-r--r-- | degesch.c | 55 |
1 files changed, 54 insertions, 1 deletions
@@ -7458,6 +7458,7 @@ enum lua_hook_type XLUA_HOOK_DEFUNCT, ///< No longer functional XLUA_HOOK_INPUT, ///< Input hook XLUA_HOOK_IRC, ///< IRC hook + XLUA_HOOK_TIMER, ///< One-shot timer }; struct lua_hook @@ -7466,9 +7467,11 @@ struct lua_hook enum lua_hook_type type; ///< Type of the hook union { - struct hook hook; ///< Base structure + struct hook hook; ///< Hook base structure struct input_hook input_hook; ///< Input hook struct irc_hook irc_hook; ///< IRC hook + + struct poller_timer timer; ///< Timer } data; ///< Hook data }; @@ -7485,6 +7488,9 @@ lua_hook_unhook (lua_State *L) case XLUA_HOOK_IRC: LIST_UNLINK (hook->plugin->ctx->irc_hooks, &hook->data.hook); break; + case XLUA_HOOK_TIMER: + poller_timer_reset (&hook->data.timer); + break; default: hard_assert (!"invalid hook type"); case XLUA_HOOK_DEFUNCT: @@ -7644,6 +7650,31 @@ struct irc_hook_vtable lua_irc_hook_vtable = // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +static void +lua_timer_hook_dispatch (void *user_data) +{ + struct lua_hook *hook = user_data; + struct lua_plugin *plugin = hook->plugin; + lua_State *L = plugin->L; + + lua_pushcfunction (L, lua_plugin_error_handler); + + lua_rawgetp (L, LUA_REGISTRYINDEX, hook); // 1: hook + lua_getuservalue (L, -1); // Retrieve function + lua_insert (L, -2); // Swap with the hook + + if (lua_pcall (L, 1, 0, -3)) + { + struct error *e = NULL; + (void) lua_plugin_process_error (plugin, lua_tostring (L, -1), &e); + log_global_error (plugin->ctx, "Lua: plugin \"#s\": #s: #s", + plugin->super.name, "timer hook", e->message); + error_free (e); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + static struct lua_hook * lua_plugin_push_hook (struct lua_plugin *plugin, int callback_index, enum lua_hook_type type, int priority) @@ -7691,10 +7722,32 @@ lua_plugin_hook_irc (lua_State *L) return 1; } +static int +lua_plugin_hook_timer (lua_State *L) +{ + struct lua_plugin *plugin = lua_touserdata (L, lua_upvalueindex (1)); + lua_Integer timeout = luaL_checkinteger (L, 2); + + if (timeout < 0) + luaL_argerror (L, 2, "timeout mustn't be negative"); + + // This doesn't really hook anything but we can reuse the code + struct lua_hook *hook = lua_plugin_push_hook + (plugin, 1, XLUA_HOOK_TIMER, 0 /* priority doesn't apply */); + + struct poller_timer *timer = &hook->data.timer; + poller_timer_init (timer, &plugin->ctx->poller); + timer->dispatcher = lua_timer_hook_dispatch; + timer->user_data = hook; + poller_timer_set (timer, timeout); + return 1; +} + static luaL_Reg lua_plugin_library[] = { { "hook_input", lua_plugin_hook_input }, { "hook_irc", lua_plugin_hook_irc }, + { "hook_timer", lua_plugin_hook_timer }, { NULL, NULL }, }; |