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.