ZoneCodeGenerator: Add arraysize test to explicitly override the size of an array with a dynamic one

This commit is contained in:
Jan 2019-11-10 18:07:28 +01:00
parent 76cae3a948
commit 6ca7f18f9f
4 changed files with 100 additions and 11 deletions

View File

@ -136,10 +136,10 @@ set count quat 1;
// XAnimPartTrans
use XAnimPartTrans;
set condition u::frames size > 0;
set condition XAnimParts::deltaPart::trans::u::frames::indices::_1 numframes < 256;
set count u::frames::indices::_1 size + 1;
set count u::frames::indices::_2 size + 1;
set condition u::frames::frames::_1 smallTrans == true;
set condition u::frames::indices::_1 XAnimParts::numframes < 256;
set arraysize u::frames::indices::_1 size + 1;
set arraysize u::frames::indices::_2 size + 1;
set condition u::frames::frames::_1 smallTrans;
set count u::frames::frames::_1 size + 1;
set count u::frames::frames::_2 size + 1;
@ -151,9 +151,9 @@ reorder XAnimPartTransFrames:
// XAnimDeltaPartQuat2
use XAnimDeltaPartQuat2;
set condition u::frames size > 0;
set condition XAnimParts::deltaPart::quat2::u::frames::indices::_1 numframes < 256;
set count u::frames::indices::_1 size + 1;
set count u::frames::indices::_2 size + 1;
set condition u::frames::indices::_1 XAnimParts::numframes < 256;
set arraysize u::frames::indices::_1 size + 1;
set arraysize u::frames::indices::_2 size + 1;
set count u::frames::frames size + 1;
// XAnimDeltaPartQuatDataFrames2
@ -164,9 +164,9 @@ reorder XAnimDeltaPartQuatDataFrames2:
// XAnimDeltaPartQuat
use XAnimDeltaPartQuat;
set condition u::frames size > 0;
set condition XAnimParts::deltaPart::quat::u::frames::indices::_1 numframes < 256;
set count u::frames::indices::_1 size + 1;
set count u::frames::indices::_2 size + 1;
set condition u::frames::indices::_1 XAnimParts::numframes < 256;
set arraysize u::frames::indices::_1 size + 1;
set arraysize u::frames::indices::_2 size + 1;
set count u::frames::frames size + 1;
// =========================================

View File

@ -1,12 +1,17 @@
namespace ZoneCodeGenerator.Domain
using ZoneCodeGenerator.Domain.Evaluation;
namespace ZoneCodeGenerator.Domain
{
class ReferenceTypeArray : ReferenceType
{
public int ArraySize { get; }
public IEvaluation DynamicSize { get; set; }
public ReferenceTypeArray(int arraySize)
{
ArraySize = arraySize;
DynamicSize = null;
}
}
}

View File

@ -14,6 +14,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Impl
class CommandParserState : ICommandParserState
{
private static readonly ITokenTest<ICommandParserState>[] tests = {
new TestArraySize(),
new TestAsset(),
new TestBlock(),
new TestCondition(),

View File

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ZoneCodeGenerator.Domain;
using ZoneCodeGenerator.Domain.Information;
using ZoneCodeGenerator.Parsing.Matching;
using ZoneCodeGenerator.Parsing.Matching.Matchers;
using ZoneCodeGenerator.Parsing.Testing;
namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
{
class TestArraySize : TestWithEvaluation
{
private StructureInformation referencedType;
private const string TypeNameToken = "typeName";
// set count <typename> <calculationStatement>;
private static readonly TokenMatcher[] matchers =
{
new MatcherLiteral("set"),
new MatcherLiteral("arraysize"),
new MatcherTypename().WithName(TypeNameToken),
new MatcherWithTag(TagEvaluation),
new MatcherLiteral(";")
};
public TestArraySize() : base(matchers)
{
}
protected override void ProcessMatch(ICommandParserState state)
{
var typeName = NextMatch(TypeNameToken);
var typeNameParts = typeName.Split(new[] { "::" }, StringSplitOptions.None);
if (state.DataTypeInUse != null
&& state.GetMembersFromParts(typeNameParts, state.DataTypeInUse, out var typeMembers))
{
referencedType = state.DataTypeInUse;
}
else if (state.GetTypenameAndMembersFromParts(typeNameParts, out referencedType, out typeMembers))
{
// Do nothing
}
else
{
throw new TestFailedException($"Could not find type/members '{typeName}'");
}
if (typeMembers == null
|| !typeMembers.Any())
{
throw new TestFailedException("Can only set array size for members and not for types.");
}
if (!NextTag().Equals(TagEvaluation))
throw new Exception("Expected first array size tag to be a calculation statement");
var evaluation = ProcessEvaluation(state);
var referencedMember = typeMembers.Last();
var reference = referencedMember.Member.VariableType.References.OfType<ReferenceTypeArray>()
.FirstOrDefault();
if (reference != null)
reference.DynamicSize = evaluation;
else
throw new TestFailedException(
$"Member '{referencedMember.Member.Name}' of type '{referencedMember.Member.VariableType.Type.FullName}' cannot have its array size set due to it not having an array reference");
}
protected override IEnumerable<StructureInformation> GetUsedTypes(ICommandParserState state)
{
if (state.DataTypeInUse != null
&& state.DataTypeInUse != referencedType)
{
return new[] { state.DataTypeInUse, referencedType };
}
return new[] { referencedType };
}
}
}