среда, 8 апреля 2015 г.

Briefly. Weak reference to interface

Original in Russian: http://programmingmindstream.blogspot.ru/2015/04/blog-post_3.html

In some cases we have to keep WEAK references to interfaces (without reference counting).

The analogue of attribute [Weak].

For example, for publisher/subscriber.

"It defines the one-to-many relationships between the objects so that on changing the state of one object all the objects related to it are reported about it."

Here's the solution:

type
 TmsWeakInterfaceRef<t> = record
 // Weak reference to interfece
  rShape : Pointer;
  constructor Create(const aShape: T);
  function AsShape: ImsShape;
  class operator Equal(const A: TmsWeakInterfaceRef<t>; const B: TmsWeakInterfaceRef<t>): Boolean;
  class operator Equal(const A: TmsWeakInterfaceRef<t>; const B: T): Boolean;
  class operator Implicit(const aShape: T): TmsWeakInterfaceRef<t>;
 end;//TmsWeakInterfaceRef
 
 TmsWeakShapeRef = TmsWeakInterfaceRef<imsshape>;
...
// TmsWeakInterfaceRef<t>
 
constructor TmsWeakInterfaceRef<t>.Create(const aShape: T);
begin
 Assert(SizeOf(T) = SizeOf(IUnknown));
 Move(aShape, Self.rShape, SizeOf(T));
end;
 
function TmsWeakInterfaceRef<t>.AsShape: ImsShape;
begin
 Result := ImsShape(Self.rShape);
end;
 
class operator TmsWeakInterfaceRef<t>.Equal(const A: TmsWeakInterfaceRef<t>; const B: TmsWeakInterfaceRef<t>): Boolean;
begin
 Result := (A.rShape = B.rShape);
end;
 
class operator TmsWeakInterfaceRef<t>.Equal(const A: TmsWeakInterfaceRef<t>; const B: T): Boolean;
var
 l_P : Pointer;
begin
 Assert(SizeOf(T) = SizeOf(Pointer));
 Move(B, l_P, SizeOf(T));
 Result := (A.rShape = l_P);
end;
 
class operator TmsWeakInterfaceRef<t>.Implicit(const aShape: T): TmsWeakInterfaceRef<t>;
begin
 Result := TmsWeakInterfaceRef<t>.Create(aShape);
end;

Link to the commit - https://bitbucket.org/lulinalex/mindstream/commits/825ca7487905ce786aa9f44b6a0d95e570b06b71

Another commit - https://bitbucket.org/lulinalex/mindstream/commits/861e56e0bff2613b652d633f0183c93fde75601e

The final version:
type
 TmsWeakInterfaceRef<T: IUnknown> = record
 // Weak reference to interface
  rRef : Pointer;
  constructor Create(const aShape: T);
  function AsRef: T; inline;
  class operator Equal(const A: TmsWeakInterfaceRef<t>; const B: TmsWeakInterfaceRef<t>): Boolean;
  class operator Equal(const A: TmsWeakInterfaceRef<t>; const B: T): Boolean;
  class operator Implicit(const aShape: T): TmsWeakInterfaceRef<t>;
  class operator Implicit(const aValue: TmsWeakInterfaceRef<t>): T; inline;
 end;//TmsWeakInterfaceRef
 
 TmsWeakShapeRef = TmsWeakInterfaceRef<imsshape>
...
// TmsWeakInterfaceRef<t>
 
constructor TmsWeakInterfaceRef<t>.Create(const aShape: T);
begin
 Assert(SizeOf(T) = SizeOf(IUnknown));
 Move(aShape, Self.rRef, SizeOf(T));
end;
 
function TmsWeakInterfaceRef<t>.AsRef: T;
begin
 Result := nil;
 Assert(SizeOf(T) = SizeOf(Result));
 Move(Self.rRef, Result, SizeOf(T));
 Result._AddRef;
end;
 
class operator TmsWeakInterfaceRef<t>.Implicit(const aValue: TmsWeakInterfaceRef<t>): T;
begin
 Result := aValue.AsRef;
end;
 
class operator TmsWeakInterfaceRef<t>.Equal(const A: TmsWeakInterfaceRef<t>; const B: TmsWeakInterfaceRef<t>): Boolean;
begin
 Result := (A.rRef = B.rRef);
end;
 
class operator TmsWeakInterfaceRef<t>.Equal(const A: TmsWeakInterfaceRef<t>; const B: T): Boolean;
var
 l_P : Pointer;
begin
 Assert(SizeOf(T) = SizeOf(Pointer));
 Move(B, l_P, SizeOf(T));
 Result := (A.rRef = l_P);
end;
 
class operator TmsWeakInterfaceRef<t>.Implicit(const aShape: T): TmsWeakInterfaceRef<t>;
begin
 Result := TmsWeakInterfaceRef<t>.Create(aShape);
end;


Хорошая подборка кстати:
https://www.google.com/search?q=Weak+reference+to+interface&oq=Weak+reference+to+interface&aqs=chrome..69i57j69i60l2.13918j0j7&sourceid=chrome&es_sm=122&ie=UTF-8

(+) Weak interface references

Комментариев нет:

Отправить комментарий