@@ -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;
15501550function TExposedEvent.GetterWrapper (AObj: PPyObject; AContext : Pointer): PPyObject;
15511551var
15521552 Obj: TObject;
1553- PyObject: TPyDelphiObject;
15541553 RttiProp: TRttiInstanceProperty;
15551554 LOutMsg: string;
1556- EventHandler: TRttiEventHandler;
1557- Index: Integer;
15581555begin
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;
15791561end ;
15801562
15811563function TExposedEvent.SetterWrapper (AObj, AValue: PPyObject; AContext: Pointer): Integer;
15821564var
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;
17921761end ;
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);
17971767begin
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);
18041771end ;
18051772
18061773destructor TRttiEventHandler.Destroy;
18071774begin
1808- DelphiWrapper.Engine.Py_XDECREF(PyCallable);
18091775 FMethodImplementation.Free;
1776+ inherited ;
18101777end ;
18111778
18121779function 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;
29512918destructor TPyDelphiObject.Destroy;
29522919begin
29532920 DelphiObject := nil ; // will free the object if owned
2954- fEventHandlers.Free;
29552921 fContainerAccess.Free;
29562922 inherited ;
29572923end ;
@@ -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);
48364801var
48374802 _FreeNotification : IFreeNotification;
@@ -4851,7 +4816,7 @@ constructor TEventHandler.Create(PyDelphiWrapper : TPyDelphiWrapper;
48514816 (Component as TComponent).FreeNotification(PyDelphiWrapper);
48524817end ;
48534818
4854- destructor TEventHandler .Destroy;
4819+ destructor TBaseEventHandler .Destroy;
48554820var
48564821 Method : TMethod;
48574822begin
@@ -4874,7 +4839,7 @@ destructor TEventHandler.Destroy;
48744839 inherited ;
48754840end ;
48764841
4877- procedure TEventHandler .Unsubscribe ;
4842+ procedure TBaseEventHandler .Unsubscribe ;
48784843var
48794844 _FreeNotification : IFreeNotification;
48804845begin
@@ -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;
49114876begin
49124877 fItems.Add(AEventHandler);
49134878 Result := True;
@@ -4983,9 +4948,9 @@ function TEventHandlers.GetCount: Integer;
49834948 Result := fItems.Count;
49844949end ;
49854950
4986- function TEventHandlers.GetItem (AIndex: Integer): TEventHandler ;
4951+ function TEventHandlers.GetItem (AIndex: Integer): TBaseEventHandler ;
49874952begin
4988- Result := TEventHandler (fItems[AIndex]);
4953+ Result := TBaseEventHandler (fItems[AIndex]);
49894954end ;
49904955
49914956function TEventHandlers.GetRegisteredClass (
0 commit comments