mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 21:49:15 +02:00
* Patch from Michal Gawrycki to implement streaming interface properties (IComponent) Bug ID
git-svn-id: trunk@35474 -
This commit is contained in:
parent
b9dba41ad0
commit
cc81abdd83
@ -722,7 +722,10 @@ begin
|
|||||||
FOnReferenceName(Self,Ref);
|
FOnReferenceName(Self,Ref);
|
||||||
C:=FindNestedComponent(R.FRoot,Ref);
|
C:=FindNestedComponent(R.FRoot,Ref);
|
||||||
If Assigned(C) then
|
If Assigned(C) then
|
||||||
SetObjectProp(R.FInstance,R.FPropInfo,C)
|
if R.FPropInfo^.PropType^.Kind = tkInterface then
|
||||||
|
SetInterfaceProp(R.FInstance,R.FPropInfo,C)
|
||||||
|
else
|
||||||
|
SetObjectProp(R.FInstance,R.FPropInfo,C)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
P:=Pos('.',R.FRelative);
|
P:=Pos('.',R.FRelative);
|
||||||
@ -1256,6 +1259,8 @@ begin
|
|||||||
|
|
||||||
if PropInfo^.PropType^.Kind = tkClass then
|
if PropInfo^.PropType^.Kind = tkClass then
|
||||||
Obj := TObject(GetObjectProp(Instance, PropInfo))
|
Obj := TObject(GetObjectProp(Instance, PropInfo))
|
||||||
|
//else if PropInfo^.PropType^.Kind = tkInterface then
|
||||||
|
// Obj := TObject(GetInterfaceProp(Instance, PropInfo))
|
||||||
else
|
else
|
||||||
Obj := nil;
|
Obj := nil;
|
||||||
|
|
||||||
@ -1385,7 +1390,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
SetVariantProp(Instance,PropInfo,ReadVariant);
|
SetVariantProp(Instance,PropInfo,ReadVariant);
|
||||||
end;
|
end;
|
||||||
tkClass:
|
tkClass, tkInterface:
|
||||||
case FDriver.NextValue of
|
case FDriver.NextValue of
|
||||||
vaNil:
|
vaNil:
|
||||||
begin
|
begin
|
||||||
|
@ -874,6 +874,8 @@ var
|
|||||||
VarValue, DefVarValue : tvardata;
|
VarValue, DefVarValue : tvardata;
|
||||||
BoolValue, DefBoolValue: boolean;
|
BoolValue, DefBoolValue: boolean;
|
||||||
Handled: Boolean;
|
Handled: Boolean;
|
||||||
|
IntfValue: IInterface;
|
||||||
|
CompRef: IInterfaceComponentReference;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
// do not stream properties without getter
|
// do not stream properties without getter
|
||||||
@ -1181,6 +1183,79 @@ begin
|
|||||||
Driver.EndProperty;
|
Driver.EndProperty;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
tkInterface:
|
||||||
|
begin
|
||||||
|
IntfValue := GetInterfaceProp(Instance, PropInfo);
|
||||||
|
if Assigned(IntfValue) and Supports(IntfValue, IInterfaceComponentReference, CompRef) then
|
||||||
|
begin
|
||||||
|
Component := CompRef.GetComponent;
|
||||||
|
if HasAncestor then
|
||||||
|
begin
|
||||||
|
AncestorObj := TObject(GetObjectProp(Ancestor, PropInfo));
|
||||||
|
if (AncestorObj is TComponent) then
|
||||||
|
begin
|
||||||
|
//writeln('TWriter.WriteProperty AncestorObj=',TComponent(AncestorObj).Name,' OwnerFit=',TComponent(AncestorObj).Owner = FRootAncestor,' ',TComponent(ObjValue).Name,' OwnerFit=',TComponent(ObjValue).Owner = Root);
|
||||||
|
if (AncestorObj<> Component) and
|
||||||
|
(TComponent(AncestorObj).Owner = FRootAncestor) and
|
||||||
|
(Component.Owner = Root) and
|
||||||
|
(UpperCase(TComponent(AncestorObj).Name) = UpperCase(Component.Name)) then
|
||||||
|
begin
|
||||||
|
// different components, but with the same name
|
||||||
|
// treat it like an override
|
||||||
|
AncestorObj := Component;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end else
|
||||||
|
AncestorObj := nil;
|
||||||
|
|
||||||
|
if not Assigned(Component) then
|
||||||
|
begin
|
||||||
|
if Component <> AncestorObj then
|
||||||
|
begin
|
||||||
|
Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name);
|
||||||
|
Driver.WriteIdent('NIL');
|
||||||
|
Driver.EndProperty;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else if ((not (csSubComponent in Component.ComponentStyle))
|
||||||
|
or ((Component.Owner<>Instance) and (Component.Owner<>Nil))) then
|
||||||
|
begin
|
||||||
|
if (Component <> AncestorObj)
|
||||||
|
and not (csTransient in Component.ComponentStyle) then
|
||||||
|
begin
|
||||||
|
Name:= '';
|
||||||
|
C:= Component;
|
||||||
|
While (C<>Nil) and (C.Name<>'') do
|
||||||
|
begin
|
||||||
|
If (Name<>'') Then
|
||||||
|
Name:='.'+Name;
|
||||||
|
if C.Owner = LookupRoot then
|
||||||
|
begin
|
||||||
|
Name := C.Name+Name;
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
else if C = LookupRoot then
|
||||||
|
begin
|
||||||
|
Name := 'Owner' + Name;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
Name:=C.Name + Name;
|
||||||
|
C:= C.Owner;
|
||||||
|
end;
|
||||||
|
if (C=nil) and (Component.Owner=nil) then
|
||||||
|
if (Name<>'') then //foreign root
|
||||||
|
Name:=Name+'.Owner';
|
||||||
|
if Length(Name) > 0 then
|
||||||
|
begin
|
||||||
|
Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name);
|
||||||
|
WriteIdent(Name);
|
||||||
|
Driver.EndProperty;
|
||||||
|
end; // length Name>0
|
||||||
|
end; //(Component <> AncestorObj)
|
||||||
|
end;
|
||||||
|
end; //Assigned(IntfValue) and Supports(IntfValue,..
|
||||||
|
//else write NIL ?
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ TTestComponentStream = Class(TTestStreaming)
|
|||||||
Procedure TestTStreamedOwnedComponents;
|
Procedure TestTStreamedOwnedComponents;
|
||||||
Procedure TestTMethodComponent;
|
Procedure TestTMethodComponent;
|
||||||
Procedure TestTMethodComponent2;
|
Procedure TestTMethodComponent2;
|
||||||
|
Procedure TestTOwnedInterface;
|
||||||
end;
|
end;
|
||||||
{ TMyItem }
|
{ TMyItem }
|
||||||
|
|
||||||
@ -1229,6 +1230,28 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Procedure TTestComponentStream.TestTOwnedInterface;
|
||||||
|
|
||||||
|
Var
|
||||||
|
C : TComponent;
|
||||||
|
|
||||||
|
begin
|
||||||
|
C:=TOwnedInterface.Create(Nil);
|
||||||
|
Try
|
||||||
|
SaveToStream(C);
|
||||||
|
ExpectSignature;
|
||||||
|
ExpectFlags([],0);
|
||||||
|
ExpectBareString('TOwnedInterface');
|
||||||
|
ExpectBareString('TestTOwnedInterface');
|
||||||
|
ExpectBareString('IntfProp');
|
||||||
|
ExpectIdent('InterfacedComponent');
|
||||||
|
ExpectEndOfList;
|
||||||
|
ExpectEndOfList;
|
||||||
|
Finally
|
||||||
|
C.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TMyColl }
|
{ TMyColl }
|
||||||
|
|
||||||
function TMyColl.GetIt(index : Integer): TMyItem;
|
function TMyColl.GetIt(index : Integer): TMyItem;
|
||||||
|
@ -491,6 +491,26 @@ Type
|
|||||||
Procedure MyMethod2;
|
Procedure MyMethod2;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Interface as published property
|
||||||
|
|
||||||
|
ITestInterface = interface
|
||||||
|
end;
|
||||||
|
|
||||||
|
TTestIntfComponent = class(TComponent, ITestInterface)
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TOwnedInterface }
|
||||||
|
|
||||||
|
TOwnedInterface = class(TComponent)
|
||||||
|
Private
|
||||||
|
F : ITestInterface;
|
||||||
|
Public
|
||||||
|
Constructor Create(AOwner : TComponent); override;
|
||||||
|
Destructor Destroy; override;
|
||||||
|
Published
|
||||||
|
Property IntfProp: ITestInterface Read F Write F;
|
||||||
|
end;
|
||||||
|
|
||||||
Implementation
|
Implementation
|
||||||
|
|
||||||
procedure TChildrenComponent.GetChildren(Proc: TGetChildProc; Root: TComponent);
|
procedure TChildrenComponent.GetChildren(Proc: TGetChildProc; Root: TComponent);
|
||||||
@ -950,5 +970,22 @@ begin
|
|||||||
// Do nothng
|
// Do nothng
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TOwnedInterface }
|
||||||
|
|
||||||
|
constructor TOwnedInterface.Create(AOwner: TComponent);
|
||||||
|
var
|
||||||
|
C : TTestIntfComponent;
|
||||||
|
begin
|
||||||
|
inherited Create(AOwner);
|
||||||
|
C := TTestIntfComponent.Create(Self);
|
||||||
|
C.Name:='InterfacedComponent';
|
||||||
|
IntfProp:=C;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Destructor TOwnedInterface.Destroy;
|
||||||
|
begin
|
||||||
|
F := nil; // prevent memory leak
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user