mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 00:02:55 +00:00
105 lines
4.5 KiB
C#
105 lines
4.5 KiB
C#
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;
|
|
private readonly int combinedIndex;
|
|
|
|
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 bool HasDynamicArrayCount => Reference is ReferenceTypeArray array && array.DynamicCount != null;
|
|
|
|
public IEvaluation DynamicArrayCountEvaluation =>
|
|
Reference is ReferenceTypeArray array ? array.DynamicCount : null;
|
|
|
|
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(combinedIndex)
|
|
&& !FollowingReferences.OfType<ReferenceTypePointer>().Any();
|
|
|
|
public bool IsArrayPointer => Reference is ReferenceTypePointer referenceTypePointer
|
|
&& referenceTypePointer.IsArray(combinedIndex)
|
|
&& !FollowingReferences.OfType<ReferenceTypePointer>().Any();
|
|
|
|
public IEvaluation ArrayPointerCountEvaluation
|
|
{
|
|
get
|
|
{
|
|
if (!(Reference is ReferenceTypePointer pointer))
|
|
return null;
|
|
|
|
return pointer.HasCountByArrayIndex ? pointer.CountByArrayIndex[combinedIndex] : pointer.Count;
|
|
}
|
|
}
|
|
|
|
public bool IsPointerArray =>
|
|
(Reference is ReferenceTypePointer referenceTypePointer && referenceTypePointer.IsArray(combinedIndex) ||
|
|
Reference is ReferenceTypeArray)
|
|
&& NextReference is ReferenceTypePointer nextReferencePointer &&
|
|
!nextReferencePointer.IsArray(combinedIndex);
|
|
|
|
public IEvaluation PointerArrayCountEvaluation => NextReference is ReferenceTypePointer referenceTypePointer
|
|
? referenceTypePointer.Count
|
|
: null;
|
|
|
|
public bool IsDynamicArray =>
|
|
Reference is ReferenceTypeArray referenceTypeArray && referenceTypeArray.DynamicSize != null;
|
|
|
|
public IEvaluation DynamicArraySizeEvaluation => Reference is ReferenceTypeArray referenceTypeArray
|
|
? referenceTypeArray.DynamicSize
|
|
: null;
|
|
|
|
public MemberReferenceComputations(MemberInformation information)
|
|
{
|
|
this.information = information;
|
|
referenceIndices = new List<int>();
|
|
combinedIndex = 0;
|
|
}
|
|
|
|
private MemberReferenceComputations(MemberInformation information, IEnumerable<int> referenceIndices)
|
|
{
|
|
this.information = information;
|
|
this.referenceIndices = new List<int>(referenceIndices);
|
|
|
|
var arraySizes = information.Member.VariableType.References
|
|
.OfType<ReferenceTypeArray>()
|
|
.Select(array => array.ArraySize)
|
|
.ToList();
|
|
var indexDepth = 0;
|
|
combinedIndex = 0;
|
|
foreach (var referenceIndex in this.referenceIndices)
|
|
{
|
|
var sizePerIndexInCurrentDepth = arraySizes.Count <= indexDepth + 1
|
|
? 1
|
|
: arraySizes.Skip(indexDepth + 1).Aggregate((i1, i2) => i1 * i2);
|
|
|
|
combinedIndex += referenceIndex * sizePerIndexInCurrentDepth;
|
|
indexDepth++;
|
|
}
|
|
}
|
|
}
|
|
} |