On Wed, 28 Nov 2012, luiz americo pereira camara wrote:

2012/11/28 Graeme Geldenhuys <gra...@geldenhuys.co.uk>:
On 2012-11-27 16:19, Michael Van Canneyt wrote:


If you haven't made other changes to those LCL Mediators since the code
you emailed me, I could take a look at updating the code for Lazarus too.

That's a perfect example of the FPC Observers support being fully
functional as-is.


I don't discuss being fully functional as is. But you must agree that,
if an architeture works in a scenario does not mean it's good or at
least could not be improved.

Correct. But the design should also not try to cover all possible use cases at any cost.

Till now, I have not seen a common use case that will not work.

I just proposed a change that will give more flexibility for the
programmer when designing his application interface. As a plus with
less typecasts, so less overhead.

If we assume for a second that the internal change to store the interface instead of the instance is done:

There are not less typecasts executed, they are in a different place simply.
You must always type the typecast before calling AttachObserver, I do it inside AttachObserver. My code is therefore simpler to read, generates less code and hence is preferable.

I'm not speaking idly about less code generated. Interfaces generate
some overhead. COM interfaces generate even quite some overhead.

Compare this (not meant to be runnable):

-----------------------------------------------------------------------
{$mode objfpc}
uses classes;

Procedure DoI(I : IInterface);

begin
  I._addref;
end;

Var
  C : TComponent;

begin
  DoI(C as IInterface);
end.
-----------------------------------------------------------------------

With this:

-----------------------------------------------------------------------
{$mode objfpc}
uses classes;

Procedure DoI(C : TComponent);

begin
  (C as IInterface)._addref;
end;

Var
  C : TComponent;

begin
  DoI(C);
end.
-----------------------------------------------------------------------

The latter (no interface passed on) generates the following assembler for the main program:

        movq    U_$P$PROGRAM_$$_C,%rdi
        call    P$PROGRAM_$$_DOI$TCOMPONENT

The former (pass an interface) generates for the main program the following 
assembler:

        movq    $0,-104(%rbp)
        leaq    -24(%rbp),%rdx
        leaq    -88(%rbp),%rsi
        movq    $1,%rdi
        call    FPC_PUSHEXCEPTADDR
        movq    %rax,%rdi
        call    FPC_SETJMP
        movq    %rax,-96(%rbp)
        testl   %eax,%eax
        jne     .Lj10
        movq    _$PROGRAM$_Ld1,%rdx
        movq    _$PROGRAM$_Ld1+8,%rcx
        movq    U_$P$PROGRAM_$$_C,%rsi
        leaq    -104(%rbp),%rdi
        call    fpc_class_as_intf
        movq    -104(%rbp),%rdi
        call    P$PROGRAM_$$_DOI$IUNKNOWN
.Lj10:
        call    FPC_POPADDRSTACK
        leaq    -104(%rbp),%rdi
        call    fpc_intf_decr_ref
        movq    -96(%rbp),%rax
        testq   %rax,%rax
        je      .Lj11
        call    FPC_RERAISE
.Lj11:

If you use corba interfaces, then the interface version of the main program is 
reduced to

        movq    $_$PROGRAM$_Ld1,%rsi
        movq    U_$P$PROGRAM_$$_C,%rdi
        call    fpc_class_as_corbaintf
        movq    %rax,%rdi
        call    P$PROGRAM_$$_DOI$MYI

This kind of code you will generate for each call to 
AttachObserver/DetachObserver.

So, not requiring the interface to be passed on saves code if you use corba interfaces. Using COM classes would generate even more code for each invokation.

Just to show why I prefer to avoid COM interfaces and the whole 'as' when 
possible.

If it had been possible to implement the whole observer thing without using
interfaces, I would have done it, but alas...

Michael.
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to