Skip to content

Commit ad0ac33

Browse files
committed
Unify TEventHandler and TRttiEventHandler.
1 parent 9830872 commit ad0ac33

1 file changed

Lines changed: 39 additions & 74 deletions

File tree

Source/WrapDelphi.pas

Lines changed: 39 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,6 @@ TPyDelphiObject = class (TPyInterfacedObject, IFreeNotificationSubscriber)
527527
private
528528
fDelphiObject: TObject;
529529
fContainerAccess: TContainerAccess;
530-
fEventHandlers: TObjectList;
531530
function GetContainerAccess: TContainerAccess;
532531
procedure SetDelphiObject(const Value: TObject);
533532
protected
@@ -715,7 +714,7 @@ TPyPascalInterface = class(TPyRttiObject)
715714
end;
716715
{$ENDIF}
717716

718-
TEventHandler = class
717+
TBaseEventHandler = class
719718
private
720719
fComponent: TObject;
721720
public
@@ -729,11 +728,15 @@ TEventHandler = class
729728
destructor Destroy; override;
730729
// Disconnects from the free notification event now
731730
procedure Unsubscribe;
732-
// returns the type info of the supported event
733-
class function GetTypeInfo : PTypeInfo; virtual; abstract;
734731
// properties
735732
property Component : TObject read fComponent;
736733
end;
734+
735+
TEventHandler = class(TBaseEventHandler)
736+
public
737+
// returns the type info of the supported event
738+
class function GetTypeInfo : PTypeInfo; virtual; abstract;
739+
end;
737740
TEventHandlerClass = class of TEventHandler;
738741

739742
TEventHandlers = class
@@ -742,7 +745,7 @@ TEventHandlers = class
742745
fRegisteredClasses : TClassList;
743746
fPyDelphiWrapper: TPyDelphiWrapper;
744747
function GetCount: Integer;
745-
function GetItem(AIndex: Integer): TEventHandler;
748+
function GetItem(AIndex: Integer): TBaseEventHandler;
746749
function GetRegisteredClass(AIndex: Integer): TEventHandlerClass;
747750
function GetRegisteredClassCount: Integer;
748751
protected
@@ -753,7 +756,7 @@ TEventHandlers = class
753756
constructor Create(APyDelphiWrapper : TPyDelphiWrapper);
754757
destructor Destroy; override;
755758

756-
function Add(AEventHandler : TEventHandler) : Boolean;
759+
function Add(AEventHandler : TBaseEventHandler) : Boolean;
757760
procedure Clear;
758761
procedure Delete(AIndex : Integer);
759762
function GetCallable(AComponent : TObject; APropInfo : PPropInfo) : PPyObject; overload;
@@ -765,7 +768,7 @@ TEventHandlers = class
765768
function Unlink(AComponent : TObject; APropInfo : PPropInfo) : Boolean;
766769

767770
property Count : Integer read GetCount;
768-
property Items[AIndex : Integer] : TEventHandler read GetItem; default;
771+
property Items[AIndex : Integer] : TBaseEventHandler read GetItem; default;
769772
property PyDelphiWrapper : TPyDelphiWrapper read fPyDelphiWrapper;
770773
end;
771774

@@ -1293,18 +1296,15 @@ TExposedIndexedProperty = class(TAbstractExposedMember)
12931296
property GetterCallback: Pointer read GetGetterCallback;
12941297
end;
12951298

1296-
TRttiEventHandler = class
1299+
TRttiEventHandler = class(TBaseEventHandler)
12971300
private
12981301
FMethodImplementation: TMethodImplementation;
12991302
public
1300-
DelphiWrapper: TPyDelphiWrapper;
1301-
PropInfo: PPropInfo;
13021303
MethodType: TRttiMethodType;
1303-
PyCallable: PPyObject;
13041304
function CodeAddress: Pointer;
1305-
constructor Create(ADelphiWrapper : TPyDelphiWrapper;
1306-
APropertyInfo: PPropInfo; ACallable: PPyObject;
1307-
AMethodType: TRttiMethodType);
1305+
constructor Create(PyDelphiWrapper: TPyDelphiWrapper; Component: TObject;
1306+
PropertyInfo: PPropInfo; Callable: PPyObject;
1307+
AMethodType: TRttiMethodType); reintroduce;
13081308
destructor Destroy; override;
13091309
class procedure ImplCallback(UserData: Pointer; const Args: TArray<TValue>;
13101310
out Result: TValue); static;
@@ -1550,38 +1550,19 @@ function TExposedEvent.GetDefaultDocString(): string;
15501550
function TExposedEvent.GetterWrapper(AObj: PPyObject; AContext : Pointer): PPyObject;
15511551
var
15521552
Obj: TObject;
1553-
PyObject: TPyDelphiObject;
15541553
RttiProp: TRttiInstanceProperty;
15551554
LOutMsg: string;
1556-
EventHandler: TRttiEventHandler;
1557-
Index: Integer;
15581555
begin
1559-
Result := nil;
1556+
RttiProp := FRttiMember as TRttiInstanceProperty;
15601557
if ValidateClassProperty(AObj, FParentRtti.Handle, Obj, LOutMsg) then
1561-
begin
1562-
PyObject := PythonToDelphi(AObj) as TPyDelphiObject;
1563-
RttiProp := FRttiMember as TRttiInstanceProperty;
1564-
// Search for and Event handler
1565-
if Assigned(PyObject.fEventHandlers) then
1566-
for Index := 0 to PyObject.fEventHandlers.Count - 1 do
1567-
begin
1568-
EventHandler := PyObject.fEventHandlers[Index] as TRttiEventHandler;
1569-
if EventHandler.PropInfo = RttiProp.PropInfo then
1570-
begin
1571-
Result := EventHandler.PyCallable;
1572-
FPyDelphiWrapper.Engine.Py_XINCREF(Result);
1573-
end;
1574-
end;
1575-
end;
1576-
1577-
if not Assigned(Result) then
1558+
Result := FPyDelphiWrapper.EventHandlers.GetCallable(Obj, RttiProp.PropInfo)
1559+
else
15781560
Result := FPyDelphiWrapper.Engine.ReturnNone;
15791561
end;
15801562

15811563
function TExposedEvent.SetterWrapper(AObj, AValue: PPyObject; AContext: Pointer): Integer;
15821564
var
15831565
Obj: TObject;
1584-
PyObject: TPyDelphiObject;
15851566
RttiProp: TRttiInstanceProperty;
15861567
ErrMsg: string;
15871568
EventHandler: TRttiEventHandler;
@@ -1595,20 +1576,10 @@ function TExposedEvent.SetterWrapper(AObj, AValue: PPyObject; AContext: Pointer)
15951576
if ValidateClassProperty(AObj, FParentRtti.Handle, Obj, ErrMsg) then
15961577
begin
15971578
try
1598-
PyObject := PythonToDelphi(AObj) as TPyDelphiObject;
15991579
RttiProp := FRttiMember as TRttiInstanceProperty;
16001580

16011581
// Remove handler if it exists
1602-
if Assigned(PyObject.fEventHandlers) then
1603-
for Index := 0 to PyObject.fEventHandlers.Count - 1 do
1604-
begin
1605-
EventHandler := PyObject.fEventHandlers[Index] as TRttiEventHandler;
1606-
if EventHandler.PropInfo = RttiProp.PropInfo then
1607-
begin
1608-
PyObject.fEventHandlers.Delete(Index);
1609-
break;
1610-
end;
1611-
end;
1582+
fPyDelphiWrapper.EventHandlers.Unlink(Obj, RttiProp.PropInfo);
16121583

16131584
if AValue = GetPythonEngine.Py_None then
16141585
begin
@@ -1617,12 +1588,10 @@ function TExposedEvent.SetterWrapper(AObj, AValue: PPyObject; AContext: Pointer)
16171588
end
16181589
else
16191590
begin
1620-
EventHandler := TRttiEventHandler.Create(FPyDelphiWrapper,
1591+
EventHandler := TRttiEventHandler.Create(FPyDelphiWrapper, Obj,
16211592
RttiProp.PropInfo, AValue, RttiProp.PropertyType as TRttiMethodType);
16221593

1623-
if not Assigned(PyObject.fEventHandlers) then
1624-
PyObject.fEventHandlers := TObjectList.Create(True);
1625-
PyObject.fEventHandlers.Add(EventHandler);
1594+
FPyDelphiWrapper.EventHandlers.Add(EventHandler);
16261595

16271596
Method.Code := EventHandler.CodeAddress;
16281597
Method.Data := EventHandler;
@@ -1792,21 +1761,19 @@ function TPyIndexedProperty.MpAssSubscript(obj1, obj2: PPyObject) : Integer;
17921761
end;
17931762

17941763
{ TRttiEventHandler }
1795-
constructor TRttiEventHandler.Create(ADelphiWrapper : TPyDelphiWrapper;
1796-
APropertyInfo: PPropInfo; ACallable: PPyObject; AMethodType: TRttiMethodType);
1764+
constructor TRttiEventHandler.Create(PyDelphiWrapper: TPyDelphiWrapper;
1765+
Component: TObject; PropertyInfo: PPropInfo; Callable: PPyObject;
1766+
AMethodType: TRttiMethodType);
17971767
begin
1798-
PropInfo := APropertyInfo;
1799-
DelphiWrapper := ADelphiWrapper;
1800-
PyCallable := ACallable;
1801-
GetPythonEngine.Py_INCREF(PyCallable);
1768+
inherited Create(PyDelphiWrapper, Component, PropertyInfo, Callable);
18021769
MethodType := AMethodType;
18031770
FMethodImplementation := AMethodType.CreateImplementation(nil, ImplCallback);
18041771
end;
18051772

18061773
destructor TRttiEventHandler.Destroy;
18071774
begin
1808-
DelphiWrapper.Engine.Py_XDECREF(PyCallable);
18091775
FMethodImplementation.Free;
1776+
inherited;
18101777
end;
18111778

18121779
function TRttiEventHandler.CodeAddress: Pointer;
@@ -1834,32 +1801,32 @@ class procedure TRttiEventHandler.ImplCallback(UserData: Pointer;
18341801

18351802
if Length(Args) <> Length(Params) + 1 then // +1 for Self
18361803
begin
1837-
InvalidArguments(string(EventHandler.PropInfo.Name), rs_IncompatibleArguments);
1804+
InvalidArguments(string(EventHandler.PropertyInfo.Name), rs_IncompatibleArguments);
18381805
Exit;
18391806
end;
18401807

1841-
Engine := EventHandler.DelphiWrapper.Engine;
1808+
Engine := EventHandler.PyDelphiWrapper.Engine;
18421809

18431810
// Set up the python arguments
18441811
PyArgs := Engine.PyTuple_New(Length(Args) - 1); //Ignore Self
18451812
try
18461813
for Index := 1 to Length(Args) - 1 do
18471814
begin
18481815
if Params[Index - 1].Flags * [TParamFlag.pfVar, TParamFlag.pfOut] <> [] then
1849-
TempPy := CreateVarParam(EventHandler.DelphiWrapper, Args[Index])
1816+
TempPy := CreateVarParam(EventHandler.PyDelphiWrapper, Args[Index])
18501817
else
1851-
TempPy := TValueToPyObject(Args[Index], EventHandler.DelphiWrapper, ErrMsg);
1818+
TempPy := TValueToPyObject(Args[Index], EventHandler.PyDelphiWrapper, ErrMsg);
18521819
if TempPy <> nil then
18531820
Engine.PyTuple_SetItem(PyArgs, Index - 1, TempPy)
18541821
else
18551822
begin
1856-
InvalidArguments(string(EventHandler.PropInfo.Name), rs_IncompatibleArguments);
1823+
InvalidArguments(string(EventHandler.PropertyInfo.Name), rs_IncompatibleArguments);
18571824
Engine.CheckError; // will raise an Exception
18581825
end;
18591826
end;
18601827

18611828
// Make the call
1862-
PyResult := Engine.PyObject_CallObject(EventHandler.PyCallable, PyArgs);
1829+
PyResult := Engine.PyObject_CallObject(EventHandler.Callable, PyArgs);
18631830

18641831
// deal with var/out parameters
18651832
for Index := 1 to Length(Args) - 1 do
@@ -1870,7 +1837,7 @@ class procedure TRttiEventHandler.ImplCallback(UserData: Pointer;
18701837
if not PyObjectToTValue((PythonToDelphi(TempPy) as TPyDelphiVarParameter).Value,
18711838
Params[Index- 1].ParamType, Args[Index], ErrMsg) then
18721839
begin
1873-
InvalidArguments(string(EventHandler.PropInfo.Name), rs_IncompatibleArguments);
1840+
InvalidArguments(string(EventHandler.PropertyInfo.Name), rs_IncompatibleArguments);
18741841
Engine.CheckError; // will raise an Exception
18751842
end;
18761843
end;
@@ -1879,7 +1846,7 @@ class procedure TRttiEventHandler.ImplCallback(UserData: Pointer;
18791846
not PyObjectToTValue(PyResult, EventHandler.MethodType.ReturnType, Result, ErrMsg)
18801847
then
18811848
Engine.PyErr_SetObject(Engine.PyExc_TypeError^, Engine.PyUnicodeFromString(
1882-
Format(rs_ErrInvalidRet, [string(EventHandler.PropInfo.Name), ErrMsg])));
1849+
Format(rs_ErrInvalidRet, [string(EventHandler.PropertyInfo.Name), ErrMsg])));
18831850
Engine.Py_XDECREF(PyResult);
18841851
finally
18851852
Engine.Py_XDECREF(PyArgs);
@@ -2951,7 +2918,6 @@ class function TPyDelphiObject.DelphiObjectClass: TClass;
29512918
destructor TPyDelphiObject.Destroy;
29522919
begin
29532920
DelphiObject := nil; // will free the object if owned
2954-
fEventHandlers.Free;
29552921
fContainerAccess.Free;
29562922
inherited;
29572923
end;
@@ -3949,7 +3915,6 @@ procedure TPyDelphiObject.SetDelphiObject(const Value: TObject);
39493915
if Assigned(fDelphiObject)then
39503916
begin
39513917
UnSubscribeToFreeNotification;
3952-
FreeAndNil(fEventHandlers);
39533918
if Owned then
39543919
fDelphiObject.Free;
39553920
end;
@@ -4831,7 +4796,7 @@ function TPyDelphiVarParameter.Set_Value(AValue: PPyObject;
48314796

48324797
{ TEventHandler }
48334798

4834-
constructor TEventHandler.Create(PyDelphiWrapper : TPyDelphiWrapper;
4799+
constructor TBaseEventHandler.Create(PyDelphiWrapper : TPyDelphiWrapper;
48354800
Component: TObject; PropertyInfo: PPropInfo; Callable: PPyObject);
48364801
var
48374802
_FreeNotification : IFreeNotification;
@@ -4851,7 +4816,7 @@ constructor TEventHandler.Create(PyDelphiWrapper : TPyDelphiWrapper;
48514816
(Component as TComponent).FreeNotification(PyDelphiWrapper);
48524817
end;
48534818

4854-
destructor TEventHandler.Destroy;
4819+
destructor TBaseEventHandler.Destroy;
48554820
var
48564821
Method : TMethod;
48574822
begin
@@ -4874,7 +4839,7 @@ destructor TEventHandler.Destroy;
48744839
inherited;
48754840
end;
48764841

4877-
procedure TEventHandler.Unsubscribe;
4842+
procedure TBaseEventHandler.Unsubscribe;
48784843
var
48794844
_FreeNotification : IFreeNotification;
48804845
begin
@@ -4907,7 +4872,7 @@ class function TNotifyEventHandler.GetTypeInfo: PTypeInfo;
49074872

49084873
{ TEventHandlers }
49094874

4910-
function TEventHandlers.Add(AEventHandler: TEventHandler) : Boolean;
4875+
function TEventHandlers.Add(AEventHandler: TBaseEventHandler) : Boolean;
49114876
begin
49124877
fItems.Add(AEventHandler);
49134878
Result := True;
@@ -4983,9 +4948,9 @@ function TEventHandlers.GetCount: Integer;
49834948
Result := fItems.Count;
49844949
end;
49854950

4986-
function TEventHandlers.GetItem(AIndex: Integer): TEventHandler;
4951+
function TEventHandlers.GetItem(AIndex: Integer): TBaseEventHandler;
49874952
begin
4988-
Result := TEventHandler(fItems[AIndex]);
4953+
Result := TBaseEventHandler(fItems[AIndex]);
49894954
end;
49904955

49914956
function TEventHandlers.GetRegisteredClass(

0 commit comments

Comments
 (0)