ZoneCodeGenerator: Add computations for single references to be able to correctly handle arrays

This commit is contained in:
Jan 2019-11-24 01:58:01 +01:00
parent 6d1359c3d9
commit 5d3c13e833
15 changed files with 418 additions and 223 deletions

View File

@ -14,36 +14,55 @@ namespace ZoneCodeGenerator.Generating.Computations
&& information.Condition.IsStatic && information.Condition.IsStatic
&& information.Condition.EvaluateNumeric() == 0; && information.Condition.EvaluateNumeric() == 0;
public bool IsEmbeddedReference => !information.Member.VariableType.References.OfType<ReferenceTypePointer>().Any(); public bool ContainsNonEmbeddedReference =>
information.Member.VariableType.References.OfType<ReferenceTypePointer>().Any();
public bool IsNonEmbeddedReference => !IsEmbeddedReference; public bool ContainsSinglePointerReference => information.Member.VariableType.References.Any()
&& information.Member.VariableType.References.Last() is
public bool IsSinglePointerReference => information.Member.VariableType.References.Any() ReferenceTypePointer pointerReference
&& information.Member.VariableType.References.Last() is ReferenceTypePointer
pointerReference
&& !pointerReference.IsArray; && !pointerReference.IsArray;
public bool IsArrayPointerReference => information.Member.VariableType.References.Any() public bool ContainsArrayPointerReference => information.Member.VariableType.References.Any()
&& information.Member.VariableType.References.Last() is ReferenceTypePointer && information.Member.VariableType.References.Last() is
pointerReference ReferenceTypePointer pointerReference
&& pointerReference.IsArray; && pointerReference.IsArray;
public bool ContainsPointerArrayReference => ContainsSinglePointerReference
&& (IsArray && PointerDepthIsOne || !IsArray && PointerDepthIsTwo);
public bool ContainsArrayReference => information.Member.VariableType.References.Any()
&& information.Member.VariableType.References
.Last() is ReferenceTypeArray;
public IEvaluation ArrayPointerCountEvaluation => public IEvaluation ArrayPointerCountEvaluation =>
information.Member.VariableType.References.Last() is ReferenceTypePointer pointerReference information.Member.VariableType.References.Last() is ReferenceTypePointer pointerReference
? pointerReference.Count ? pointerReference.Count
: null; : null;
public bool IsArrayReference => information.Member.VariableType.References.Any()
&& information.Member.VariableType.References.Last() is ReferenceTypeArray;
public bool IsArray => information.Member.VariableType.References public bool IsArray => information.Member.VariableType.References
.OfType<ReferenceTypeArray>() .TakeWhile(type => type is ReferenceTypeArray)
.Any(); .Any();
public IEnumerable<int> ArraySizes => information.Member.VariableType.References public IEnumerable<int> ArraySizes => information.Member.VariableType.References
.TakeWhile(type => type is ReferenceTypeArray)
.OfType<ReferenceTypeArray>() .OfType<ReferenceTypeArray>()
.Select(array => array.ArraySize); .Select(array => array.ArraySize);
public int ArrayDimension => information.Member.VariableType.References
.TakeWhile(type => type is ReferenceTypeArray)
.Count();
public bool IsPointerToArray => information.Member.VariableType.References.OfType<ReferenceTypePointer>().Any()
&& information.Member.VariableType.References.Last() is ReferenceTypeArray;
public IEnumerable<int> PointerToArraySizes => information.Member.VariableType.References
.Reverse()
.TakeWhile(type => type is ReferenceTypeArray)
.OfType<ReferenceTypeArray>()
.Reverse()
.Select(array => array.ArraySize);
public int PointerDepth => information.Member.VariableType.References public int PointerDepth => information.Member.VariableType.References
.OfType<ReferenceTypePointer>() .OfType<ReferenceTypePointer>()
.Count(); .Count();
@ -51,6 +70,8 @@ namespace ZoneCodeGenerator.Generating.Computations
public bool PointerDepthIsOne => PointerDepth == 1; public bool PointerDepthIsOne => PointerDepth == 1;
public bool PointerDepthIsTwo => PointerDepth == 2; public bool PointerDepthIsTwo => PointerDepth == 2;
public MemberReferenceComputations References => new MemberReferenceComputations(information);
public MemberComputations(MemberInformation information) public MemberComputations(MemberInformation information)
{ {
this.information = information; this.information = information;

View File

@ -0,0 +1,67 @@
using System.Collections.Generic;
using System.Linq;
using ZoneCodeGenerator.Domain;
using ZoneCodeGenerator.Domain.Evaluation;
using ZoneCodeGenerator.Domain.Information;
namespace ZoneCodeGenerator.Generating.Computations
{
class MemberReferenceComputations
{
private readonly MemberInformation information;
private readonly List<int> referenceIndices;
public ReferenceType Reference => referenceIndices.Count < information.Member.VariableType.References.Count
? information.Member.VariableType.References[referenceIndices.Count]
: null;
public ReferenceType NextReference =>
referenceIndices.Count + 1 < information.Member.VariableType.References.Count
? information.Member.VariableType.References[referenceIndices.Count + 1]
: null;
public IEnumerable<ReferenceType> FollowingReferences =>
information.Member.VariableType.References.Skip(referenceIndices.Count + 1);
public IEnumerable<int> ArrayIndices => referenceIndices;
public bool IsArray => Reference is ReferenceTypeArray;
public int ArraySize => Reference is ReferenceTypeArray array ? array.ArraySize : 0;
public IEnumerable<MemberReferenceComputations> ArrayEntries => Enumerable.Range(0, ArraySize)
.Select(i => new MemberReferenceComputations(information, referenceIndices.Concat(new[] {i})));
public bool IsSinglePointer => Reference is ReferenceTypePointer referenceTypePointer
&& !referenceTypePointer.IsArray
&& !FollowingReferences.OfType<ReferenceTypePointer>().Any();
public bool IsArrayPointer => Reference is ReferenceTypePointer referenceTypePointer
&& referenceTypePointer.IsArray
&& !FollowingReferences.OfType<ReferenceTypePointer>().Any();
public IEvaluation ArrayPointerCountEvaluation => Reference is ReferenceTypePointer referenceTypePointer
? referenceTypePointer.Count
: null;
public bool IsPointerArray =>
(Reference is ReferenceTypePointer referenceTypePointer && referenceTypePointer.IsArray ||
Reference is ReferenceTypeArray)
&& NextReference is ReferenceTypePointer nextReferencePointer && !nextReferencePointer.IsArray;
public IEvaluation PointerArrayCountEvaluation => NextReference is ReferenceTypePointer referenceTypePointer
? referenceTypePointer.Count
: null;
public MemberReferenceComputations(MemberInformation information)
{
this.information = information;
referenceIndices = new List<int>();
}
private MemberReferenceComputations(MemberInformation information, IEnumerable<int> referenceIndices)
{
this.information = information;
this.referenceIndices = new List<int>(referenceIndices);
}
}
}

View File

@ -1,24 +1,42 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using ZoneCodeGenerator.Domain; using ZoneCodeGenerator.Domain;
using ZoneCodeGenerator.Domain.FastFileStructure; using ZoneCodeGenerator.Domain.FastFileStructure;
using ZoneCodeGenerator.Domain.Information; using ZoneCodeGenerator.Domain.Information;
using ZoneCodeGenerator.Interface; using ZoneCodeGenerator.Interface;
using ZoneCodeGenerator.Persistence;
namespace ZoneCodeGenerator.Generating namespace ZoneCodeGenerator.Generating
{ {
class RenderingContext class RenderingContext
{ {
public class UsedType
{
public DataType Type { get; }
public StructureInformation Information { get; }
public bool IsContextAsset { get; set; }
public bool NonEmbeddedReferenceExists { get; set; }
public bool ArrayReferenceExists { get; set; }
public bool PointerArrayReferenceExists { get; set; }
public UsedType(DataType type, StructureInformation information)
{
Type = type;
Information = information;
IsContextAsset = false;
NonEmbeddedReferenceExists = false;
ArrayReferenceExists = false;
PointerArrayReferenceExists = false;
}
}
public string Game { get; set; } public string Game { get; set; }
public StructureInformation Asset { get; set; } public StructureInformation Asset { get; set; }
public ISet<StructureInformation> Structures { get; } private readonly IDictionary<DataType, UsedType> usedTypes;
public ISet<DataType> MemberTypes { get; } public IEnumerable<UsedType> UsedTypes => usedTypes.Values;
public IEnumerable<StructureInformation> ReferencedAssets => public IEnumerable<UsedType> ReferencedAssets => UsedTypes.Where(type => type.Information != null && type.Information.IsAsset && type.Information != Asset);
Structures.Where(inf => inf.IsAsset && inf != Asset);
public IList<FastFileBlock> Blocks { get; private set; } public IList<FastFileBlock> Blocks { get; private set; }
@ -27,22 +45,45 @@ namespace ZoneCodeGenerator.Generating
private RenderingContext() private RenderingContext()
{ {
Structures = new HashSet<StructureInformation>(); usedTypes = new Dictionary<DataType, UsedType>();
MemberTypes = new HashSet<DataType>();
} }
private void AddToContext(StructureInformation structureInformation) private void AddToContext(StructureInformation structureInformation)
{ {
if (!Structures.Add(structureInformation)) if (usedTypes.ContainsKey(structureInformation.Type))
return; return;
var newUsage = new UsedType(structureInformation.Type, structureInformation);
usedTypes.Add(newUsage.Type, newUsage);
if (structureInformation.IsAsset && structureInformation != Asset) if (structureInformation.IsAsset && structureInformation != Asset)
return; return;
foreach (var member in structureInformation.OrderedMembers foreach (var member in structureInformation.OrderedMembers
.Where(member => member.StructureType != null && !member.Computations.ShouldIgnore)) .Where(member => !member.Computations.ShouldIgnore))
{ {
if(member.StructureType != null)
AddToContext(member.StructureType); AddToContext(member.StructureType);
UsedType usedType;
if (!usedTypes.ContainsKey(member.Member.VariableType.Type))
{
usedType = new UsedType(member.Member.VariableType.Type, member.StructureType);
usedTypes.Add(usedType.Type, usedType);
}
else
{
usedType = usedTypes[member.Member.VariableType.Type];
}
if (member.Computations.ContainsNonEmbeddedReference)
usedType.NonEmbeddedReferenceExists = true;
if (member.Computations.ContainsArrayPointerReference || member.Computations.ContainsArrayReference)
usedType.ArrayReferenceExists = true;
if (member.Computations.ContainsPointerArrayReference)
usedType.PointerArrayReferenceExists = true;
} }
} }
@ -56,15 +97,7 @@ namespace ZoneCodeGenerator.Generating
}; };
context.AddToContext(asset); context.AddToContext(asset);
context.MemberTypes.UnionWith(context.Structures context.usedTypes[asset.Type].IsContextAsset = true;
.Where(structureInformation => !structureInformation.IsAsset || structureInformation == asset)
.Where(structureInformation =>
structureInformation.Computations.IsUsed || structureInformation == asset)
.SelectMany(information => information.OrderedMembers)
.Where(information => !information.Computations.ShouldIgnore)
.Select(information => information.Member.VariableType.Type)
.Where(type => !(type is DataTypeBaseType) && type != asset.Type)
.Distinct());
return context; return context;
} }

View File

@ -5,8 +5,24 @@ Lower(name) ::= "$name; format=\"lower\"$"
TypeDeclaration(typeDecl) ::= "$if(typeDecl.IsConst)$const $endif$$typeDecl.Type.FullName$" TypeDeclaration(typeDecl) ::= "$if(typeDecl.IsConst)$const $endif$$typeDecl.Type.FullName$"
TypeVarName(structure) ::= "var$structure.Type.Name$" TypeVarName(structure) ::= "var$SafeTypeName(structure.Type)$"
TypePtrVarName(structure) ::= "var$structure.Type.Name$Ptr" TypePtrVarName(structure) ::= "var$SafeTypeName(structure.Type)$Ptr"
SafeTypeName(type) ::= "$type; format=\"safe_name\"$"
PrintFollowingReferences(references) ::= <%
$references:{ reference |
$if(reference.ArraySize)$
[$reference.ArraySize$]
$else$
*
$endif$
}$
%>
PrintArrayIndices(reference) ::= "$reference.ArrayIndices:{ index | [$index$] }$"
PrintOperandStatic(op) ::= <% PrintOperandStatic(op) ::= <%
$if(op.EnumMemberValue)$ $if(op.EnumMemberValue)$

View File

@ -1,68 +1,59 @@
delimiters "$", "$"
// Everything related to loading a pointer with a count that can be larger than 1 // Everything related to loading a pointer with a count that can be larger than 1
LoadArrayPointer_Loading(context, structure, member) ::= <% LoadArrayPointer_Loading(context, structure, member, reference) ::= <%
$TypeVarName(structure)$->$member.Member.Name$ = m_stream->Alloc<$TypeDeclaration(member.Member.VariableType)$>(alignof($TypeDeclaration(member.Member.VariableType)$));$\n$ $TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$ = m_stream->Alloc<$TypeDeclaration(member.Member.VariableType)$$PrintFollowingReferences(reference.FollowingReferences)$>(alignof($TypeDeclaration(member.Member.VariableType)$$PrintFollowingReferences(reference.FollowingReferences)$));$\n$
$if(member.StructureType && !member.StructureType.IsLeaf)$ $if(member.StructureType && !member.StructureType.IsLeaf)$
$TypeVarName(member.StructureType)$ = $TypeVarName(structure)$->$member.Member.Name$;$\n$ $TypeVarName(member.StructureType)$ = $TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$;$\n$
LoadArray_$member.Member.VariableType.Type.Name$(true, $PrintEvaluation(member.Computations.ArrayPointerCountEvaluation)$); LoadArray_$member.Member.VariableType.Type.Name$(true, $PrintEvaluation(reference.ArrayPointerCountEvaluation)$);
$else$ $else$
m_stream->Load<$TypeDeclaration(member.Member.VariableType)$>($TypeVarName(structure)$->$member.Member.Name$, $PrintEvaluation(member.Computations.ArrayPointerCountEvaluation)$); m_stream->Load<$TypeDeclaration(member.Member.VariableType)$$PrintFollowingReferences(reference.FollowingReferences)$>($TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$, $PrintEvaluation(reference.ArrayPointerCountEvaluation)$);
$endif$ $endif$
%> %>
LoadArrayPointer_PointerCheck(context, structure, member) ::= << LoadArrayPointer_PointerCheck(context, structure, member, reference) ::= <<
if ($TypeVarName(structure)$->$member.Member.Name$) if ($TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$)
{ {
$if(member.IsReusable)$ $if(member.IsReusable)$
if($TypeVarName(structure)$->$member.Member.Name$ == PTR_FOLLOWING) if($TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$ == PTR_FOLLOWING)
{ {
$LoadArrayPointer_Loading(context, structure, member)$ $LoadArrayPointer_Loading(context, structure, member, reference)$
} }
else else
{ {
$TypeVarName(structure)$->$member.Member.Name$ = m_stream->ConvertOffsetToPointer($TypeVarName(structure)$->$member.Member.Name$); $TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$ = m_stream->ConvertOffsetToPointer($TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$);
} }
$else$ $else$
$LoadArrayPointer_Loading(context, structure, member)$ $LoadArrayPointer_Loading(context, structure, member, reference)$
$endif$ $endif$
} }
>> >>
LoadArrayPointer_Condition(context, structure, member) ::= <% LoadArrayPointer_TypeCheck(context, structure, member, reference) ::= <%
$if(member.Condition)$ $if(member.IsScriptString)$
$if(structure.IsUnion)$ // ScriptString $member.Member.Name$
if($PrintEvaluation(member.Condition)$)$\n$
{$\n$
$LoadArrayPointer_PointerCheck(context, structure, member)$$\n$
}$\n$
$\n$
$else$ $else$
$LoadArrayPointer_PointerCheck(context, structure, member, reference)$
if($PrintEvaluation(member.Condition)$)$\n$
{$\n$
$LoadArrayPointer_PointerCheck(context, structure, member)$$\n$
}$\n$
$\n$
$endif$
$else$
$LoadArrayPointer_PointerCheck(context, structure, member)$$\n$
$\n$
$endif$ $endif$
%> %>
LoadArrayPointer(context, structure, member) ::= <% LoadArrayPointer_Condition(context, structure, member, reference) ::= <<
$if(!member.Computations.ShouldIgnore)$ $if(member.Condition)$$\\$
$LoadArrayPointer_Condition(context, structure, member)$ if($PrintEvaluation(member.Condition)$)
{
$LoadArrayPointer_TypeCheck(context, structure, member, reference)$
}
$else$$\\$
$LoadArrayPointer_TypeCheck(context, structure, member, reference)$$\\$
$endif$ $endif$
>>
LoadArrayPointer(context, structure, member, reference) ::= <%
$LoadArrayPointer_Condition(context, structure, member, reference)$
%> %>

View File

@ -1,2 +1,4 @@
delimiters "$", "$"
// Loading common // Loading common
LoaderClassName(asset) ::= "Loader_$asset.Type.Name$" LoaderClassName(asset) ::= "Loader_$asset.Type.Name$"

View File

@ -1,21 +1,25 @@
delimiters "$", "$"
// Everything related to loading an embedded reference // Everything related to loading an embedded reference
LoadEmbedded_Load(context, structure, member) ::= << LoadEmbedded_Load(context, structure, member, reference) ::= <<
$TypeVarName(member.StructureType)$ = &$TypeVarName(structure)$->$member.Member.Name$; $TypeVarName(member.StructureType)$ = &$TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$;
Load_$member.Member.VariableType.Type.Name$(false); Load_$member.Member.VariableType.Type.Name$(false);
>> >>
LoadEmbedded_Array(context, structure, member) ::= << LoadEmbedded_TypeCheck(context, structure, member, reference) ::= <%
$if(member.IsScriptString)$
>> $TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$ = UseScriptString($TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$);
LoadEmbedded(context, structure, member) ::= <%
$if(!member.Computations.ShouldIgnore)$
$if(member.Computations.IsArray)$
$LoadEmbedded_Array(context, structure, member)$
$else$ $else$
$LoadEmbedded_Load(context, structure, member)$ $LoadEmbedded_Load(context, structure, member, reference)$
$endif$
$endif$ $endif$
%> %>
LoadEmbedded(context, structure, member, reference) ::= <%
$LoadEmbedded_TypeCheck(context, structure, member, reference)$
%>
LoadEmbeddedArray(context, structure, member, reference) ::= <<
$TypeVarName(member.StructureType)$ = $TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$;
LoadArray_$member.Member.VariableType.Type.Name$(false, $reference.ArraySize$); // ASDF
>>

View File

@ -0,0 +1,45 @@
delimiters "$", "$"
LoadPointerArray_Loading(context, structure, member, reference) ::= <%
$if(member.Computations.IsArray)$
$TypePtrVarName(member.Member.VariableType)$ = $TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$;$\n$
LoadPtrArray_$SafeTypeName(member.Member.VariableType.Type)$(false, $reference.ArraySize$);
$else$
$TypePtrVarName(member.Member.VariableType)$ = $TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$;$\n$
LoadPtrArray_$SafeTypeName(member.Member.VariableType.Type)$(true, $PrintEvaluation(reference.ArrayPointerCountEvaluation)$);
$endif$
%>
LoadPointerArray_String(context, structure, member, reference) ::= <%
$if(reference.IsArray)$
varXString = $TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$;$\n$
LoadXStringArray(false, $reference.ArraySize$);
$else$
$TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$ = m_stream->Alloc<$TypeDeclaration(member.Member.VariableType)$$PrintFollowingReferences(reference.FollowingReferences)$>(alignof($TypeDeclaration(member.Member.VariableType)$$PrintFollowingReferences(reference.FollowingReferences)$));$\n$
varXString = $TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$;$\n$
LoadXStringArray(true, $PrintEvaluation(reference.ArrayPointerCountEvaluation)$);
$endif$
%>
LoadPointerArray_TypeCheck(context, structure, member, reference) ::= <%
$if(member.IsString)$
$LoadPointerArray_String(context, structure, member, reference)$
$else$
$LoadPointerArray_Loading(context, structure, member, reference)$
$endif$
%>
LoadPointerArray_Condition(context, structure, member, reference) ::= <<
$if(member.Condition)$$\\$
if($PrintEvaluation(member.Condition)$)
{
$LoadPointerArray_TypeCheck(context, structure, member, reference)$
}
$else$$\\$
$LoadPointerArray_TypeCheck(context, structure, member, reference)$$\\$
$endif$
>>
LoadPointerArray(context, structure, member, reference) ::= <%
$LoadPointerArray_Condition(context, structure, member, reference)$
%>

View File

@ -1,62 +1,78 @@
delimiters "$", "$"
// Everything related to loading a pointer with a count that is statically 1 // Everything related to loading a pointer with a count that is statically 1
LoadSinglePointerInner(context, structure, member) ::= << LoadSinglePointerInner(context, structure, member, reference) ::= <%
$TypeVarName(structure)$->$member.Member.Name$ = m_stream->Alloc<$TypeDeclaration(member.Member.VariableType)$>(alignof($TypeDeclaration(member.Member.VariableType)$)); $TypeVarName(structure)$->$member.Member.Name$ = m_stream->Alloc<$TypeDeclaration(member.Member.VariableType)$$PrintFollowingReferences(reference.FollowingReferences)$>(alignof($TypeDeclaration(member.Member.VariableType)$$PrintFollowingReferences(reference.FollowingReferences)$));$\n$
$if(member.StructureType && !member.StructureType.IsLeaf)$ $if(member.StructureType && !member.StructureType.IsLeaf)$
$TypeVarName(member.StructureType)$ = $TypeVarName(structure)$->$member.Member.Name$;
$TypeVarName(member.StructureType)$ = $TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$;$\n$
Load_$member.Member.VariableType.Type.Name$(true); Load_$member.Member.VariableType.Type.Name$(true);
$else$ $else$
m_stream->Load<$TypeDeclaration(member.Member.VariableType)$>($TypeVarName(structure)$->$member.Member.Name$);$endif$
>>
LoadSinglePointerAsset(context, structure, member) ::= << m_stream->Load<$TypeDeclaration(member.Member.VariableType)$$PrintFollowingReferences(reference.FollowingReferences)$>($TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$);
$endif$
%>
LoadSinglePointerAsset(context, structure, member, reference) ::= <<
$LoaderClassName(member.StructureType)$ loader(m_script_string_provider, m_zone, m_stream); $LoaderClassName(member.StructureType)$ loader(m_script_string_provider, m_zone, m_stream);
loader.Load(&$TypeVarName(structure)$->$member.Member.Name$); loader.Load(&$TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$);
>> >>
LoadSinglePointer_PointerCheck(context, structure, member) ::= << LoadSinglePointer_PointerCheck(context, structure, member, reference) ::= <<
if ($TypeVarName(structure)$->$member.Member.Name$) if ($TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$)
{ {
$if(member.StructureType && member.StructureType.IsAsset)$ $if(member.StructureType && member.StructureType.IsAsset)$
$LoadSinglePointerAsset(context, structure, member)$ $LoadSinglePointerAsset(context, structure, member, reference)$
$else$ $else$
$if(member.IsReusable)$ $if(member.IsReusable)$
if($TypeVarName(structure)$->$member.Member.Name$ == PTR_FOLLOWING) if($TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$ == PTR_FOLLOWING)
{ {
$LoadSinglePointerInner(context, structure, member)$ $LoadSinglePointerInner(context, structure, member, reference)$
} }
else else
{ {
$TypeVarName(structure)$->$member.Member.Name$ = m_stream->ConvertOffsetToPointer($TypeVarName(structure)$->$member.Member.Name$); $TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$ = m_stream->ConvertOffsetToPointer($TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$);
} }
$else$ $else$
$LoadSinglePointerInner(context, structure, member)$ $LoadSinglePointerInner(context, structure, member, reference)$
$endif$ $endif$
$endif$ $endif$
} }
>> >>
LoadSinglePointer_Condition(context, structure, member) ::= <% LoadSinglePointer_String(context, structure, member, reference) ::= <%
$if(member.Condition)$ varXString = &$TypeVarName(structure)$->$member.Member.Name$$PrintArrayIndices(reference)$;$\n$
LoadXString(false);
if($PrintEvaluation(member.Condition)$)$\n$ %>
{$\n$
$LoadSinglePointer_PointerCheck(context, structure, member)$$\n$
}$\n$
$\n$
LoadSinglePointer_TypeCheck(context, structure, member, reference) ::= <%
$if(member.IsString)$
$LoadSinglePointer_String(context, structure, member, reference)$
$elseif(member.IsScriptString)$
// ScriptString $member.Member.Name$
$else$ $else$
$LoadSinglePointer_PointerCheck(context, structure, member, reference)$
$LoadSinglePointer_PointerCheck(context, structure, member)$$\n$
$\n$
$endif$ $endif$
%> %>
LoadSinglePointer(context, structure, member) ::= <% LoadSinglePointer_Condition(context, structure, member, reference) ::= <<
$if(!member.Computations.ShouldIgnore)$ $if(member.Condition)$
$if(!member.Computations.IsArray && member.Computations.PointerDepthIsOne)$$! TODO: FIX ARRAYS !$ if($PrintEvaluation(member.Condition)$)
$LoadSinglePointer_Condition(context, structure, member)$ {
$LoadSinglePointer_TypeCheck(context, structure, member, reference)$
}
$if(structure.IsUnion)$
return;
$endif$ $endif$
$else$$\\$
$LoadSinglePointer_TypeCheck(context, structure, member, reference)$$\\$
$endif$ $endif$
>>
LoadSinglePointer(context, structure, member, reference) ::= <%
$LoadSinglePointer_Condition(context, structure, member, reference)$
%> %>

View File

@ -1,30 +0,0 @@
// String
LoadStringSingleDepth(context, structure, member) ::= <%
$if(!member.Computations.IsArray)$
varXString = &$TypeVarName(structure)$->$member.Member.Name$;$\n$
LoadXString(false);$\n$
$else$
varXString = $TypeVarName(structure)$->$member.Member.Name$;$\n$
LoadXStringArray(false, $first(member.Computations.ArraySizes)$);$\n$
$endif$
%>
LoadString_PointerCheck(context, structure, member) ::= <<
if ($TypeVarName(structure)$->$member.Member.Name$)
{
$TypeVarName(structure)$->$member.Member.Name$ = m_stream->Alloc<$TypeDeclaration(member.Member.VariableType)$*>(alignof($TypeDeclaration(member.Member.VariableType)$*));
varXString = $TypeVarName(structure)$->$member.Member.Name$;
LoadXStringArray(true, $PrintEvaluation(member.Computations.ArrayPointerCountEvaluation)$);
}
>>
LoadString(context, structure, member) ::= <%
$if(member.Computations.PointerDepthIsOne)$
$LoadStringSingleDepth(context, structure, member)$
$elseif(member.Computations.PointerDepthIsTwo && member.Computations.ArrayPointerCountEvaluation)$
$LoadString_PointerCheck(context, structure, member)$
$else$
#error Cannot load string $member.Member.Name$
$endif$
%>

View File

@ -3,10 +3,10 @@ delimiters "$", "$"
import "Common.stg" import "Common.stg"
import "Loading/Common.stg" import "Loading/Common.stg"
import "Loading/String.stg"
import "Loading/ArrayPointer.stg" import "Loading/ArrayPointer.stg"
import "Loading/Embedded.stg" import "Loading/Embedded.stg"
import "Loading/SinglePointer.stg" import "Loading/SinglePointer.stg"
import "Loading/PointerArray.stg"
// Loading common // Loading common
LoaderClassName(asset) ::= "Loader_$asset.Type.Name$" LoaderClassName(asset) ::= "Loader_$asset.Type.Name$"
@ -14,7 +14,8 @@ LoaderClassName(asset) ::= "Loader_$asset.Type.Name$"
HeaderConstructor(context) ::= "$LoaderClassName(context.Asset)$(IZoneScriptStringProvider* scriptStringProvider, Zone* zone, IZoneInputStream* stream);" HeaderConstructor(context) ::= "$LoaderClassName(context.Asset)$(IZoneScriptStringProvider* scriptStringProvider, Zone* zone, IZoneInputStream* stream);"
HeaderSinglePtrLoadMethodDeclaration(structure) ::= "void LoadPtr_$structure.Type.Name$(bool atStreamStart);" HeaderSinglePtrLoadMethodDeclaration(structure) ::= "void LoadPtr_$structure.Type.Name$(bool atStreamStart);"
HeaderArrayPtrLoadMethodDeclaration(structure) ::= "void LoadArray_$structure.Type.Name$(bool atStreamStart, size_t count);" HeaderArrayLoadMethodDeclaration(structure) ::= "void LoadArray_$structure.Type.Name$(bool atStreamStart, size_t count);"
HeaderPtrArrayLoadMethodDeclaration(type) ::= "void LoadPtrArray_$SafeTypeName(type)$(bool atStreamStart, size_t count);"
HeaderLoadMethodDeclaration(structure) ::= "void Load_$structure.Type.Name$(bool atStreamStart);" HeaderLoadMethodDeclaration(structure) ::= "void Load_$structure.Type.Name$(bool atStreamStart);"
HeaderGetNameMethodDeclaration(asset) ::= "static std::string GetAssetName($asset.Type.FullName$* pAsset);" HeaderGetNameMethodDeclaration(asset) ::= "static std::string GetAssetName($asset.Type.FullName$* pAsset);"
@ -22,26 +23,24 @@ HeaderAssetLoadMethodDeclaration(asset) ::= "void LoadAsset_$asset.Type.Name$($a
HeaderMainLoadMethodDeclaration(asset) ::= "void Load($asset.Type.FullName$** pAsset);" HeaderMainLoadMethodDeclaration(asset) ::= "void Load($asset.Type.FullName$** pAsset);"
VariableDeclaration(type) ::= << VariableDeclaration(type) ::= <<
$type.FullName$* var$type.Name$; $type.FullName$* var$SafeTypeName(type)$;
>> >>
PointerVariableDeclaration(type) ::= << PointerVariableDeclaration(type) ::= <<
$type.FullName$** var$type.Name$Ptr; $type.FullName$** var$SafeTypeName(type)$Ptr;
>> >>
HeaderDeclaration(structure) ::= <% HeaderMethodDeclarations(usedType) ::= <%
$if(structure.SinglePointerReferenceExists)$ $if(usedType.PointerArrayReferenceExists)$
$HeaderSinglePtrLoadMethodDeclaration(structure)$ $HeaderPtrArrayLoadMethodDeclaration(usedType.Type)$
$\n$ $\n$
$endif$ $endif$
$if(usedType.ArrayReferenceExists && usedType.Information && !usedType.Information.IsLeaf)$
$if(structure.ArrayPointerReferenceExists && !structure.IsLeaf)$ $HeaderArrayLoadMethodDeclaration(usedType.Information)$
$HeaderArrayPtrLoadMethodDeclaration(structure)$
$\n$ $\n$
$endif$ $endif$
$if(usedType.Information && !usedType.Information.IsLeaf && !usedType.Information.IsAsset)$
$if(!structure.IsLeaf && structure.Computations.IsUsed)$ $HeaderLoadMethodDeclaration(usedType.Information)$
$HeaderLoadMethodDeclaration(structure)$
$\n$ $\n$
$endif$ $endif$
%> %>
@ -68,11 +67,13 @@ namespace $context.Game$
{ {
$VariableDeclaration(context.Asset.Type)$ $VariableDeclaration(context.Asset.Type)$
$PointerVariableDeclaration(context.Asset.Type)$ $PointerVariableDeclaration(context.Asset.Type)$
$context.MemberTypes:{type | $if(!type.IsAnonymous)$$VariableDeclaration(type)$
$context.UsedTypes:{type | $if(type.Information && !type.Information.Type.IsAnonymous && !type.Information.IsLeaf && !type.Information.IsAsset)$$VariableDeclaration(type.Type)$
$endif$}$ $endif$}$
$context.Structures:{structure | $if(!structure.IsAsset && structure.SinglePointerReferenceExists)$$PointerVariableDeclaration(structure.Type)$ $context.UsedTypes:{type | $if(type.PointerArrayReferenceExists && !type.IsContextAsset)$$PointerVariableDeclaration(type.Type)$
$endif$}$ $endif$}$$\\$
$context.Structures:{structure | $if(!structure.IsAsset)$$HeaderDeclaration(structure)$$endif$}$
$context.UsedTypes:{usedType | $HeaderMethodDeclarations(usedType)$}$
$HeaderLoadMethodDeclaration(context.Asset)$ $HeaderLoadMethodDeclaration(context.Asset)$
$HeaderSinglePtrLoadMethodDeclaration(context.Asset)$ $HeaderSinglePtrLoadMethodDeclaration(context.Asset)$
$HeaderAssetLoadMethodDeclaration(context.Asset)$ $HeaderAssetLoadMethodDeclaration(context.Asset)$
@ -89,41 +90,43 @@ LoadMember(context, member) ::= <<
Loading member $member.Member.Name$ Loading member $member.Member.Name$
>> >>
LoadMemberReference(context, structure, member, reference) ::= <%
LoadMemberIfNeedsTreatment(context, structure, member) ::= <% $if(reference.IsSinglePointer)$
$if(member.IsString)$ $\n$$\n$
$LoadString(context, structure, member)$ $LoadSinglePointer(context, structure, member, reference)$
$elseif(member.IsScriptString)$ $elseif(reference.IsArrayPointer)$
// Load scriptstring for $member.Member.Name$ $\n$$\n$
$elseif(member.Computations.IsArrayPointerReference && member.Computations.PointerDepthIsOne)$ $LoadArrayPointer(context, structure, member, reference)$
$LoadArrayPointer(context, structure, member)$ $elseif(reference.IsPointerArray)$
$elseif(member.Computations.IsSinglePointerReference)$ $\n$$\n$
$LoadSinglePointer(context, structure, member)$ $LoadPointerArray(context, structure, member, reference)$
$elseif(member.Computations.IsEmbeddedReference && member.StructureType && !member.StructureType.IsLeaf)$ $elseif(reference.IsArray && !reference.NextReference)$
$LoadEmbedded(context, structure, member)$ $\n$$\n$
$LoadEmbeddedArray(context, structure, member, reference)$
$elseif(!reference.Reference)$
$\n$$\n$
$LoadEmbedded(context, structure, member, reference)$
$else$
$\n$$\n$
// $member.Member.Name$
$endif$ $endif$
%> %>
LoadMethod(structure, context) ::= << LoadMemberIfNeedsTreatment(context, structure, member) ::= <%
void $LoaderClassName(context.Asset)$::Load_$structure.Type.Name$(const bool atStreamStart) $if(!member.Computations.ShouldIgnore)$
{
assert($TypeVarName(structure)$ != nullptr);
if(atStreamStart) $if(member.IsString || member.IsScriptString)$
m_stream->Load<$structure.Type.FullName$>($TypeVarName(structure)$); $LoadMemberReference(context, structure, member, member.Computations.References)$
$if(structure.Block.IsTemp)$ $elseif(member.Computations.ContainsNonEmbeddedReference)$
$LoadMemberReference(context, structure, member, member.Computations.References)$
m_stream->PushBlock($context.DefaultNormalBlock.Name$); $elseif(member.StructureType && !member.StructureType.IsLeaf)$
$LoadMemberReference(context, structure, member, member.Computations.References)$
$endif$ $endif$
$structure.OrderedMembers:{member | $LoadMemberIfNeedsTreatment(context, structure, member)$}$
$if(structure.Block.IsTemp)$
m_stream->PopBlock();
$endif$ $endif$
} %>
>>
LoadSinglePtrMethod(structure, context) ::= << LoadSinglePtrMethod(context, structure) ::= <<
void $LoaderClassName(context.Asset)$::LoadPtr_$structure.Type.Name$(const bool atStreamStart) void $LoaderClassName(context.Asset)$::LoadPtr_$structure.Type.Name$(const bool atStreamStart)
{ {
assert($TypePtrVarName(structure)$ != nullptr); assert($TypePtrVarName(structure)$ != nullptr);
@ -177,7 +180,14 @@ void $LoaderClassName(context.Asset)$::LoadPtr_$structure.Type.Name$(const bool
} }
>> >>
LoadArrayPtrMethod(structure, context) ::= << LoadPointerArrayMethod(context, type, structure) ::= <<
void $LoaderClassName(context.Asset)$::LoadPtrArray_$SafeTypeName(type)$(const bool atStreamStart, const size_t count)
{
}
>>
LoadArrayMethod(context, structure) ::= <<
void $LoaderClassName(context.Asset)$::LoadArray_$structure.Type.Name$(const bool atStreamStart, const size_t count) void $LoaderClassName(context.Asset)$::LoadArray_$structure.Type.Name$(const bool atStreamStart, const size_t count)
{ {
assert($TypeVarName(structure)$ != nullptr); assert($TypeVarName(structure)$ != nullptr);
@ -193,21 +203,40 @@ void $LoaderClassName(context.Asset)$::LoadArray_$structure.Type.Name$(const boo
} }
>> >>
SourceDefinition(structure, context) ::= << LoadMethod(context, structure) ::= <<
$if(structure.SinglePointerReferenceExists)$ void $LoaderClassName(context.Asset)$::Load_$structure.Type.Name$(const bool atStreamStart)
$LoadSinglePtrMethod(structure, context)$ {
assert($TypeVarName(structure)$ != nullptr);
$endif$ if(atStreamStart)
$if(structure.ArrayPointerReferenceExists && !structure.IsLeaf)$ m_stream->Load<$structure.Type.FullName$>($TypeVarName(structure)$);$\\$
$LoadArrayPtrMethod(structure, context)$ $if(structure.Block.IsTemp)$
m_stream->PushBlock($context.DefaultNormalBlock.Name$);$\\$
$endif$ $endif$
$if(!structure.IsLeaf && structure.Computations.IsUsed)$ $structure.OrderedMembers:{member | $LoadMemberIfNeedsTreatment(context, structure, member)$}$
$LoadMethod(structure, context)$ $if(structure.Block.IsTemp)$
m_stream->PopBlock();
$endif$ $endif$
}
>> >>
SourceDefinition(context, usedType) ::= <%
$if(usedType.PointerArrayReferenceExists)$
$LoadPointerArrayMethod(context, usedType.Type, usedType.Information)$
$\n$$\n$
$endif$
$if(usedType.ArrayReferenceExists && usedType.Information && !usedType.Information.IsLeaf)$
$LoadArrayMethod(context, usedType.Information)$
$\n$$\n$
$endif$
$if(usedType.Information && !usedType.Information.IsLeaf && !usedType.Information.IsAsset)$
$LoadMethod(context, usedType.Information)$
$\n$$\n$
$endif$
%>
VariableInitialization(type) ::= << VariableInitialization(type) ::= <<
var$type.Name$ = nullptr; var$type.Name$ = nullptr;
>> >>
@ -222,14 +251,15 @@ $LoaderClassName(context.Asset)$::$LoaderClassName(context.Asset)$(IZoneScriptSt
{ {
$VariableInitialization(context.Asset.Type)$ $VariableInitialization(context.Asset.Type)$
$PointerVariableInitialization(context.Asset.Type)$ $PointerVariableInitialization(context.Asset.Type)$
$context.MemberTypes:{type | $if(!type.IsAnonymous)$$VariableInitialization(type)$
$endif$}$ $context.UsedTypes:{type | $if(type.Information && !type.Information.Type.IsAnonymous && !type.Information.IsLeaf && !type.Information.IsAsset)$$VariableInitialization(type.Type)$
$context.Structures:{structure | $if(!structure.IsAsset && structure.SinglePointerReferenceExists)$$PointerVariableInitialization(structure.Type)$
$endif$}$ $endif$}$
$context.UsedTypes:{type | $if(type.Information && type.PointerArrayReferenceExists && !type.IsContextAsset)$$PointerVariableInitialization(type.Type)$
$endif$}$$\\$
} }
>> >>
LoadAssetMethod(structure, context) ::= << LoadAssetMethod(context, structure) ::= <<
void $LoaderClassName(context.Asset)$::LoadAsset_$structure.Type.Name$($structure.Type.FullName$** pAsset) void $LoaderClassName(context.Asset)$::LoadAsset_$structure.Type.Name$($structure.Type.FullName$** pAsset)
{ {
assert(pAsset != nullptr); assert(pAsset != nullptr);
@ -283,12 +313,12 @@ using namespace $context.Game$;
$ConstructorMethod(context)$ $ConstructorMethod(context)$
$context.Structures:{structure | $if(!structure.IsAsset)$$SourceDefinition(structure, context)$$endif$}$ $context.UsedTypes:{usedType | $SourceDefinition(context, usedType)$}$
$LoadMethod(context.Asset, context)$ $LoadMethod(context, context.Asset)$
$LoadAssetMethod(context.Asset, context)$ $LoadSinglePtrMethod(context, context.Asset)$
$LoadSinglePtrMethod(context.Asset, context)$ $LoadAssetMethod(context, context.Asset)$
$MainLoadMethod(context)$ $MainLoadMethod(context)$

View File

@ -27,16 +27,16 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.PostProcessor
.Where(member => member.StructureType != null) .Where(member => member.StructureType != null)
.Where(member => !member.Computations.ShouldIgnore)) .Where(member => !member.Computations.ShouldIgnore))
{ {
if (member.Computations.IsNonEmbeddedReference) if (member.Computations.ContainsNonEmbeddedReference)
member.StructureType.NonEmbeddedReferenceExists = true; member.StructureType.NonEmbeddedReferenceExists = true;
if (member.Computations.IsSinglePointerReference) if (member.Computations.ContainsSinglePointerReference)
member.StructureType.SinglePointerReferenceExists = true; member.StructureType.SinglePointerReferenceExists = true;
if (member.Computations.IsArrayPointerReference) if (member.Computations.ContainsArrayPointerReference)
member.StructureType.ArrayPointerReferenceExists = true; member.StructureType.ArrayPointerReferenceExists = true;
if (member.Computations.IsArrayReference) if (member.Computations.ContainsArrayReference)
member.StructureType.ArrayReferenceExists = true; member.StructureType.ArrayReferenceExists = true;
member.StructureType.Usages.Add(currentStructure); member.StructureType.Usages.Add(currentStructure);

View File

@ -50,7 +50,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
for (var i = 0; i < memberList.Count - 1; i++) for (var i = 0; i < memberList.Count - 1; i++)
{ {
if (!memberList[i].Computations.IsEmbeddedReference) if (memberList[i].Computations.ContainsNonEmbeddedReference)
{ {
throw new TestFailedException("Can only add embedded members to name chain."); throw new TestFailedException("Can only add embedded members to name chain.");
} }

View File

@ -52,7 +52,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
var lastMember = memberList.Last(); var lastMember = memberList.Last();
if (!lastMember.Computations.IsNonEmbeddedReference) if (!lastMember.Computations.ContainsNonEmbeddedReference)
{ {
throw new TestFailedException($"Specified member '{lastMember.Member.Name}' is not a pointer reference and therefore cannot be reusable."); throw new TestFailedException($"Specified member '{lastMember.Member.Name}' is not a pointer reference and therefore cannot be reusable.");
} }

View File

@ -56,7 +56,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
throw new TestFailedException($"Specified member '{lastMember.Member.Name}' is not char type and therefore cannot be a string."); throw new TestFailedException($"Specified member '{lastMember.Member.Name}' is not char type and therefore cannot be a string.");
} }
if (!lastMember.Computations.IsSinglePointerReference) if (!lastMember.Computations.ContainsSinglePointerReference)
{ {
throw new TestFailedException($"Specified member '{lastMember.Member.Name}' is a single pointer reference and therefore cannot be a string."); throw new TestFailedException($"Specified member '{lastMember.Member.Name}' is a single pointer reference and therefore cannot be a string.");
} }