From d1742775ad0bb2a5fb8d336594d2228ef86fde84 Mon Sep 17 00:00:00 2001 From: Samuele Lorefice Date: Wed, 22 Jan 2025 01:57:46 +0100 Subject: [PATCH] Renamed library project, cleaned up code --- .../BlendFile.csproj | 0 BlendFile/CompatTypes/uchar.cs | 34 +++++ BlenderSharp.sln | 2 +- CodeGenerator/Program.cs | 120 +++++++++++------- 4 files changed, 107 insertions(+), 49 deletions(-) rename BlendTypes/BlendTypes.csproj => BlendFile/BlendFile.csproj (100%) create mode 100644 BlendFile/CompatTypes/uchar.cs diff --git a/BlendTypes/BlendTypes.csproj b/BlendFile/BlendFile.csproj similarity index 100% rename from BlendTypes/BlendTypes.csproj rename to BlendFile/BlendFile.csproj diff --git a/BlendFile/CompatTypes/uchar.cs b/BlendFile/CompatTypes/uchar.cs new file mode 100644 index 0000000..b9fd5ea --- /dev/null +++ b/BlendFile/CompatTypes/uchar.cs @@ -0,0 +1,34 @@ +using System.Numerics; + +namespace BlendFile.CompatTypes; + +public readonly struct uchar { + public uchar Value => _value; + + private readonly byte _value; + + public uchar(byte value) => _value = value; + public uchar(uchar value) => _value = value._value; + + public static explicit operator byte(uchar value) => value._value; + public static implicit operator uchar(byte value) => new(value); + + public static explicit operator sbyte(uchar value) => (sbyte)value._value; + public static implicit operator uchar(sbyte value) => new((byte)value); + + public static explicit operator int(uchar value) => value._value; + public static implicit operator uchar(int value) => new((byte)value); + + public static uchar operator +(uchar left, uchar right) => left.Value + right.Value; + public static uchar operator -(uchar left, uchar right) => left.Value - right.Value; + public static uchar operator *(uchar left, uchar right) => left.Value * right.Value; + public static uchar operator /(uchar left, uchar right) => left.Value / right.Value; + public static uchar operator %(uchar left, uchar right) => left.Value % right.Value; + public static uchar operator &(uchar left, uchar right) => left.Value & right.Value; + public static uchar operator |(uchar left, uchar right) => left.Value | right.Value; + public static uchar operator ^(uchar left, uchar right) => left.Value ^ right.Value; + public static uchar operator <<(uchar left, byte right) => left.Value << right; + public static uchar operator >>(uchar left, byte right) => left.Value >> right; + public static uchar operator ++(uchar value) => new (value.Value + 1); + public static uchar operator --(uchar value) => new (value.Value - 1); +} diff --git a/BlenderSharp.sln b/BlenderSharp.sln index 94ab229..f1d084f 100644 --- a/BlenderSharp.sln +++ b/BlenderSharp.sln @@ -2,7 +2,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeGenerator", "CodeGenerator\CodeGenerator.csproj", "{F7A0CD58-F691-4EFC-AC04-D63DB372DA31}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlendTypes", "BlendTypes\BlendTypes.csproj", "{E2D22AE2-A31A-453C-8A3F-1D4066F0C55D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlendFile", "BlendFile\BlendFile.csproj", "{E2D22AE2-A31A-453C-8A3F-1D4066F0C55D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/CodeGenerator/Program.cs b/CodeGenerator/Program.cs index 538e703..9fb5692 100644 --- a/CodeGenerator/Program.cs +++ b/CodeGenerator/Program.cs @@ -10,6 +10,7 @@ using System.Reflection.Emit; using System.Text; using Microsoft.CSharp; using BlendFile = Kaitai.BlenderBlend; +// ReSharper disable BitwiseOperatorOnEnumWithoutFlags namespace CodeGenerator { @@ -35,8 +36,7 @@ namespace CodeGenerator { public class Program { public static BlendFile blendfile; - - private static StringBuilder sb = new StringBuilder(); + private static StringBuilder sb = new(); public static void Log(string message) { sb.AppendLine(message); @@ -45,7 +45,6 @@ namespace CodeGenerator { public static void Main(string[] args) { Log("Reading empty.blend file"); - blendfile = BlendFile.FromFile("empty.blend"); Log($"Header: Blender v{blendfile.Hdr.Version} {blendfile.Hdr.Endian}\n" + @@ -54,6 +53,66 @@ namespace CodeGenerator { Log("Generating C# code"); + //Create a new NameSpace + CodeNamespace ns = new CodeNamespace("Blender"); + + Log("Pass 1: Generating structs"); + + foreach (var type in blendfile.SdnaStructs) { + Log($"Generating struct {type.Type}"); + bool referenceSelf = false; + bool referencePointer = false; + + //Create a new type declaration + var ctd = new CodeTypeDeclaration(type.Type);// { IsStruct = true }; + + foreach (var field in type.Fields) { + if(field.Name.Contains("*")) { + referencePointer = true; + } + if(field.Type.Contains(type.Type)) { + referenceSelf = true; + } + } + + if(referenceSelf || referencePointer) { + Log("Struct contains references"); + ctd.IsClass = true; + } else { + ctd.IsStruct = true; + } + + //Add the class to the namespace + ns.Types.Add(ctd); + //Add the fields to the class + Log($"Fields: {type.Fields.Count}"); + + foreach (var field in type.Fields) { + CodeMemberField cmf; + string name = field.Name; + if (field.Name.Contains("[")) { + Log($"Generating array field {field.Name}"); + cmf = CreateArrayMemberField(field); + } else { + Log($"Generating field {field.Name}"); + cmf = CreateMemberField(field); + } + + ctd.Members.Add(cmf); + } + + Log("Generating constructor"); + ctd.Members.Add(GenerateConstructor(type, ctd)); + + Log("Finished generating struct"); + } + + Log("Pass 2: Writing out code"); + CodeNamespace tempNs = new CodeNamespace("BlendFile.DNA"); + if(!Path.Exists("Blendfile\\DNA")) { + Directory.CreateDirectory("Blendfile\\DNA"); + } + CodeGeneratorOptions codeGeneratorOptions = new CodeGeneratorOptions() { BlankLinesBetweenMembers = false, BracingStyle = "Block", @@ -61,54 +120,17 @@ namespace CodeGenerator { IndentString = " ", VerbatimOrder = false }; - var provider = new CSharpCodeProvider(); - //Create a new NameSpace - CodeNamespace ns = new CodeNamespace("Blender"); - - Log("Pass 1: Generating structs"); - - foreach (var type in blendfile.SdnaStructs) { - bool hasArrays = false; - Log($"Generating struct {type.Type}"); - //Create a new structs - var ctd = new CodeTypeDeclaration(type.Type) { IsStruct = true }; - //Add the class to the namespace - ns.Types.Add(ctd); - //Add the fields to the class - Log($"Fields: {type.Fields.Count}"); - foreach (var field in type.Fields) { - CodeMemberField cmf; - string name = field.Name; - if (field.Name.Contains("[")) { - Log($"Generating array field {field.Name}"); - hasArrays = true; - cmf = CreateArrayMemberField(field); - } else { - Log($"Generating field {field.Name}"); - cmf = CreateMemberField(field); - } - - cmf.Attributes = MemberAttributes.Public; - ctd.Members.Add(cmf); - } - - Log("Generating constructor"); - ctd.Members.Add(GenerateConstructor(type, ctd)); - - //If it has arrays, generate a static constructor for them - if (hasArrays) { - Log("Generating static constructor"); - ctd.Members.Add(GenerateStaticConstructor(ctd)); - } - - Log("Finished generating struct"); + foreach (var type in ns.Types.OfType()) { + tempNs.Types.Add(type); + Log($"Writing out {(type.IsStruct ? "struct" : "class")} {type.Name}"); + using var sw = new StreamWriter($"Blender\\{type.Name}.cs"); + provider.GenerateCodeFromNamespace(tempNs, sw, codeGeneratorOptions); + tempNs.Types.Remove(type); } - using var sw = new StreamWriter("BlenderSharp.cs"); - provider.GenerateCodeFromNamespace(ns, sw, codeGeneratorOptions); Log("Finished generating C# code"); - Log("Code saved to BlenderSharp.cs"); + File.AppendAllText("Log.txt", sb.ToString()); } @@ -165,6 +187,7 @@ namespace CodeGenerator { //Check if the type is a built-in type or a custom type if (t != null) cmf = new(t, field.Name.ParseFName()); //Built-in type else cmf = new(new CodeTypeReference(field.Type), field.Name.ParseFName()); //Custom type + cmf.Attributes = MemberAttributes.Public; return cmf; } @@ -194,6 +217,8 @@ namespace CodeGenerator { if (t != null) cmf = new(t, name); //Built-in type else cmf = new(field.Type, name); //Custom type + //Set the field attributes + cmf.Attributes = MemberAttributes.Public; //Define the array type cmf.Type.ArrayElementType = new(field.Type.ParseFType() ?? field.Type); cmf.Type.ArrayRank = dimensions.Count; @@ -207,6 +232,5 @@ namespace CodeGenerator { string dims = string.Concat(dimensions.Select(d => $"[{d}]")); return new CodeSnippetExpression($"new {type.BaseType}{dims}"); } - } } \ No newline at end of file