[fpc-devel] Published record

Michalis Kamburelis michalis.kambi at gmail.com
Sat Aug 17 23:31:34 CEST 2024


Thanks Michael!

OK, that's partially good news :)

I understand that streaming records by default to LFM would lead to
too many questions (and I'm unsure whether Delphi does it too, for
records and DFM). If this means they are not allowed in the
"published" section, *but* the RTTI is capable of telling me what
records are in the "public" section, and read / write them (using
proper getters / setters), this is something we can work with.

I mean, I can 1. add my own serialization / deserialization of them,
and 2. make them exposed in the object inspector in CGE editor.

(
Details:
AD 1 - For serialization / deserialization, in Castle Game Engine, we
use CastleComponentSerialize on top of FpJsonRtti. One of the reasons
I like JSON and FpJsonRtti over LFM is that this gives us more control
-- I know I can add code to CastleComponentSerialize to deal with
records, if only RTTI tells me about them.
AD 2 - For object inspector, we use Lazarus "ObjectInspector" unit.
I'm less sure about it, but hopefully it is possible to add there
"fake" subcomponents too.
)

Can you expand your statement "It is since some time, but you must
explicitly enable it."? What compiler switch enables it? What API
should I use to access it -- Rtti unit in FPC has all we need? (I
guess TypeInfo unit API does not expose it, or it does?)

To make my question more concrete, imagine a code like this:

"""
type
  TVector3 = record X, Y, Z: Single end;
  TCastleTransform = class
  public
    property Translation: TVector3 read ... write ...;
    property Scale: TVector3 read ... write ...;
  end;
"""

I'm looking for a way to tell, at runtime, using RTTI, having any
instance of TObject (maybe of TCastleTransform):

- what public properties of type TVector3 are there (like
"Translation" and "Scale"),
- what public fields does TVector3 have (like X, Y, Z) (this is
nice-to-have, we could work without this info but then limiting our
record serialization / deserialization to only specific record types),
- read / write these record properties using the proper getter /
setter (whether it's direct field access or a method).

Regards,
Michalis

sob., 17 sie 2024 o 16:44 Michael Van Canneyt via fpc-devel
<fpc-devel at lists.freepascal.org> napisał(a):
>
>
>
> On Fri, 16 Aug 2024, Michalis Kamburelis via fpc-devel wrote:
>
> >> You cannot publish records, and this is not planned.
> >>
> >> This is because things like
> >>
> >> MyClass.MyRecord.MyField:=12;
> >>
> >> do not work as one would naively expect. It does work if you use a TPersistent
> >> instead of a record (the very reason the TPersistent class was invented)
> >
> > Do you mean the trap when "MyField" is actually a property (with
> > possible setter) and "MyClass.MyRecord.MyField:=123" effectively (may)
> > modify a temporary value? I feel this is something a bit independent
> > to being able to publish the records.
>
> Partly, yes.
>
> You need "published" when you want to stream them (in a .lfm file).
>
> But for streaming the above behaviour is prohibitive.
>
> When using a TPersistent, it is a class which behaves 'normally'
> and you get the streaming "for free": streaming a TPersistent is not
> different from a TComponent.
>
> To be able to stream published records one would need to create an empty
> record, fill it with data and then assign the record (possibly recursively)
> because of the above behaviour.
>
> Doing this correctly would simply lead too far, since basically you need
> to duplicate the whole mechanism that exists for classes.
>
> A more funddamental reason is of course that records can have variant
> parts and streaming that in a correct way is impossible:
> you do not know what actual data is present.
> Which of the variants should then be streamed ?
>
> > Last time I checked, the RTTI information was not generated for
> > records in only the "public" section, and (as per above) the records
> > could not be placed in the "published" section. Is now one of the
> > above possible? :)
>
> It is since some time, but you must explicitly enable it.
> The basic TObject does not have extended RTTI enabled as it is in Delphi,
> except when you compile the unicode rtl.
>
> Enabling it in TObject doubles the binary size of any project I tested it
> with, so I don't plan to enable it in the default RTL.
>
> Michael.
> _______________________________________________
> fpc-devel maillist  -  fpc-devel at lists.freepascal.org
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


More information about the fpc-devel mailing list