2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-09-03 23:37:26 +00:00

ZoneCodeGenerator: Make unions work with conditions and only load one union member at a time consistently

This commit is contained in:
Jan
2019-12-06 16:33:05 +01:00
parent f4a2639e30
commit 9253ac14fa
9 changed files with 196 additions and 17 deletions

View File

@@ -14,7 +14,9 @@ namespace ZoneCodeGenerator.Parsing.CommandFile
private static readonly IDataPostProcessor[] postProcessors =
{
new PostProcessorUsages(),
new PostProcessorLeafs()
new PostProcessorLeafs(),
new PostProcessorMemberLeafs(),
new PostProcessorUnions(),
};
public static bool ReadFile(string path, CUISession session, bool verbose = false)

View File

@@ -7,7 +7,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.PostProcessor
{
class PostProcessorLeafs : IDataPostProcessor
{
private static bool IsLeaf(StructureInformation structureInformation)
public static bool IsLeaf(StructureInformation structureInformation)
{
foreach (var member in structureInformation.OrderedMembers)
{

View File

@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ZoneCodeGenerator.Domain;
using ZoneCodeGenerator.Domain.Information;
using ZoneCodeGenerator.Persistence;
namespace ZoneCodeGenerator.Parsing.CommandFile.PostProcessor
{
class PostProcessorMemberLeafs : IDataPostProcessor
{
private static bool MemberIsLeaf(MemberInformation member)
{
if (member.IsString || member.IsScriptString)
return false;
if (member.StructureType != null && !member.StructureType.IsLeaf)
return false;
// If there are any Pointer members that are not always count 0 it needs to be processed.
var hasNoPointerMembers = member.Member.VariableType.References.OfType<ReferenceTypePointer>().All(pointer =>
{
if (!pointer.Count.IsStatic)
return false;
return pointer.Count.EvaluateNumeric() == 0;
});
if (!hasNoPointerMembers)
return false;
return true;
}
private static void ProcessStructureInformation(StructureInformation structure)
{
foreach (var member in structure.OrderedMembers)
{
member.IsLeaf = MemberIsLeaf(member);
}
}
public bool PostProcess(IDataRepository repository)
{
foreach (var structure in repository.GetAllStructs()
.Cast<DataTypeWithMembers>()
.Concat(repository.GetAllUnions())
.Select(repository.GetInformationFor))
{
ProcessStructureInformation(structure);
}
return true;
}
}
}

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ZoneCodeGenerator.Domain;
using ZoneCodeGenerator.Domain.Information;
using ZoneCodeGenerator.Persistence;
namespace ZoneCodeGenerator.Parsing.CommandFile.PostProcessor
{
class PostProcessorUnions : IDataPostProcessor
{
private static bool ProcessUnion(StructureInformation unionInformation)
{
var entriesWithoutConditionCount =
unionInformation.OrderedMembers.Count(member => member.Condition == null && !member.IsLeaf);
if (entriesWithoutConditionCount > 1 && unionInformation.Usages.Any() && !unionInformation.IsLeaf)
{
Console.WriteLine($"Union '{unionInformation.Type.FullName}' has more than one entry without a condition!");
return false;
}
else if (entriesWithoutConditionCount == 1)
{
// If there is only one entry without condition make it the last of the ordered members
var entryWithoutCondition = unionInformation.OrderedMembers.First(information => information.Condition == null);
unionInformation.OrderedMembers.Remove(entryWithoutCondition);
unionInformation.OrderedMembers.Insert(unionInformation.OrderedMembers.Count, entryWithoutCondition);
}
return true;
}
public bool PostProcess(IDataRepository repository)
{
return repository.GetAllUnions()
.Select(repository.GetInformationFor)
.All(ProcessUnion);
}
}
}