Code Reformat

This commit is contained in:
Samuele Lorefice
2025-03-11 19:09:47 +01:00
parent 0fee1f10d2
commit 3756f864ed

View File

@@ -9,7 +9,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using Kaitai; using Kaitai;
using static Kaitai.BlendFile; using static Kaitai.BlendFile;
using Microsoft.CSharp; using Microsoft.CSharp;
// ReSharper disable BitwiseOperatorOnEnumWithoutFlags // ReSharper disable BitwiseOperatorOnEnumWithoutFlags
@@ -25,26 +25,28 @@ namespace CodeGenerator {
private const string OutPath = @"GeneratedOutput"; private const string OutPath = @"GeneratedOutput";
private const string Namespace = "BlendFile"; private const string Namespace = "BlendFile";
private static HashSet<string> _customTypes; private static HashSet<string> _customTypes;
private static readonly string[] ListMarkerStr = {"list", "array"}; private static readonly string[] ListMarkerStr = { "list", "array" };
private static readonly string[] ListLenghtStr = {"num", "len", "size"}; private static readonly string[] ListLenghtStr = { "num", "len", "size" };
private static ConcurrentQueue<Tuple<string, LogType>> _logQueue = new(); private static ConcurrentQueue<Tuple<string, LogType>> _logQueue = new();
enum LogType { enum LogType {
Info, Info,
Warning, Warning,
Error Error
} }
private static void LogNow(string message, LogType type = LogType.Info) { private static void LogNow(string message, LogType type = LogType.Info) {
string msg = $"{DateTime.Now:yy-MM-dd HH:mm:ss}|{type.ToString()}|{message}"; string msg = $"{DateTime.Now:yy-MM-dd HH:mm:ss}|{type.ToString()}|{message}";
lock (Sb){ Sb.AppendLine(msg); } lock (Sb) {
Sb.AppendLine(msg);
}
Console.WriteLine(msg); Console.WriteLine(msg);
} }
private static void Log(string message, LogType type = LogType.Info) { private static void Log(string message, LogType type = LogType.Info) {
_logQueue.Enqueue(new (message, type)); _logQueue.Enqueue(new(message, type));
} }
public static void Main(string[] args) { public static void Main(string[] args) {
@@ -52,27 +54,28 @@ namespace CodeGenerator {
Stopwatch sw = new(); Stopwatch sw = new();
sw.Start(); sw.Start();
long start = 0; long start = 0;
bool loggerExit = false; bool loggerExit = false;
Thread logger = new(() => { Thread logger = new(() =>
{
start = sw.ElapsedTicks; start = sw.ElapsedTicks;
LogNow($"Logger started! In {sw.ElapsedMilliseconds}ms"); LogNow($"Logger started! In {sw.ElapsedMilliseconds}ms");
// ReSharper disable once AccessToModifiedClosure LoopVariableIsNeverChangedInsideLoop // ReSharper disable once AccessToModifiedClosure LoopVariableIsNeverChangedInsideLoop
while (!loggerExit || !_logQueue.IsEmpty) while (!loggerExit || !_logQueue.IsEmpty)
if (_logQueue.TryDequeue(out var msg)) if (_logQueue.TryDequeue(out var msg))
LogNow(msg.Item1, msg.Item2); LogNow(msg.Item1, msg.Item2);
LogNow("Logger exiting..."); LogNow("Logger exiting...");
}); });
logger.Start(); logger.Start();
var initTime = sw.ElapsedTicks; var initTime = sw.ElapsedTicks;
Log("Reading blend file"); Log("Reading blend file");
sw.Restart(); sw.Restart();
ReadBlendFile(); ReadBlendFile();
var readTime = sw.ElapsedTicks; var readTime = sw.ElapsedTicks;
Log("Generating C# code..."); Log("Generating C# code...");
Log("Pass 1: Generating types"); Log("Pass 1: Generating types");
@@ -86,20 +89,21 @@ namespace CodeGenerator {
OutputCodeFiles(rootNs, false); OutputCodeFiles(rootNs, false);
var writeTime = sw.ElapsedTicks; var writeTime = sw.ElapsedTicks;
sw.Stop(); sw.Stop();
Log("Finished generating C# code!"); Log("Finished generating C# code!");
Log($""" Log($"""
Timings: Timings:
Initialization: {(decimal)initTime/ TimeSpan.TicksPerMillisecond,10:N4} ms Initialization: {(decimal)initTime / TimeSpan.TicksPerMillisecond,10:N4} ms
Logger Startup: {(decimal)start / TimeSpan.TicksPerMillisecond,10:N4} ms Logger Startup: {(decimal)start / TimeSpan.TicksPerMillisecond,10:N4} ms
Reading: {(decimal)readTime/ TimeSpan.TicksPerMillisecond,10:N4} ms Reading: {(decimal)readTime / TimeSpan.TicksPerMillisecond,10:N4} ms
Generating: {(decimal)genTime/ TimeSpan.TicksPerMillisecond,10:N4} ms Generating: {(decimal)genTime / TimeSpan.TicksPerMillisecond,10:N4} ms
Writing: {(decimal)writeTime/ TimeSpan.TicksPerMillisecond,10:N4} ms Writing: {(decimal)writeTime / TimeSpan.TicksPerMillisecond,10:N4} ms
---------------------------- ----------------------------
Total: {(decimal)(initTime+readTime+genTime+writeTime) / TimeSpan.TicksPerMillisecond,10:N4} ms Total: {(decimal)(initTime + readTime + genTime + writeTime) / TimeSpan.TicksPerMillisecond,10:N4} ms
"""); """);
loggerExit = true; loggerExit = true;
while(logger.IsAlive) { } while (logger.IsAlive) {
}
Thread.Sleep(1000); Thread.Sleep(1000);
lock (Sb) { lock (Sb) {
File.AppendAllText("Log.txt", Sb.ToString()); File.AppendAllText("Log.txt", Sb.ToString());
@@ -115,8 +119,7 @@ namespace CodeGenerator {
$"DNA1: {_blendfile.SdnaStructs.Count} structures\n"); $"DNA1: {_blendfile.SdnaStructs.Count} structures\n");
} }
private static int AddNormalField(DnaField field, ref CodeTypeDeclaration ctd, int index, int totalSize) private static int AddNormalField(DnaField field, ref CodeTypeDeclaration ctd, int index, int totalSize) {
{
CodeMemberField cmf; CodeMemberField cmf;
string name = field.Name; string name = field.Name;
if (name.Contains("()")) return 0; if (name.Contains("()")) return 0;
@@ -143,8 +146,8 @@ namespace CodeGenerator {
ctd.Members.Add(cmf); ctd.Members.Add(cmf);
return size; return size;
} }
private static int AddListField(ref CodeTypeDeclaration ctd, int totalSize, int index, int listLenghtOffset, private static int AddListField(ref CodeTypeDeclaration ctd, int totalSize, int index, int listLenghtOffset,
DnaField listPointer, DnaField listLength, int sizeIndex) { DnaField listPointer, DnaField listLength, int sizeIndex) {
var cmf = CreateListMemberField(listPointer, listLength); var cmf = CreateListMemberField(listPointer, listLength);
@@ -153,19 +156,19 @@ namespace CodeGenerator {
cmf.CustomAttributes.Add(attribute); cmf.CustomAttributes.Add(attribute);
ctd.Members.Add(cmf); ctd.Members.Add(cmf);
return size; return size;
} }
private static CodeNamespace GenerateTypes(out CodeNamespace additionalNs) { private static CodeNamespace GenerateTypes(out CodeNamespace additionalNs) {
//Initialize the namespaces //Initialize the namespaces
CodeNamespace rootNs = new CodeNamespace(Namespace); CodeNamespace rootNs = new CodeNamespace(Namespace);
CodeNamespace ns = new CodeNamespace(Namespace+".DNA"); CodeNamespace ns = new CodeNamespace(Namespace + ".DNA");
//Fill the attribute types then add them to the namespaces //Fill the attribute types then add them to the namespaces
rootNs.Types.AddRange(GenerateTypeDeclarations()); rootNs.Types.AddRange(GenerateTypeDeclarations());
ns.Imports.Add(new(rootNs.Name)); ns.Imports.Add(new(rootNs.Name));
_customTypes = new(); _customTypes = new();
foreach (var type in _blendfile.SdnaStructs) { foreach (var type in _blendfile.SdnaStructs) {
@@ -174,18 +177,17 @@ namespace CodeGenerator {
//Create a new type declaration //Create a new type declaration
var ctd = new CodeTypeDeclaration(type.Type); var ctd = new CodeTypeDeclaration(type.Type);
ctd.CustomAttributes.Add(new ("DNAClassAttribute", ctd.CustomAttributes.Add(new("DNAClassAttribute",
new CodeAttributeArgument(new CodePrimitiveExpression(type.IdxType)), new CodeAttributeArgument(new CodePrimitiveExpression(type.IdxType)),
new CodeAttributeArgument(new CodePrimitiveExpression(type.Type)) new CodeAttributeArgument(new CodePrimitiveExpression(type.Type))
)); ));
Log($"Generating type from struct {type.Type}"); Log($"Generating type from struct {type.Type}");
if(IsClass(type)) { if (IsClass(type)) {
Log($"Marking {type.Type} as class"); Log($"Marking {type.Type} as class");
ctd.IsClass = true; ctd.IsClass = true;
} } else {
else {
Log($"Marking {type.Type} as struct"); Log($"Marking {type.Type} as struct");
ctd.IsStruct = !ctd.IsClass; ctd.IsStruct = !ctd.IsClass;
} }
@@ -197,14 +199,14 @@ namespace CodeGenerator {
List<DnaField> normalFields; //Fields that are not lists nor lengths of lists List<DnaField> normalFields; //Fields that are not lists nor lengths of lists
List<(DnaField, DnaField)> listFields; //Fields that are lists, and their corresponding length fields List<(DnaField, DnaField)> listFields; //Fields that are lists, and their corresponding length fields
// ReSharper restore InlineOutVariableDeclaration // ReSharper restore InlineOutVariableDeclaration
//filter the fields we want to include in the class minus the lists //filter the fields we want to include in the class minus the lists
FilterFields(type.Fields, out normalFields, out listFields); FilterFields(type.Fields, out normalFields, out listFields);
var totalSize = 0; var totalSize = 0;
Dictionary<string, int> listCountOffsets = new(); Dictionary<string, int> listCountOffsets = new();
//Add the fields to the class //Add the fields to the class
Log($"Fields: {type.Fields.Count}"); Log($"Fields: {type.Fields.Count}");
for (var index = 0; index < type.Fields.Count; index++) { for (var index = 0; index < type.Fields.Count; index++) {
@@ -212,7 +214,7 @@ namespace CodeGenerator {
//Check if the field is a normal field or a list field //Check if the field is a normal field or a list field
if (normalFields.Contains(field) && !listFields.Select(f => f.Item2).Contains(field)) { if (normalFields.Contains(field) && !listFields.Select(f => f.Item2).Contains(field)) {
//check if the field is an array //check if the field is an array
if (field.Name.Contains('[')) if (field.Name.Contains('['))
totalSize += AddArrayField(ref ctd, field, index, totalSize); totalSize += AddArrayField(ref ctd, field, index, totalSize);
else else
totalSize += AddNormalField(field, ref ctd, index, totalSize); totalSize += AddNormalField(field, ref ctd, index, totalSize);
@@ -220,39 +222,42 @@ namespace CodeGenerator {
//Retrieve the list pointer and the list length fields //Retrieve the list pointer and the list length fields
var (listPointer, listLength) = listFields.FirstOrDefault(x => x.Item1 == field); var (listPointer, listLength) = listFields.FirstOrDefault(x => x.Item1 == field);
Log($"Generating list field {listPointer.Name}"); Log($"Generating list field {listPointer.Name}");
//retrieve the offset of the list length field if exists //retrieve the offset of the list length field if exists
listCountOffsets.TryGetValue(listLength.Name.ParseFName(), out int listLenghtOffset); listCountOffsets.TryGetValue(listLength.Name.ParseFName(), out int listLenghtOffset);
//Retrieve the index of the list length field //Retrieve the index of the list length field
int sizeIndex = type.Fields.IndexOf(listLength); int sizeIndex = type.Fields.IndexOf(listLength);
totalSize += AddListField(ref ctd, totalSize, index, listLenghtOffset, listPointer, listLength, sizeIndex); totalSize += AddListField(ref ctd, totalSize, index, listLenghtOffset, listPointer, listLength,
sizeIndex);
} else if (listFields.Select(f => f.Item2).Contains(field)) { } else if (listFields.Select(f => f.Item2).Contains(field)) {
//update the size of the list attribute //update the size of the list attribute
string fName = field.Name.ParseFName(); string fName = field.Name.ParseFName();
//retrieve the name of the list pointer //retrieve the name of the list pointer
string listPointerName = listFields.First(f => f.Item2.Name.ParseFName() == fName).Item1.Name.ParseFName(); string listPointerName =
listFields.First(f => f.Item2.Name.ParseFName() == fName).Item1.Name.ParseFName();
//Try seeing if the list attribute is already present //Try seeing if the list attribute is already present
var x = ctd.Members.OfType<CodeMemberField>().FirstOrDefault(member => member.Name.ParseFName() == listPointerName); var x = ctd.Members.OfType<CodeMemberField>()
.FirstOrDefault(member => member.Name.ParseFName() == listPointerName);
if (x != null) //Update the existing list attribute if (x != null) //Update the existing list attribute
x.CustomAttributes[0].Arguments[9] = new(new CodePrimitiveExpression(totalSize)); x.CustomAttributes[0].Arguments[9] = new(new CodePrimitiveExpression(totalSize));
else //Store the data for when the list attribute is made else //Store the data for when the list attribute is made
listCountOffsets.Add(fName, totalSize); listCountOffsets.Add(fName, totalSize);
totalSize += field.Type.ParseFSize(); totalSize += field.Type.ParseFSize();
} else { } else {
Log($"Field {field.Name} is of unknown or unsupported type"); Log($"Field {field.Name} is of unknown or unsupported type");
} }
} }
ctd.CustomAttributes[0].Arguments.Add(new (new CodePrimitiveExpression(totalSize))); ctd.CustomAttributes[0].Arguments.Add(new(new CodePrimitiveExpression(totalSize)));
Log("Generating Parameterless constructor"); Log("Generating Parameterless constructor");
if(ctd.Members.Count > 0) if (ctd.Members.Count > 0)
ctd.Members.Add(GenerateParameterlessConstructor(type, ctd)); ctd.Members.Add(GenerateParameterlessConstructor(type, ctd));
Log("Generating Default Constructor"); Log("Generating Default Constructor");
ctd.Members.Add(GenerateConstructor(type, ctd)); ctd.Members.Add(GenerateConstructor(type, ctd));
@@ -281,8 +286,8 @@ namespace CodeGenerator {
Log($"No pointer or self reference detected in {type.Type}"); Log($"No pointer or self reference detected in {type.Type}");
return false; return false;
} }
/// <summary> /// <summary>
/// Filters the fields into normal fields and list fields pairs /// Filters the fields into normal fields and list fields pairs
/// </summary> /// </summary>
@@ -293,43 +298,42 @@ namespace CodeGenerator {
out List<DnaField> normalFields, out List<(DnaField, DnaField)> listFields) { out List<DnaField> normalFields, out List<(DnaField, DnaField)> listFields) {
normalFields = new(); //Fields that are not lists nor lengths of lists normalFields = new(); //Fields that are not lists nor lengths of lists
listFields = new(); //Fields that are lists, and their corresponding length fields listFields = new(); //Fields that are lists, and their corresponding length fields
//Cast to array the fields to avoid multiple enumerations //Cast to array the fields to avoid multiple enumerations
var dnaFields = fields as DnaField[] ?? fields.ToArray(); var dnaFields = fields as DnaField[] ?? fields.ToArray();
foreach (var field in dnaFields) { foreach (var field in dnaFields) {
if (ListMarkerStr.Any(s => field.Name.Contains(s)) && if (ListMarkerStr.Any(s => field.Name.Contains(s)) &&
!ListLenghtStr.Any(s2 => field.Name.Contains(s2))) { !ListLenghtStr.Any(s2 => field.Name.Contains(s2))) {
Log($"Found list field {field.Name}"); Log($"Found list field {field.Name}");
Log($"Searching for list length field"); Log($"Searching for list length field");
var listLengthField = dnaFields.FirstOrDefault(f => f.Name.Contains(field.Name.ParseFName()) && var listLengthField = dnaFields.FirstOrDefault(f => f.Name.Contains(field.Name.ParseFName()) &&
ListLenghtStr.Any(s2 => f.Name.Contains(s2))); ListLenghtStr.Any(s2 => f.Name.Contains(s2)));
if (listLengthField == null) if (listLengthField == null)
Log($"No list length field found for {field.Name}"); Log($"No list length field found for {field.Name}");
else { else {
Log($"Found list length field {listLengthField.Name}"); Log($"Found list length field {listLengthField.Name}");
listFields.Add((field, listLengthField)); listFields.Add((field, listLengthField));
//Remove the list length field from the normal fields (if present) //Remove the list length field from the normal fields (if present)
if(normalFields.Remove(listLengthField)) if (normalFields.Remove(listLengthField))
Log($"Removed list length field {listLengthField.Name}"); Log($"Removed list length field {listLengthField.Name}");
} }
continue; continue;
} }
//Skip fields that are recognized as listLengths //Skip fields that are recognized as listLengths
if (listFields.Select(f => f.Item2).Contains(field)) { if (listFields.Select(f => f.Item2).Contains(field)) {
Log($"Skipping known list length field {field.Name}"); Log($"Skipping known list length field {field.Name}");
continue; continue;
} }
Log($"Adding normal field {field.Name}"); Log($"Adding normal field {field.Name}");
normalFields.Add(field); normalFields.Add(field);
} }
} }
/// <summary> /// <summary>
/// Generates the following attribute types <c>DNAAttribute, DNAFieldAttribute, DNAClassAttribute, DNAListAttribute</c> /// Generates the following attribute types <c>DNAAttribute, DNAFieldAttribute, DNAClassAttribute, DNAListAttribute</c>
/// </summary> /// </summary>
@@ -337,17 +341,17 @@ namespace CodeGenerator {
/// <remarks>This internally uses a single instance of <see cref="AttributeBuilder"/> and sequentially generates the various attributes.</remarks> /// <remarks>This internally uses a single instance of <see cref="AttributeBuilder"/> and sequentially generates the various attributes.</remarks>
private static CodeTypeDeclaration[] GenerateTypeDeclarations() { private static CodeTypeDeclaration[] GenerateTypeDeclarations() {
var attributeBuilder = new AttributeBuilder(); var attributeBuilder = new AttributeBuilder();
var typeDeclarations = new[] { var typeDeclarations = new[] {
attributeBuilder.New().SetName("DNAAttribute") attributeBuilder.New().SetName("DNAAttribute")
.SetAttributeUsage(new (new CodeSnippetExpression("AttributeTargets.All"))) .SetAttributeUsage(new(new CodeSnippetExpression("AttributeTargets.All")))
.DeriveFromClass() .DeriveFromClass()
.AddAutoProperty(typeof(int), "OriginalIndex") .AddAutoProperty(typeof(int), "OriginalIndex")
.AddAutoProperty(typeof(string), "OriginalName") .AddAutoProperty(typeof(string), "OriginalName")
.AddPropertiesConstructor() .AddPropertiesConstructor()
.Build(), .Build(),
attributeBuilder.New().SetName("DNAFieldAttribute") attributeBuilder.New().SetName("DNAFieldAttribute")
.SetAttributeUsage(new (new CodeSnippetExpression("AttributeTargets.Field"))) .SetAttributeUsage(new(new CodeSnippetExpression("AttributeTargets.Field")))
.DeriveFromClass($"{Namespace}.DNAAttribute") .DeriveFromClass($"{Namespace}.DNAAttribute")
.AddAutoProperty(typeof(int), "Size") .AddAutoProperty(typeof(int), "Size")
.AddAutoProperty(typeof(string), "OriginalType") .AddAutoProperty(typeof(string), "OriginalType")
@@ -360,7 +364,7 @@ namespace CodeGenerator {
.AddBaseConstructorParams(["OriginalIndex", "OriginalName"]) .AddBaseConstructorParams(["OriginalIndex", "OriginalName"])
.Build(), .Build(),
attributeBuilder.New().SetName("DNAArrayAttribute") attributeBuilder.New().SetName("DNAArrayAttribute")
.SetAttributeUsage(new (new CodeSnippetExpression("AttributeTargets.Field"))) .SetAttributeUsage(new(new CodeSnippetExpression("AttributeTargets.Field")))
.DeriveFromClass($"{Namespace}.DNAAttribute") .DeriveFromClass($"{Namespace}.DNAAttribute")
.AddAutoProperty(typeof(int), "Size") .AddAutoProperty(typeof(int), "Size")
.AddAutoProperty(typeof(string), "OriginalType") .AddAutoProperty(typeof(string), "OriginalType")
@@ -373,7 +377,7 @@ namespace CodeGenerator {
.AddBaseConstructorParams(["OriginalIndex", "OriginalName"]) .AddBaseConstructorParams(["OriginalIndex", "OriginalName"])
.Build(), .Build(),
attributeBuilder.New().SetName("DNAClassAttribute") attributeBuilder.New().SetName("DNAClassAttribute")
.SetAttributeUsage(new (new CodeSnippetExpression("AttributeTargets.Class | AttributeTargets.Struct"))) .SetAttributeUsage(new(new CodeSnippetExpression("AttributeTargets.Class | AttributeTargets.Struct")))
.DeriveFromClass($"{Namespace}.DNAAttribute") .DeriveFromClass($"{Namespace}.DNAAttribute")
.AddAutoProperty(typeof(int), "OriginalIndex") .AddAutoProperty(typeof(int), "OriginalIndex")
.AddAutoProperty(typeof(string), "OriginalName") .AddAutoProperty(typeof(string), "OriginalName")
@@ -382,7 +386,7 @@ namespace CodeGenerator {
.AddBaseConstructorParams(["OriginalIndex", "OriginalName"]) .AddBaseConstructorParams(["OriginalIndex", "OriginalName"])
.Build(), .Build(),
attributeBuilder.New().SetName("DNAListAttribute") attributeBuilder.New().SetName("DNAListAttribute")
.SetAttributeUsage(new (new CodeSnippetExpression("AttributeTargets.Property | AttributeTargets.Field"))) .SetAttributeUsage(new(new CodeSnippetExpression("AttributeTargets.Property | AttributeTargets.Field")))
.DeriveFromClass($"{Namespace}.DNAAttribute") .DeriveFromClass($"{Namespace}.DNAAttribute")
.AddAutoProperty(typeof(int), "Size") .AddAutoProperty(typeof(int), "Size")
.AddAutoProperty(typeof(string), "OriginalType") .AddAutoProperty(typeof(string), "OriginalType")
@@ -408,12 +412,11 @@ namespace CodeGenerator {
size = body.Lengths[field.IdxType]; size = body.Lengths[field.IdxType];
string t = field.Type; string t = field.Type;
if (field.Name.StartsWith('*')) if (field.Name.StartsWith('*')) {
{
size = 8; size = 8;
isPointer = true; isPointer = true;
} }
CodeAttributeDeclaration cad = new("DNAFieldAttribute"); CodeAttributeDeclaration cad = new("DNAFieldAttribute");
cad.Arguments.AddRange(new CodeAttributeArgumentCollection() { cad.Arguments.AddRange(new CodeAttributeArgumentCollection() {
new(new CodePrimitiveExpression(size)), new(new CodePrimitiveExpression(size)),
@@ -433,24 +436,24 @@ namespace CodeGenerator {
size = body.Lengths[field.IdxType]; size = body.Lengths[field.IdxType];
//Generate the array declaration again... to grab the base type //Generate the array declaration again... to grab the base type
CodeMemberField amf = CreateArrayMemberField(field); CodeMemberField amf = CreateArrayMemberField(field);
//Generate the type string //Generate the type string
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.Append(amf.Type.BaseType); sb.Append(amf.Type.BaseType);
sb.Append('['); sb.Append('[');
for(int i=1; i<amf.Type.ArrayRank; i++) { for (int i = 1; i < amf.Type.ArrayRank; i++) {
sb.Append(','); sb.Append(',');
} }
sb.Append(']'); sb.Append(']');
var t = sb.ToString(); var t = sb.ToString();
var dimensions = GetArrayDimensions(field.Name); var dimensions = GetArrayDimensions(field.Name);
int length = 0; int length = 0;
foreach(int dim in dimensions) { foreach (int dim in dimensions) {
length += dim; length += dim;
size *= dim; size *= dim;
} }
CodeAttributeDeclaration cad = new("DNAArrayAttribute"); CodeAttributeDeclaration cad = new("DNAArrayAttribute");
cad.Arguments.AddRange(new CodeAttributeArgumentCollection() { cad.Arguments.AddRange(new CodeAttributeArgumentCollection() {
new(new CodePrimitiveExpression(size)), new(new CodePrimitiveExpression(size)),
@@ -466,15 +469,14 @@ namespace CodeGenerator {
private static CodeAttributeDeclaration GenerateDnaListAttribute(int listIndex, DnaField listField, int lenghtIndex, private static CodeAttributeDeclaration GenerateDnaListAttribute(int listIndex, DnaField listField, int lenghtIndex,
DnaField lenghtField, int ptrOffset, int countOffset, out int size) { DnaField lenghtField, int ptrOffset, int countOffset, out int size) {
size = 8; size = 8;
var cad = new CodeAttributeDeclaration("DNAListAttribute"); var cad = new CodeAttributeDeclaration("DNAListAttribute");
cad.Arguments.AddRange(new CodeAttributeArgumentCollection() { cad.Arguments.AddRange(new CodeAttributeArgumentCollection() {
new(new CodeSnippetExpression("8")),//pointer size new(new CodeSnippetExpression("8")), //pointer size
new(new CodePrimitiveExpression(listField.Type)), new(new CodePrimitiveExpression(listField.Type)),
new(new CodePrimitiveExpression(listField.Name)), new(new CodePrimitiveExpression(listField.Name)),
new(new CodePrimitiveExpression(listIndex)), new(new CodePrimitiveExpression(listIndex)),
new(new CodePrimitiveExpression(listField.Type)),//TODO: double check this new(new CodePrimitiveExpression(listField.Type)), //TODO: double check this
new(new CodePrimitiveExpression(lenghtField.Type)), new(new CodePrimitiveExpression(lenghtField.Type)),
new(new CodePrimitiveExpression(lenghtField.Name)), new(new CodePrimitiveExpression(lenghtField.Name)),
new(new CodePrimitiveExpression(lenghtIndex)), new(new CodePrimitiveExpression(lenghtIndex)),
@@ -530,21 +532,22 @@ namespace CodeGenerator {
Type t = Type.GetType(field.Type.ParseFType()); Type t = Type.GetType(field.Type.ParseFType());
CodeMemberField cmf; CodeMemberField cmf;
CodeTypeReference ctr = new(typeof(List<>)); CodeTypeReference ctr = new(typeof(List<>));
//Check if the type is a built-in type or a custom type //Check if the type is a built-in type or a custom type
if (t != null) { //Built-in type if (t != null) {
//Built-in type
ctr.TypeArguments.Add(t); ctr.TypeArguments.Add(t);
cmf = new(ctr, field.Name.ParseFName()); cmf = new(ctr, field.Name.ParseFName());
} else { //Custom type } else {
//Custom type
ctr.TypeArguments.Add(new CodeTypeReference(field.Type)); ctr.TypeArguments.Add(new CodeTypeReference(field.Type));
cmf = new(ctr, field.Name.ParseFName()); cmf = new(ctr, field.Name.ParseFName());
} }
cmf.Attributes = MemberAttributes.Public; cmf.Attributes = MemberAttributes.Public;
return cmf; return cmf;
} }
private static List<int> GetArrayDimensions(string name) private static List<int> GetArrayDimensions(string name) {
{
var dimensions = new List<int>(); var dimensions = new List<int>();
int startIndex = 0; int startIndex = 0;
// Get all array dimensions // Get all array dimensions
@@ -556,7 +559,7 @@ namespace CodeGenerator {
} }
startIndex = endIndex + 1; startIndex = endIndex + 1;
} }
return dimensions; return dimensions;
} }
@@ -617,7 +620,7 @@ namespace CodeGenerator {
return cc; return cc;
} }
private static CodeConstructor GenerateParameterlessConstructor(DnaStruct type, CodeTypeDeclaration ctd) { private static CodeConstructor GenerateParameterlessConstructor(DnaStruct type, CodeTypeDeclaration ctd) {
//Create a normal constructor //Create a normal constructor
CodeConstructor cc = new CodeConstructor { CodeConstructor cc = new CodeConstructor {
@@ -673,7 +676,7 @@ namespace CodeGenerator {
provider.GenerateCodeFromCompileUnit(ccu, sw, codeGeneratorOptions); provider.GenerateCodeFromCompileUnit(ccu, sw, codeGeneratorOptions);
tempNs.Types.Remove(type); tempNs.Types.Remove(type);
} }
if (!outputExtraTypes) return; if (!outputExtraTypes) return;
_customTypes.ExceptWith(ns.Types.OfType<CodeTypeDeclaration>().Select(t => t.Name)); _customTypes.ExceptWith(ns.Types.OfType<CodeTypeDeclaration>().Select(t => t.Name));
foreach (var type in _customTypes) { foreach (var type in _customTypes) {