From eab0940bcf7577a9542b474848ee376c581d898c Mon Sep 17 00:00:00 2001 From: whiteshark0 Date: Mon, 20 Apr 2009 12:47:39 +0000 Subject: hookable event nearly finished(unhook function missing) plugin Id now written to the lua states registry Usdx.Version added, Usdx.Hook added git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/experimental@1689 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Lua/src/lua/UHookableEvent.pas | 86 +++++++++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 30 deletions(-) (limited to 'Lua/src/lua/UHookableEvent.pas') diff --git a/Lua/src/lua/UHookableEvent.pas b/Lua/src/lua/UHookableEvent.pas index cc7cc443..d6ec2807 100644 --- a/Lua/src/lua/UHookableEvent.pas +++ b/Lua/src/lua/UHookableEvent.pas @@ -42,12 +42,14 @@ type Handle: Integer; //< Handle to identify the hook, e.g. for unhooking by plugin Parent: Integer; //< Lua Core Handle this hook belongs to + Func: String; //< Name of the global that holds the function + Next: PHook; //< Next Hook in list (nil for the first) end; { procedure is called before each call to the hooking lua functions, to push values on stack returns the number of pushed arguments} - PrepareStackProc = Function: Integer; + PrepareStackProc = Function(L: PLua_State): Integer; { class representing a hookable event } THookableEvent = class @@ -65,7 +67,7 @@ type property Name: String read sName; //< returns the events name property Handle: Integer read iHandle; //< returns the events name - procedure Hook(L: Plua_State; Parent: Integer; Proc: String); //< pushes hook object/table to the lua stack + procedure Hook(L: Plua_State; Parent: Integer; Func: String); //< pushes hook object/table to the lua stack procedure UnHook(L: Plua_State; hHook: Integer); //< unhook by plugin. push true or error string to lua stack procedure UnHookByParent(Parent: Integer); //< deletes all hooks by a specified parent (unhook by core) @@ -76,7 +78,7 @@ type end; { the default function for THookableEvent.PrepareStack it don't pass any arguments } -function PrepareStack_Dummy: Integer; +function PrepareStack_Dummy(L: PLua_State): Integer; { function in resulting hook table. it calls the unhook command of the event on plugins demand } function LuaHook_UnHook(L: Plua_State): Integer; cdecl; @@ -124,44 +126,50 @@ begin end; { adds hook to events list and pushes hook object/table to the lua stack } -procedure THookableEvent.Hook(L: Plua_State; Parent: Integer; Proc: String); +procedure THookableEvent.Hook(L: PLua_State; Parent: Integer; Func: String); var Item: PHook; + P: TLuaPlugin; begin - // get mem and fill it w/ data - New(Item); - Item.Handle := NextHookHandle; - Inc(NextHookHandle); + P := LuaCore.GetPluginById(Parent); + if (P <> nil) then + begin + // get mem and fill it w/ data + New(Item); + Item.Handle := NextHookHandle; + Inc(NextHookHandle); - Item.Parent := Parent; + Item.Parent := Parent; + Item.Func := Func; - // add at front of the hook chain - Item.Next := LastHook; - LastHook := Item; + // add at front of the hook chain + Item.Next := LastHook; + LastHook := Item; - //we need 2 free stack slots - lua_checkstack(L, 2); + //we need 2 free stack slots + lua_checkstack(L, 2); - //create the hook table, we need 2 elements (event name and unhook function) - lua_createtable(L, 0, 2); + //create the hook table, we need 2 elements (event name and unhook function) + lua_createtable(L, 0, 2); - //push events name - lua_pushstring(L, PAnsiChar(Name)); + //push events name + lua_pushstring(L, PAnsiChar(Name)); - //add the name to the table - lua_setfield(L, -2, 'Event'); + //add the name to the table + lua_setfield(L, -2, 'Event'); - //push hook id to the stack - lua_pushinteger(L, Item.Handle); + //push hook id to the stack + lua_pushinteger(L, Item.Handle); - //create a c closure, append one value from stack(the id) - //this will pop both, the function and the id - lua_pushcclosure(L, LuaHook_UnHook, 1); + //create a c closure, append one value from stack(the id) + //this will pop both, the function and the id + lua_pushcclosure(L, LuaHook_UnHook, 1); - //add the function to our table - lua_setfield(L, -2, 'Unhook'); + //add the function to our table + lua_setfield(L, -2, 'Unhook'); - //the table is left on the stack, it is our result + //the table is left on the stack, it is our result + end; end; { unhook by plugin. push true or error string to lua stack } @@ -231,19 +239,37 @@ begin end; { calls the events hookchain. if breakable, plugin can breake the chain - by returning a value other than 0 or false or nil + by returning a value breakable is pushed as the first parameter to the hooking functions if chain is broken the LuaStack is returned, with all results left you may call lua_clearstack } function THookableEvent.CallHookChain(Breakable: Boolean): Plua_State; var Cur: PHook; + P: TLuaPlugin; begin + Result := nil; + + Cur := LastHook; + While (Cur <> nil) do + begin + P := LuaCore.GetPluginById(Cur.Parent); + lua_pushboolean(P.LuaState, Breakable); + + if (P.CallFunctionByName(Cur.Func, 1 + PrepareStack(P.LuaState), LUA_MULTRET)) + and Breakable + and (lua_gettop(P.LuaState) > 0) then + begin //Chain Broken + Result := P.LuaState; + Break; + end; + Cur := Cur.Next; + end; end; { the default function for THookableEvent.PrepareStack it don't pass any arguments } -function PrepareStack_Dummy: Integer; +function PrepareStack_Dummy(L: PLua_State): Integer; begin Result := 0; end; -- cgit v1.2.3