Results 1 to 4 of 4

Thread: Is there a way to enumerate *all* the fields of a class?

  1. #1

    Is there a way to enumerate *all* the fields of a class?

    Goal: to create the system of automatic saving/loading the entire game world to/from a stream.

    Why TPersistent + published properties won't do:
    1. Must work for dynamic arrays (single- and multi-dimensional) and records. AFAIK, FPC doesn't allow to publish these types.
    2. There is no way to control if I missed "publishing" some field - which, in turn can cause a nasty and hard to catch glitches in runtime - the last thing I need.

    Solution: (is this an optimal one?)
    Each class is registered at program startup. It then registers all its fields (via manually created method). To avoid mising something, the registering method looks up all the registered fields and analyzes if they cover the entire object instance (taking the aligning into account). If not, program terminates with a yell.

    Does anybody know a better way?

  2. #2

    Re: Is there a way to enumerate *all* the fields of a class?

    Quote Originally Posted by Chebmaster
    Goal: to create the system of automatic saving/loading the entire game world to/from a stream.
    Make sure all relevant props are published then :-) There is nothing else but workarounds. Deep RTTI is horrible expensive.

    Why TPersistent + published properties won't do:
    1. Must work for dynamic arrays (single- and multi-dimensional) and records. AFAIK, FPC doesn't allow to publish these types.
    For types you can't publish: wrap them in a publihed property that you only use for streaming (and mark them as such e.g. with a prefix)

    arrays: define an array property with getters and setters.
    records : define a class and stream the record in the class.

  3. #3

    Is there a way to enumerate *all* the fields of a class?

    Also look into TReader and TWriter. These help out a bit. In the end, outside of published properties in $m there is no automated way of doing this. Simply put, the info isn't there at run time.

  4. #4

    Is there a way to enumerate *all* the fields of a class?

    I just got notification about this thread on my e-mail as my ISP cut my access due to delayed payment.
    Now I'm back and can reply at last.


    ...In the end I implemented the approach with "registering" the types and classes. Every "streameable" :?: class has a special method where all the class fields are registered one by one. The registrator watches for the "holes" in the class body and stops the program if I forget to register some field.

    Example:
    [pascal]
    Type
    TMipMapKind = (mmk_None, mmk_Normal, mmk_AlphaCorrected);
    TMotherTexture = class (TTrulyPersistent)
    //base class for all textures.
    protected
    f_SessionID: int64;
    f_name: glUint;
    f_target: glEnum;
    f_quality: integer;
    f_priority: glFloat;
    f_mmk: TMipMapKind;
    function _GetIsResident: GLboolean;
    public
    procedure RegisterFields; override;
    procedure AfterLoading(); override;
    procedure AfterConstruction(); override;

    procedure Reload; virtual; abstract;
    procedure Bind;
    property IsResident: GLboolean read _GetIsResident;
    end;


    ...

    procedure TMotherTexture.RegisterFields;
    begin
    RegType(TypeInfo(TMIpMapKind));
    RegField('f_SessionID', @f_SessionId, TypeInfo(int64));
    RegField('f_name', @f_name, TypeInfo(glUint));
    RegField('f_target', @f_target, TypeInfo(glEnum));
    RegField('f_quality', @f_quality, TypeInfo(integer));
    RegField('f_priority', @f_priority, TypeInfo(glFloat));
    RegField('f_MipMapKind', @f_mmk, TypeInfo(TMipMapKind));
    end;
    [/pascal]

    In the end the system came out so powerful that the puny published properties can't even compare with it. I achieved the saving/loading speed of 1.000.000 cross-linked objects per second.

    Test can be downloaded here.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •