aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2015-11-21 19:48:15 +0100
committerPřemysl Janouch <p.janouch@gmail.com>2015-11-21 19:48:15 +0100
commit02c7c6dcd692cb0f1c2bfaf8fa03bc3077fb8ac9 (patch)
tree04fda4f41acf48293d7610406997ec8104242908
parent364eb009ca5f22f9c8994578853e24fdd6e883a3 (diff)
downloadxK-02c7c6dcd692cb0f1c2bfaf8fa03bc3077fb8ac9.tar.gz
xK-02c7c6dcd692cb0f1c2bfaf8fa03bc3077fb8ac9.tar.xz
xK-02c7c6dcd692cb0f1c2bfaf8fa03bc3077fb8ac9.zip
degesch: export timers to Lua
-rw-r--r--degesch.c55
1 files changed, 54 insertions, 1 deletions
diff --git a/degesch.c b/degesch.c
index 3a80c3f..1f8a675 100644
--- a/degesch.c
+++ b/degesch.c
@@ -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 },
};