mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-16 00:05:53 +01:00
128 lines
3.3 KiB
ObjectPascal
128 lines
3.3 KiB
ObjectPascal
|
unit LuaBind.DelphiObjects;
|
||
|
|
||
|
interface
|
||
|
|
||
|
uses
|
||
|
LuaBind.Intf;
|
||
|
|
||
|
function _delphi_call_method(const L: Plua_State): Integer; cdecl;
|
||
|
|
||
|
implementation
|
||
|
|
||
|
uses
|
||
|
System.Rtti,
|
||
|
LuaBind,
|
||
|
System.SysUtils,
|
||
|
System.TypInfo;
|
||
|
|
||
|
function InvokeMethod(Obj: TObject; MethodName: AnsiString; params: TArray<TValue>): TValue;
|
||
|
var
|
||
|
ctx : TRTTIContext;
|
||
|
_type: TRttiType;
|
||
|
_m : TRttiMethod;
|
||
|
_p : TRttiProperty;
|
||
|
_pars: TArray<TRttiParameter>;
|
||
|
par : TRttiParameter;
|
||
|
i : Integer;
|
||
|
begin
|
||
|
ctx := TRTTIContext.Create;
|
||
|
try
|
||
|
_type := ctx.GetType(Obj.ClassInfo);
|
||
|
_m := _type.GetMethod(MethodName);
|
||
|
if _m = nil then
|
||
|
begin
|
||
|
_p := _type.GetProperty(MethodName);
|
||
|
if _p = nil then
|
||
|
raise Exception.CreateFmt('Method or property [%s] not found', [MethodName]);
|
||
|
Result := _p.GetValue(Obj);
|
||
|
end
|
||
|
else
|
||
|
begin
|
||
|
_pars := _m.GetParameters;
|
||
|
i := 0;
|
||
|
for par in _pars do
|
||
|
begin
|
||
|
if par.ParamType.TypeKind in [tkInteger, tkInt64] then
|
||
|
begin
|
||
|
if params[i].Kind in [tkFloat] then
|
||
|
params[i] := Trunc(params[i].AsExtended);
|
||
|
end;
|
||
|
end;
|
||
|
Result := _m.Invoke(Obj, params);
|
||
|
end;
|
||
|
finally
|
||
|
ctx.Free;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
function _delphi_call_method(const L: Plua_State): Integer; cdecl;
|
||
|
var
|
||
|
s : AnsiString;
|
||
|
params : TArray<TValue>;
|
||
|
maxindex : Integer;
|
||
|
i : Integer;
|
||
|
LuaValueType: TLuaValueType;
|
||
|
MethodName : AnsiString;
|
||
|
Obj : TObject;
|
||
|
v : TValue;
|
||
|
begin
|
||
|
Result := 0;
|
||
|
try
|
||
|
Result := lua_gettop(L);
|
||
|
assert(lua_istable(L, 1));
|
||
|
assert(lua_isstring(L, 2) = 1);
|
||
|
|
||
|
methodname := lua_tostring(L, 2);
|
||
|
|
||
|
// assert(lua_islightuserdata(L, - 3));
|
||
|
|
||
|
// lua_getfield(L, - 1, 'maxindex');
|
||
|
// maxindex := lua_tointeger(L, - 1);
|
||
|
lua_pop(L, 1);
|
||
|
if maxindex > - 1 then
|
||
|
begin
|
||
|
SetLength(params, maxindex + 1);
|
||
|
for i := 0 to maxindex do
|
||
|
begin
|
||
|
s := '_' + IntToStr(i);
|
||
|
lua_getfield(L, - 1, PAnsiChar(s));
|
||
|
LuaValueType := TLuaValue.GetLuaValueType(L, - 1);
|
||
|
params[i] := TLuaValue.GetTValueFromLuaValueType(LuaValueType, L, - 1);
|
||
|
lua_pop(L, 1);
|
||
|
end;
|
||
|
end;
|
||
|
lua_pop(L, 1); // pop the table
|
||
|
|
||
|
// read the method name
|
||
|
LuaValueType := TLuaValue.GetLuaValueType(L, - 1);
|
||
|
if LuaValueType <> lvtString then
|
||
|
raise ELuaException.Create('Bad error! Cannot find the method name');
|
||
|
MethodName := TLuaValue.GetTValueFromLuaValueType(LuaValueType, L, - 1).AsString;
|
||
|
lua_pop(L, 1); // remove the methodname
|
||
|
|
||
|
// read the pointer
|
||
|
LuaValueType := TLuaValue.GetLuaValueType(L, - 1);
|
||
|
if LuaValueType <> lvtLightUserData then
|
||
|
raise ELuaException.Create('Bad error! Cannot find the object ref');
|
||
|
Obj := TLuaValue.GetTValueFromLuaValueType(LuaValueType, L, - 1).AsObject;
|
||
|
lua_pop(L, 1); // remove the lightuserdata
|
||
|
|
||
|
v := InvokeMethod(Obj, MethodName, params);
|
||
|
if v.IsEmpty then
|
||
|
Result := 0
|
||
|
else
|
||
|
begin
|
||
|
Result := 1;
|
||
|
TLuaUtils.PushTValue(L, v);
|
||
|
end;
|
||
|
except
|
||
|
on E: Exception do
|
||
|
begin
|
||
|
lua_pushstring(L, PAnsiChar(UTF8Encode(E.ClassName + ' ' + E.Message)));
|
||
|
lua_error(L);
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
end.
|