aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwhiteshark0 <whiteshark0@b956fd51-792f-4845-bead-9b4dfca2ff2c>2009-04-20 12:47:39 +0000
committerwhiteshark0 <whiteshark0@b956fd51-792f-4845-bead-9b4dfca2ff2c>2009-04-20 12:47:39 +0000
commiteab0940bcf7577a9542b474848ee376c581d898c (patch)
treeedd09b7e00a6a8d29db5e9ae9307971d6c4809a5
parent6a44ff7dc1154b6bc5cf9ef250b536c5fc11519e (diff)
downloadusdx-eab0940bcf7577a9542b474848ee376c581d898c.tar.gz
usdx-eab0940bcf7577a9542b474848ee376c581d898c.tar.xz
usdx-eab0940bcf7577a9542b474848ee376c581d898c.zip
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
-rw-r--r--Lua/src/base/UMain.pas4
-rw-r--r--Lua/src/lua/UHookableEvent.pas86
-rw-r--r--Lua/src/lua/ULuaCore.pas7
-rw-r--r--Lua/src/lua/ULuaUsdx.pas65
4 files changed, 122 insertions, 40 deletions
diff --git a/Lua/src/base/UMain.pas b/Lua/src/base/UMain.pas
index e1226c4d..b37d698b 100644
--- a/Lua/src/base/UMain.pas
+++ b/Lua/src/base/UMain.pas
@@ -423,10 +423,8 @@ begin
LuaCore.RegisterModule('Log', ULuaLog_Lib_f);
-
LuaCore.BrowseDir(PluginPath);
- LuaCore.DumpPlugins;
-
+ LuaCore.DumpPlugins;
//------------------------------
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;
diff --git a/Lua/src/lua/ULuaCore.pas b/Lua/src/lua/ULuaCore.pas
index 9f965567..403709dd 100644
--- a/Lua/src/lua/ULuaCore.pas
+++ b/Lua/src/lua/ULuaCore.pas
@@ -655,7 +655,12 @@ begin
lua_checkstack(State, 2);
lua_pushinteger(State, Id);
lua_pushcclosure(State, TLuaPlugin_Register, 1);
- lua_setglobal(State, PChar('register'));
+ lua_setglobal(State, PChar('register'));
+
+ // write plugin id to registry
+ lua_pushinteger(State, iId);
+ lua_setfield (State, LUA_REGISTRYINDEX, '_USDX_STATE_ID');
+ lua_pop(State, Lua_GetTop(State));
// now run the plugin_init function
// plugin_init() if false or nothing is returned plugin init is aborted
diff --git a/Lua/src/lua/ULuaUsdx.pas b/Lua/src/lua/ULuaUsdx.pas
index 558a47cd..4bbb64ea 100644
--- a/Lua/src/lua/ULuaUsdx.pas
+++ b/Lua/src/lua/ULuaUsdx.pas
@@ -37,19 +37,28 @@ uses ULua;
{ some basic lua c functions from usdx table }
-{ usdx.time - returns sdl_time to have time numbers comparable with
- ultrastar delux ones. No Arguments }
+{ Usdx.Time - returns sdl_time to have time numbers comparable with
+ ultrastar delux ones. no arguments }
function ULuaUsdx_Time(L: Plua_State): Integer; cdecl;
-function ULuaUsdx_(L: Plua_State): Integer; cdecl;
+
+{ Usdx.Version - returns Usdx version string (the same that US_Version
+ language-constant does). no arguments }
+function ULuaUsdx_Version(L: Plua_State): Integer; cdecl;
+
+{ Usdx.Hook - returns an hook table with name and Unhook function
+ arguments: event_name: string }
+function ULuaUsdx_Hook(L: Plua_State): Integer; cdecl;
const
- ULuaUsdx_Lib_f: array [0..1] of lual_reg = (
+ ULuaUsdx_Lib_f: array [0..3] of lual_reg = (
+ (name:'Version'; func:ULuaUsdx_Version),
(name:'Time'; func:ULuaUsdx_Time),
+ (name:'Hook'; func:ULuaUsdx_Hook),
(name:nil; func:nil)
);
implementation
-uses SDL;
+uses SDL, ULuaCore, UHookableEvent, UConfig;
function ULuaUsdx_Time(L: Plua_State): Integer; cdecl;
var top: Integer;
@@ -65,9 +74,53 @@ begin
Result := 1; //one result
end;
-function ULuaUsdx_(L: Plua_State): Integer; cdecl;
+{ Usdx.Version - returns Usdx version string (the same that US_Version
+ language-constant does). no arguments }
+function ULuaUsdx_Version(L: Plua_State): Integer; cdecl;
+ var top: Integer;
begin
+ //remove arguments (if any)
+ top := lua_gettop(L);
+
+ If (top > 0) then
+ lua_pop(L, top);
+
+ //push result
+ lua_pushstring(L, PChar(USDXVersionStr()));
+ Result := 1; //one result
+end;
+
+{ Usdx.Hook - returns an hook table with name and Unhook function
+ arguments: event_name: string; function_name: string }
+function ULuaUsdx_Hook(L: Plua_State): Integer; cdecl;
+var
+ EventName: String;
+ FunctionName: String;
+ ParentId: Integer;
+ Event: THookableEvent;
+begin
+ EventName := luaL_checkstring(L, 1);
+ FunctionName := luaL_checkstring(L, 2);
+
+ lua_checkstack(L, 1);
+
+ lua_getfield (L, LUA_REGISTRYINDEX, '_USDX_STATE_ID');
+ if (not lua_isNumber(L, -1)) then
+ luaL_error(L, 'unable to get _USDX_STATE_ID in ULuaUsdx_Hook');
+
+ ParentId := lua_toInteger(L, -1);
+
+ lua_pop(L, lua_gettop(L)); //clear stack
+
+ Result := 1;
+ Event := LuaCore.GetEventByName(EventName);
+ if (Event <> nil) then
+ begin
+ Event.Hook(L, ParentId, FunctionName);
+ end
+ else
+ luaL_error(L, PChar('event does not exist: ' + EventName));
end;
end. \ No newline at end of file