diff --git a/src/ZoneCodeGenerator/Generating/Computations/MemberComputations.cs b/src/ZoneCodeGenerator/Generating/Computations/MemberComputations.cs index 77f18198..5c800ca5 100644 --- a/src/ZoneCodeGenerator/Generating/Computations/MemberComputations.cs +++ b/src/ZoneCodeGenerator/Generating/Computations/MemberComputations.cs @@ -88,10 +88,9 @@ namespace ZoneCodeGenerator.Generating.Computations .OfType() .Any(array => array.DynamicSize != null); - public bool IsBarrier => HasDynamicArraySize || - information.StructureType != null && - information.StructureType != information.Parent && - information.StructureType.Computations.Barrier != null; + public bool IsDynamicMember => HasDynamicArraySize || + !ContainsNonEmbeddedReference && + information.StructureType?.Computations.DynamicMember != null; public MemberReferenceComputations References => new MemberReferenceComputations(information); diff --git a/src/ZoneCodeGenerator/Generating/Computations/MemberReferenceComputations.cs b/src/ZoneCodeGenerator/Generating/Computations/MemberReferenceComputations.cs index de9bf38f..03ccfd62 100644 --- a/src/ZoneCodeGenerator/Generating/Computations/MemberReferenceComputations.cs +++ b/src/ZoneCodeGenerator/Generating/Computations/MemberReferenceComputations.cs @@ -61,6 +61,9 @@ namespace ZoneCodeGenerator.Generating.Computations ? referenceTypePointer.Count : null; + public bool IsDynamicArray => + Reference is ReferenceTypeArray referenceTypeArray && referenceTypeArray.DynamicSize != null; + public MemberReferenceComputations(MemberInformation information) { this.information = information; diff --git a/src/ZoneCodeGenerator/Generating/Computations/StructureComputations.cs b/src/ZoneCodeGenerator/Generating/Computations/StructureComputations.cs index b538c1ca..204551dd 100644 --- a/src/ZoneCodeGenerator/Generating/Computations/StructureComputations.cs +++ b/src/ZoneCodeGenerator/Generating/Computations/StructureComputations.cs @@ -12,8 +12,8 @@ namespace ZoneCodeGenerator.Generating.Computations public bool IsUsed => information.Usages.Any(); - public MemberInformation Barrier => - information.OrderedMembers.FirstOrDefault(memberInformation => memberInformation.Computations.IsBarrier); + public MemberInformation DynamicMember => + information.OrderedMembers.FirstOrDefault(memberInformation => memberInformation.Computations.IsDynamicMember); public StructureComputations(StructureInformation information) { diff --git a/src/ZoneCodeGenerator/Generating/Templates/Loading/Embedded.stg b/src/ZoneCodeGenerator/Generating/Templates/Loading/Embedded.stg index 58132c8e..fbfbed79 100644 --- a/src/ZoneCodeGenerator/Generating/Templates/Loading/Embedded.stg +++ b/src/ZoneCodeGenerator/Generating/Templates/Loading/Embedded.stg @@ -4,7 +4,7 @@ delimiters "$", "$" LoadEmbedded_Load(context, structure, member, reference) ::= << $TypeVarName(member.Member.VariableType.Type)$ = &$TypeVarName(structure.Type)$->$member.Member.Name$$PrintArrayIndices(reference)$; -Load_$member.Member.VariableType.Type.Name$(false); +Load_$member.Member.VariableType.Type.Name$($if(member.Computations.IsDynamicMember)$true$else$false$endif$); >> LoadEmbedded_TypeCheck(context, structure, member, reference) ::= <% diff --git a/src/ZoneCodeGenerator/Generating/Templates/ZoneLoad.stg b/src/ZoneCodeGenerator/Generating/Templates/ZoneLoad.stg index 56945c81..56a187ea 100644 --- a/src/ZoneCodeGenerator/Generating/Templates/ZoneLoad.stg +++ b/src/ZoneCodeGenerator/Generating/Templates/ZoneLoad.stg @@ -81,7 +81,9 @@ $LoadMemberReference(context, structure, member, entry)$}$ >> LoadMemberReference(context, structure, member, reference) ::= <% -$if(reference.IsSinglePointer)$ +$if(reference.IsDynamicArray)$ +// Dynamic array $member.Member.Name$ +$elseif(reference.IsSinglePointer)$ $LoadSinglePointer(context, structure, member, reference)$ $elseif(reference.IsArrayPointer)$ $LoadArrayPointer(context, structure, member, reference)$ @@ -164,6 +166,8 @@ $elseif(member.Computations.ContainsNonEmbeddedReference)$ $LoadMemberCondition(context, structure, member)$ $elseif(member.StructureType && !member.StructureType.IsLeaf)$ $LoadMemberCondition(context, structure, member)$ +$elseif(member.Computations.IsDynamicMember)$ +$LoadMemberCondition(context, structure, member)$ $endif$ $endif$ @@ -238,10 +242,17 @@ void $LoaderClassName(context.Asset)$::LoadArray_$type.Name$(const bool atStream LoadMethod(context, structure) ::= << void $LoaderClassName(context.Asset)$::Load_$structure.Type.Name$(const bool atStreamStart) { - assert($TypeVarName(structure.Type)$ != nullptr); + assert($TypeVarName(structure.Type)$ != nullptr);$\\$ + + $if(!(structure.IsUnion && structure.Computations.DynamicMember))$ if(atStreamStart) + $if(!structure.Computations.DynamicMember)$ m_stream->Load<$structure.Type.FullName$>($TypeVarName(structure.Type)$);$\\$ + $else$ + m_stream->LoadPartial<$structure.Type.FullName$>($TypeVarName(structure.Type)$, offsetof($structure.Type.FullName$, $structure.Computations.DynamicMember.Member.Name$));$\\$ + $endif$ + $endif$ $if(structure.ReferenceFromNonDefaultNormalBlockExists || structure.IsAsset)$ m_stream->PushBlock($context.DefaultNormalBlock.Name$);$\\$ diff --git a/src/ZoneCodeGenerator/Parsing/CommandFile/PostProcessor/PostProcessorLeafs.cs b/src/ZoneCodeGenerator/Parsing/CommandFile/PostProcessor/PostProcessorLeafs.cs index a7616102..5fb868a2 100644 --- a/src/ZoneCodeGenerator/Parsing/CommandFile/PostProcessor/PostProcessorLeafs.cs +++ b/src/ZoneCodeGenerator/Parsing/CommandFile/PostProcessor/PostProcessorLeafs.cs @@ -32,6 +32,10 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.PostProcessor if (!hasNoPointerMembers) return false; + // If the member has an embedded type with dynamic size + if (member.Computations.HasDynamicArraySize) + return false; + if (member.StructureType != null && member.StructureType != structureInformation && !IsLeaf(member.StructureType)) diff --git a/src/ZoneCodeGenerator/Parsing/CommandFile/PostProcessor/PostProcessorMemberLeafs.cs b/src/ZoneCodeGenerator/Parsing/CommandFile/PostProcessor/PostProcessorMemberLeafs.cs index 422dfd11..755ac7a3 100644 --- a/src/ZoneCodeGenerator/Parsing/CommandFile/PostProcessor/PostProcessorMemberLeafs.cs +++ b/src/ZoneCodeGenerator/Parsing/CommandFile/PostProcessor/PostProcessorMemberLeafs.cs @@ -29,6 +29,9 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.PostProcessor if (!hasNoPointerMembers) return false; + if (member.Computations.HasDynamicArraySize) + return false; + return true; } diff --git a/src/ZoneLoading/Zone/Stream/IZoneInputStream.h b/src/ZoneLoading/Zone/Stream/IZoneInputStream.h index 6584bda3..bfb3f341 100644 --- a/src/ZoneLoading/Zone/Stream/IZoneInputStream.h +++ b/src/ZoneLoading/Zone/Stream/IZoneInputStream.h @@ -31,6 +31,12 @@ public: LoadDataInBlock(const_cast(reinterpret_cast(dst)), count * sizeof(T)); } + template + void LoadPartial(T* dst, const size_t size) + { + LoadDataInBlock(const_cast(reinterpret_cast(dst)), size); + } + virtual void** InsertPointer() = 0; template T** InsertPointer()