Add main.hook_run
authorMyhailo Danylenko <isbear@ukrpost.net>
Sat, 13 Oct 2012 20:57:03 +0300
changeset 137 4fda19d05965
parent 136 2b04fad2f61a
child 138 832ded5b44c9
Add main.hook_run
lua.c
--- a/lua.c	Fri Oct 12 21:24:44 2012 +0300
+++ b/lua.c	Sat Oct 13 20:57:03 2012 +0300
@@ -1403,6 +1403,55 @@
 	return ret;
 }
 
+/// main.hook_run
+/// Runs handlers for given hook with supplied arguments.
+/// A: string (hook name), table (hook arguments)
+/// R: return enum field (hook handler result)
+static int lua_main_hook_run ( lua_State *L )
+{
+	const char * hook_name = luaL_checkstring ( L, 1 );
+	int          num       = 1;
+	hk_arg_t *   args;
+	guint        ret;
+	lua_settop ( L, 2 );                            // 1 name, 2 args_in
+	luaL_argcheck ( L, lua_type ( L, 2 ) == LUA_TTABLE, 2, "table with hook arguments expected" );
+	// count fields, build temporary stringified table
+	lua_newtable ( L );                             // 3 args
+	lua_pushnil ( L );                              // 4 key
+	while ( lua_next ( L, 2 ) != 0 ) {              // 5 value
+		int ktype = lua_type ( L, 4 );
+		if ( ktype == LUA_TSTRING || ktype == LUA_TNUMBER ) {
+			int vtype = lua_type ( L, 5 );
+			if ( vtype == LUA_TSTRING || vtype == LUA_TNUMBER ) {
+				lua_pushvalue ( L, 4 ); // 6 key copy
+				lua_pushvalue ( L, 5 ); // 7 value copy
+				lua_tostring ( L, 6 );
+				lua_tostring ( L, 7 );
+				lua_settable ( L, 3 );  // 5 value
+				num ++;
+			}
+		}
+		lua_pop ( L, 1 );                       // 4 key
+	}
+	// alloc args, populate from temporary table
+	args = luaL_malloc ( L, num * sizeof ( hk_arg_t ) );
+	num  = 0;
+	lua_pushnil ( L );                              // 4 key
+	while ( lua_next ( L, 3 ) != 0 ) {              // 5 value
+		( args + num ) -> name  = lua_tostring ( L, 4 );
+		( args + num ) -> value = lua_tostring ( L, 5 );
+		num ++;
+		lua_pop ( L, 1 );                       // 4 key
+	}
+	( args + num ) -> name  = NULL;
+	( args + num ) -> value = NULL;
+	// run hook
+	ret = hk_run_handlers ( hook_name, args );
+	luaL_free ( L, args );
+	luaL_pushenum ( L, ret, lua_hook_handler_result );
+	return 1;
+}
+
 /// main.hook
 /// Installs hook handler, returns an object, that you need to keep until
 /// hook handling is no more needed.
@@ -1681,6 +1730,7 @@
 	reg ( timer          ) 
 	reg ( bgread         ) 
 	reg ( hook           )
+	reg ( hook_run       )
 	reg ( add_guard      )
 	reg ( del_guard      )
 	{ NULL, NULL },