From: Rui Guo Date: Fri, 12 Jun 2009 08:31:09 +0000 (+0800) Subject: Fix duplicate check on event hooking. X-Git-Url: https://repo.or.cz/w/screen-lua.git/commitdiff_plain/5c6029cfb2d285552af17c7478727ea672a52421 Fix duplicate check on event hooking. --- diff --git a/src/lua.c b/src/lua.c index 8a9c527..496e7bb 100644 --- a/src/lua.c +++ b/src/lua.c @@ -79,6 +79,7 @@ static int LuaDispatch(void *handler, const char *params, va_list va); static int LuaRegEvent(lua_State *L); static int LuaUnRegEvent(lua_State *L); static void LuaShowErr(lua_State *L); +struct binding lua_binding; typedef int lua_handler; #define LuaAllocHandler(a) a @@ -880,7 +881,7 @@ LuaPushHandler(lua_State *L, lua_handler lh) { int keyfunc; luaL_getmetatable(L, "screen"); - keyfunc = LuaPushHTable(L, -1, "_keyfunc"); + keyfunc = LuaPushHTable(L, lua_gettop(L), "_keyfunc"); lua_rawgeti(L, keyfunc, lh); lua_replace(L, -3); lua_pop(L, 1); @@ -1015,6 +1016,12 @@ LuaCheckHandler(lua_State *L, int idx, int reg) return LuaAllocHandler(key); } +int +LuaHdlrComp(lua_handler h1, lua_handler h2) +{ + return h1 - h2; +} + /* }}} **/ static int @@ -1110,7 +1117,8 @@ LuaRegEvent(lua_State *L) if (!l) return luaL_error(L, "Out of memory"); l->priv = priv; - l->dispatcher = LuaDispatch; + l->bd = &lua_binding; + l->handler = (void *)lh; if (register_listener(sev, l)) { const char *fname = LuaHGetName(L, lh); @@ -1121,7 +1129,6 @@ LuaRegEvent(lua_State *L) return luaL_error(L, "Handler has already been registered"); } /* Return the handler for un-register */ - l->handler = (void *)lh; lua_pushlightuserdata(L, l); } else @@ -1185,6 +1192,8 @@ struct binding lua_binding = LuaFinit, LuaCall, LuaSource, + LuaDispatch, + LuaHdlrComp, 0, /*b_next*/ &LuaFuncs }; diff --git a/src/script.c b/src/script.c index 91e913f..81befdc 100644 --- a/src/script.c +++ b/src/script.c @@ -202,8 +202,8 @@ register_listener(struct script_event *ev, struct listener *l) { iter = iter->chain; /* return if duplicate found*/ - if (iter->handler == l->handler - && iter->dispatcher == l->dispatcher) + if (iter->bd == l->bd + && !iter->bd->bd_hdlrcmp(iter->handler, l->handler)) return 1; } p = iter; @@ -212,9 +212,8 @@ register_listener(struct script_event *ev, struct listener *l) { iter = iter->chain; /* return if duplicate found*/ - /*FIXME: this check will not work*/ - if (iter->handler == l->handler - && iter->dispatcher == l->dispatcher) + if (iter->bd == l->bd + && !iter->bd->bd_hdlrcmp(iter->handler, l->handler)) return 1; } @@ -256,7 +255,7 @@ trigger_sevent(struct script_event *ev, VA_DOTS) while (chain) { VA_START(va, ev); - res = chain->dispatcher(chain->handler, params, va); + res = chain->bd->bd_dispatch(chain->handler, params, va); VA_END(va); if (res) break; diff --git a/src/script.h b/src/script.h index 307cb69..36e347c 100644 --- a/src/script.h +++ b/src/script.h @@ -40,6 +40,12 @@ struct binding int (*bd_call) __P((char *func, char **argv)); /*Returns zero on failure, non zero on success*/ int (*bd_Source) __P((const char *, int)); + /* The return value is significant: + * a non-zero value will stop further + * notification to the rest of the chain.*/ + int (*bd_dispatch) __P((void *handler, const char *params, va_list va)); + int (*bd_hdlrcmp) __P((void * h1, void *h2)); + struct binding *b_next; struct ScriptFuncs *fns; }; @@ -56,13 +62,8 @@ struct listener { /*Binding dependent event handler data*/ void *handler; + struct binding *bd; - /* dispatcher provided by the binding. - * The return value is significant: - * a non-zero value will stop further - * notification to the rest of the chain.*/ - int (*dispatcher) __P((void *handler, const char *params, va_list va)); - /* smaller means higher privilege.*/ unsigned int priv; struct listener *chain;