From 1544bbbd181959c2d1a95dbd433a7048fed5f038 Mon Sep 17 00:00:00 2001 From: Jan Date: Mon, 23 Dec 2019 17:05:38 +0100 Subject: [PATCH] ZoneCodeGenerator: Add loading of dynamic arrays --- .../Computations/MemberComputations.cs | 18 +++++++++++------ .../MemberReferenceComputations.cs | 4 ++++ .../Templates/Loading/DynamicArray.stg | 20 +++++++++++++++++++ .../Generating/Templates/Loading/Embedded.stg | 18 ++++++++++++++--- .../Generating/Templates/ZoneLoad.stg | 15 +++++++------- 5 files changed, 58 insertions(+), 17 deletions(-) create mode 100644 src/ZoneCodeGenerator/Generating/Templates/Loading/DynamicArray.stg diff --git a/src/ZoneCodeGenerator/Generating/Computations/MemberComputations.cs b/src/ZoneCodeGenerator/Generating/Computations/MemberComputations.cs index 5c800ca5..9064c681 100644 --- a/src/ZoneCodeGenerator/Generating/Computations/MemberComputations.cs +++ b/src/ZoneCodeGenerator/Generating/Computations/MemberComputations.cs @@ -76,13 +76,15 @@ namespace ZoneCodeGenerator.Generating.Computations public bool IsTempBlock => information.Block != null && information.Block.IsTemp; public bool IsRuntimeBlock => information.Block != null && information.Block.IsRuntime; - public bool IsFirstMember => - information.Parent.OrderedMembers.FirstOrDefault(member => - !member.IsLeaf && !member.Computations.ShouldIgnore) == information; + private IEnumerable ParentUsedMembers => + information.Parent.IsUnion && information.Parent.Computations.DynamicMember != null + ? information.Parent.OrderedMembers.Where(member => !member.Computations.ShouldIgnore) + : information.Parent.OrderedMembers.Where(member => + !member.IsLeaf && !member.Computations.ShouldIgnore); - public bool IsLastMember => - information.Parent.OrderedMembers.LastOrDefault(member => - !member.IsLeaf && !member.Computations.ShouldIgnore) == information; + public bool IsFirstMember => ParentUsedMembers.FirstOrDefault() == information; + + public bool IsLastMember => ParentUsedMembers.LastOrDefault() == information; public bool HasDynamicArraySize => information.Member.VariableType.References .OfType() @@ -92,6 +94,10 @@ namespace ZoneCodeGenerator.Generating.Computations !ContainsNonEmbeddedReference && information.StructureType?.Computations.DynamicMember != null; + public bool IsAfterPartialLoad => IsDynamicMember || + information.Parent.IsUnion && + information.Parent.Computations.DynamicMember != null; + public MemberReferenceComputations References => new MemberReferenceComputations(information); public MemberComputations(MemberInformation information) diff --git a/src/ZoneCodeGenerator/Generating/Computations/MemberReferenceComputations.cs b/src/ZoneCodeGenerator/Generating/Computations/MemberReferenceComputations.cs index 03ccfd62..8e9da8e0 100644 --- a/src/ZoneCodeGenerator/Generating/Computations/MemberReferenceComputations.cs +++ b/src/ZoneCodeGenerator/Generating/Computations/MemberReferenceComputations.cs @@ -64,6 +64,10 @@ namespace ZoneCodeGenerator.Generating.Computations public bool IsDynamicArray => Reference is ReferenceTypeArray referenceTypeArray && referenceTypeArray.DynamicSize != null; + public IEvaluation DynamicArrayCountEvaluation => Reference is ReferenceTypeArray referenceTypeArray + ? referenceTypeArray.DynamicSize + : null; + public MemberReferenceComputations(MemberInformation information) { this.information = information; diff --git a/src/ZoneCodeGenerator/Generating/Templates/Loading/DynamicArray.stg b/src/ZoneCodeGenerator/Generating/Templates/Loading/DynamicArray.stg new file mode 100644 index 00000000..3690972a --- /dev/null +++ b/src/ZoneCodeGenerator/Generating/Templates/Loading/DynamicArray.stg @@ -0,0 +1,20 @@ +delimiters "$", "$" + +// Everything related to loading a dynamic array + +LoadDynamicArray_Load(context, structure, member, reference) ::= <% +$if(member.StructureType && !member.StructureType.IsLeaf)$ + +$TypeVarName(member.Member.VariableType.Type)$ = $TypeVarName(structure.Type)$->$member.Member.Name$$PrintArrayIndices(reference)$;$\n$ +LoadArray_$member.Member.VariableType.Type.Name$(true, $PrintEvaluation(reference.DynamicArrayCountEvaluation)$); + +$else$ + +m_stream->Load<$TypeDeclaration(member.Member.VariableType)$$PrintFollowingReferences(reference.FollowingReferences)$>($TypeVarName(structure.Type)$->$member.Member.Name$$PrintArrayIndices(reference)$, $PrintEvaluation(reference.DynamicArrayCountEvaluation)$); + +$endif$ +%> + +LoadDynamicArray(context, structure, member, reference) ::= <% +$LoadDynamicArray_Load(context, structure, member, reference)$ +%> \ No newline at end of file diff --git a/src/ZoneCodeGenerator/Generating/Templates/Loading/Embedded.stg b/src/ZoneCodeGenerator/Generating/Templates/Loading/Embedded.stg index fbfbed79..4ce29d5a 100644 --- a/src/ZoneCodeGenerator/Generating/Templates/Loading/Embedded.stg +++ b/src/ZoneCodeGenerator/Generating/Templates/Loading/Embedded.stg @@ -3,8 +3,12 @@ delimiters "$", "$" // Everything related to loading an embedded reference LoadEmbedded_Load(context, structure, member, reference) ::= << +$if(!member.IsLeaf)$ $TypeVarName(member.Member.VariableType.Type)$ = &$TypeVarName(structure.Type)$->$member.Member.Name$$PrintArrayIndices(reference)$; -Load_$member.Member.VariableType.Type.Name$($if(member.Computations.IsDynamicMember)$true$else$false$endif$); +Load_$member.Member.VariableType.Type.Name$($if(member.Computations.IsAfterPartialLoad)$true$else$false$endif$);$\\$ +$elseif(member.Computations.IsAfterPartialLoad)$ +m_stream->Load<$TypeDeclaration(member.Member.VariableType)$$PrintFollowingReferences(reference.FollowingReferences)$>(&$TypeVarName(structure.Type)$->$member.Member.Name$$PrintArrayIndices(reference)$);$\\$ +$endif$ >> LoadEmbedded_TypeCheck(context, structure, member, reference) ::= <% @@ -31,13 +35,21 @@ LoadEmbedded(context, structure, member, reference) ::= <% $LoadEmbedded_Block(context, structure, member, reference)$ %> +LoadEmbeddedArray_Load(context, structure, member, reference) ::= << +$if(!member.IsLeaf)$ +$TypeVarName(member.Member.VariableType.Type)$ = $TypeVarName(structure.Type)$->$member.Member.Name$$PrintArrayIndices(reference)$; +LoadArray_$member.Member.VariableType.Type.Name$($if(member.Computations.IsAfterPartialLoad)$true$else$false$endif$, $reference.ArraySize$);$\\$ +$elseif(member.Computations.IsAfterPartialLoad)$ +m_stream->Load<$TypeDeclaration(member.Member.VariableType)$$PrintFollowingReferences(reference.FollowingReferences)$>($TypeVarName(structure.Type)$->$member.Member.Name$$PrintArrayIndices(reference)$, $reference.ArraySize$);$\\$ +$endif$ +>> + LoadEmbeddedArray_TypeCheck(context, structure, member, reference) ::= <% $if(member.IsScriptString)$ varScriptString = $TypeVarName(structure.Type)$->$member.Member.Name$$PrintArrayIndices(reference)$;$\n$ LoadScriptStringArray(false, $reference.ArraySize$); $else$ -$TypeVarName(member.Member.VariableType.Type)$ = $TypeVarName(structure.Type)$->$member.Member.Name$$PrintArrayIndices(reference)$;$\n$ -LoadArray_$member.Member.VariableType.Type.Name$(false, $reference.ArraySize$); +$LoadEmbeddedArray_Load(context, structure, member, reference)$ $endif$ %> diff --git a/src/ZoneCodeGenerator/Generating/Templates/ZoneLoad.stg b/src/ZoneCodeGenerator/Generating/Templates/ZoneLoad.stg index 56a187ea..cd631e11 100644 --- a/src/ZoneCodeGenerator/Generating/Templates/ZoneLoad.stg +++ b/src/ZoneCodeGenerator/Generating/Templates/ZoneLoad.stg @@ -4,6 +4,7 @@ import "Common.stg" import "Loading/Common.stg" import "Loading/ArrayPointer.stg" +import "Loading/DynamicArray.stg" import "Loading/Embedded.stg" import "Loading/SinglePointer.stg" import "Loading/PointerArray.stg" @@ -82,7 +83,7 @@ $LoadMemberReference(context, structure, member, entry)$}$ LoadMemberReference(context, structure, member, reference) ::= <% $if(reference.IsDynamicArray)$ -// Dynamic array $member.Member.Name$ +$LoadDynamicArray(context, structure, member, reference)$ $elseif(reference.IsSinglePointer)$ $LoadSinglePointer(context, structure, member, reference)$ $elseif(reference.IsArrayPointer)$ @@ -166,7 +167,7 @@ $elseif(member.Computations.ContainsNonEmbeddedReference)$ $LoadMemberCondition(context, structure, member)$ $elseif(member.StructureType && !member.StructureType.IsLeaf)$ $LoadMemberCondition(context, structure, member)$ -$elseif(member.Computations.IsDynamicMember)$ +$elseif(member.Computations.IsAfterPartialLoad)$ $LoadMemberCondition(context, structure, member)$ $endif$ @@ -208,11 +209,7 @@ void $LoaderClassName(context.Asset)$::LoadPtr_$structure.Type.Name$(const bool } else { - $if(structure.Block.IsTemp)$ *$TypePtrVarName(structure.Type)$ = m_stream->ConvertOffsetToAlias(*$TypePtrVarName(structure.Type)$); - $else$ - *$TypePtrVarName(structure.Type)$ = m_stream->ConvertOffsetToPointer(*$TypePtrVarName(structure.Type)$); - $endif$ } } @@ -252,13 +249,15 @@ void $LoaderClassName(context.Asset)$::Load_$structure.Type.Name$(const bool atS $else$ m_stream->LoadPartial<$structure.Type.FullName$>($TypeVarName(structure.Type)$, offsetof($structure.Type.FullName$, $structure.Computations.DynamicMember.Member.Name$));$\\$ $endif$ + $else$ + assert(atStreamStart);$\\$ $endif$ - $if(structure.ReferenceFromNonDefaultNormalBlockExists || structure.IsAsset)$ + $if(structure.IsAsset)$ m_stream->PushBlock($context.DefaultNormalBlock.Name$);$\\$ $endif$ $structure.OrderedMembers:{member | $LoadMemberIfNeedsTreatment(context, structure, member)$}$ - $if(structure.ReferenceFromNonDefaultNormalBlockExists || structure.IsAsset)$ + $if(structure.IsAsset)$ m_stream->PopBlock(); $endif$