#1 2018-01-31 11:31:09

hnb
Member
Registered: 2015-06-15
Posts: 290

TObjProxyVariant - new variant kind

Hi,

I almost forgot about my new small feature already implemented some time ago : TObjProxyVariant

https://github.com/synopse/mORMot/pull/79

TObjProxyVariant is a custom variant type used to have direct access to object published properties. Very usable for cases where conversion from object to variant is not sufficient. TObjProxyVariant provides direct access to object properties from Variant instead of conversion to Variant. Example usage with mustache:

{$MODE DELPHI}
{$APPTYPE CONSOLE}

uses
  mORMot, SynMustache;

type
  TA = class
  private
    fi: integer;
    function GetR: Integer;
  published
    property r: Integer read GetR;
    property i: integer read fi write fi;
  end;

  TB = class
  protected
    fa: TA;
  public
    constructor Create;
    destructor Destroy; override;
  published
    property a: TA read fa;
  end;

function TA.GetR: Integer;
begin
  Result := Random(100);
end;

constructor TB.Create;
begin
  fa := TA.Create;
end;

destructor TB.Destroy;
begin
  fa.Free;
end;

var
  b: TB;
  v: variant;
begin
  b := TB.Create;

  TObjProxyVariant.New(v, b);
  v.a.i := 10;
  WriteLn(TSynMustache.Parse('{{a.r}}/{{a.i}}/{{a.r}}/{{a.i}}/{{a.r}}').Render(v));

  b.Free;
  readln;
end.

example output :

54/10/59/10/71

best regards,
Maciej Izak

Offline

#2 2018-01-31 12:40:59

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 337

Re: TObjProxyVariant - new variant kind

Interesting and very useful, great works !!!


Esteban

Offline

#3 2018-01-31 13:22:19

edwinsn
Member
Registered: 2010-07-02
Posts: 1,218

Re: TObjProxyVariant - new variant kind

Very handy!

Usually I use duckduckdelphi in such case, but it uses Extended RTTI so in some cases it's slow.


Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.

Offline

#4 2018-01-31 13:58:41

hnb
Member
Registered: 2015-06-15
Posts: 290

Re: TObjProxyVariant - new variant kind

thanks wink TObjProxyVariant can be optimized a lot : by caching TSQLPropInfoRTTI and by TSynDictionary for fast lookup for property names. Anyway current implementation is fast enough for me.


best regards,
Maciej Izak

Offline

#5 2018-01-31 14:05:48

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,669
Website

Re: TObjProxyVariant - new variant kind

I'm not sure that in practice, it will be much faster than ObjectToVariant() on real code... this may not be the bottleneck.

Offline

#6 2018-01-31 14:15:46

hnb
Member
Registered: 2015-06-15
Posts: 290

Re: TObjProxyVariant - new variant kind

TObjProxyVariant is here because ObjectToVariant not work for all cases. It is not art for the art but comes from practice and is widely used in my projects. Sometimes "pre generated" Variant form object is not best choice.


best regards,
Maciej Izak

Offline

#7 2018-01-31 14:44:45

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,669
Website

Re: TObjProxyVariant - new variant kind

But in practice, the way it is coded don't make it really faster than ObjectToVariant().
What do you mean that "ObjectToVariant not work for all cases"? Is there a bug somewhere?

Offline

#8 2018-01-31 14:53:42

edwinsn
Member
Registered: 2010-07-02
Posts: 1,218

Re: TObjProxyVariant - new variant kind

Speaking of cache, does the mORMot framework has a generic object pool yet?


Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.

Offline

#9 2018-01-31 15:51:28

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,669
Website

Re: TObjProxyVariant - new variant kind

Since the beginning, there is JSON cache at TSQLRest level, which is very efficient.
Maintaining a cache of JSON is in practice a better approach that maintaining a cache of objects instances, since you can reuse the same JSON to fill several object instances, it is easier to make it threadsafe and it has lower memory fragmentation.
Instantiating an object is not worth caching: only getting the properties values may need cache.

Offline

#10 2018-01-31 16:20:13

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,669
Website

Re: TObjProxyVariant - new variant kind

Anyway, I've implemented it as TObjectVariant, since the idea is great.
See https://synopse.info/fossil/info/d5d49cdd32

It should be faster, supports TSQLRecord.ID as expected, and JSON serialization.

Offline

#11 2018-01-31 22:03:40

hnb
Member
Registered: 2015-06-15
Posts: 290

Re: TObjProxyVariant - new variant kind

Thanks, for improved/faster implementation. I think that TObjectVariant is better name smile. The description "lazy-loading to object properties from Variant" is perfect description of my intention.


best regards,
Maciej Izak

Offline

Board footer

Powered by FluxBB