<p>Am 13.12.2016 09:22 schrieb "Maciej Izak" <<a href="mailto:hnb.code@gmail.com">hnb.code@gmail.com</a>>:<br>
><br>
><br>
> 2016-12-12 23:14 GMT+01:00 Maciej Izak <<a href="mailto:hnb.code@gmail.com">hnb.code@gmail.com</a>>:<br>
>><br>
>> With second iteration we could add your modifications, I have no other objections.<br>
></p>
<p>Comment regarding your previous mail: right, I forgot that due to InitializeArray() and FinalizeArray() being publicly available version of the internal helpers we either need to keep INIT and FULL RTTI in sync or a way to differentiate them... That's why you added the Terminator field I guess?</p>
<p>> New day new ideas :)<br>
><br>
> With my patch we don't really need ManagedFieldCount, ManagedFields, ManagedFieldTable in TTypeData (each of Managed* can still be added later). It means also much better memory usage and it solves RTL problems (which was mentioned in my previous message). All what we need is:<br>
><br>
> === code begin ===<br>
> type<br>
>   TInitManagedField = record<br>
>     TypeRefRef: TypeInfoPtr;<br>
>     FldOffset: SizeInt;  <br>
>   end;<br>
><br>
>   PPRecInitTable = ^PRecInitTable;<br>
>   PRecInitTable = TRecInitTable;<br>
>   TRecInitTable = packed record <br>
>     Size: Longint;<br>
>     Terminator: Pointer;<br>
>     ManagedFieldCount: Longint;<br>
>     { ManagedFields: array[0..ManagedFieldCount - 1] of TInitManagedField ; }<br>
>   end;<br>
><br>
>   TRecordField = record<br>
>     Visibility: TVisibility;<br>
>     TypeRef: TypeInfoPtr;<br>
>     FldOffset: SizeInt;<br>
><br>
>     Name: PShortString; { can be NULL if no ext RTTI }<br>
>   end;<br>
><br>
>   TManagedField = TRecordField deprecated;<br>
><br>
>   TTypeData = record<br>
>   // ...<br>
>     tkRecord: (<br>
>       RecSize: Integer;<br>
>       RecInitTable: PPRecInitTable;<br>
>       case Boolean of<br>
>         True: (ManagedFldCount: Integer deprecated 'Use RecInitTable^^.ManagedFieldCount or TotalFieldCount depending on your use case')<br>
>         False: (TotalFieldCount: Integer)<br>
>       { Fields: array[1..TotalFieldCount] of TRecordField }<br>
>       { Names: array[1..TotalFieldCount] of {packed} ShortString }<br>
>     );<br>
>   end;<br>
> === code end ===<br>
><br>
> I have hope that this is final solution :)</p>
<p>Okay, I think we can indeed go with this aside from one small remark: the double indirection for Pointers is only needed if data resides in different units as those might be in different dynamic packages. Since the INIT and FULL RTTI of a record are always in the same unit a single indirection is sufficient (thus PRecInitTable instead of PPRecInitTable).</p>
<p>Other than that I think we've found a good compromise for our wishes and hopes for this :)</p>
<p>Regards,<br>
Sven</p>