| @ -0,0 +1,232 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using EpicGames.Core; | ||||
| using EpicGames.UHT.Types; | ||||
| using EpicGames.UHT.Utils; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator; | ||||
|  | ||||
| public class GeneratorStringBuilder : IDisposable | ||||
| { | ||||
|     private int _indent; | ||||
|     private readonly List<string> _directives = new(); | ||||
|     private BorrowStringBuilder _borrower = new(StringBuilderCache.Big); | ||||
|     private StringBuilder StringBuilder => _borrower.StringBuilder; | ||||
|  | ||||
|     public override string ToString() | ||||
|     { | ||||
|         return StringBuilder.ToString(); | ||||
|     } | ||||
|  | ||||
|     public void Dispose() | ||||
|     { | ||||
|         _borrower.Dispose(); | ||||
|     } | ||||
|      | ||||
|     public void OpenBrace() | ||||
|     { | ||||
|         AppendLine("{"); | ||||
|         Indent(); | ||||
|     } | ||||
|      | ||||
|     public void CloseBrace() | ||||
|     { | ||||
|         UnIndent(); | ||||
|         AppendLine("}"); | ||||
|     } | ||||
|  | ||||
|     public void Indent() | ||||
|     { | ||||
|        ++_indent; | ||||
|     } | ||||
|      | ||||
|     public void UnIndent() | ||||
|     { | ||||
|         --_indent; | ||||
|     } | ||||
|      | ||||
|     public void Append(string text) | ||||
|     { | ||||
|         StringBuilder.Append(text); | ||||
|     } | ||||
|  | ||||
|     public void AppendLine() | ||||
|     { | ||||
|         if (StringBuilder.Length > 0) | ||||
|         { | ||||
|             StringBuilder.AppendLine(); | ||||
|         } | ||||
|          | ||||
|         for (int i = 0; i < _indent; i++) | ||||
|         { | ||||
|             StringBuilder.Append("    "); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     public void AppendLine(string line) | ||||
|     { | ||||
|         AppendLine(); | ||||
|         StringBuilder.Append(line); | ||||
|     } | ||||
|      | ||||
|     public void DeclareDirective(string directive) | ||||
|     { | ||||
|         if (_directives.Contains(directive) || string.IsNullOrEmpty(directive)) | ||||
|         { | ||||
|             return; | ||||
|         } | ||||
|          | ||||
|         _directives.Add(directive); | ||||
|         AppendLine($"using {directive};"); | ||||
|     } | ||||
|      | ||||
|     public void DeclareDirectives(List<string> directives) | ||||
|     { | ||||
|         foreach (string directive in directives) | ||||
|         { | ||||
|             DeclareDirective(directive); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     public void BeginPreproccesorBlock(string condition) | ||||
|     { | ||||
|         AppendLine($"#if {condition}"); | ||||
|     } | ||||
|      | ||||
|     public void EndPreproccesorBlock() | ||||
|     { | ||||
|         AppendLine("#endif"); | ||||
|     } | ||||
|      | ||||
|     public void BeginWithEditorPreproccesorBlock() | ||||
|     { | ||||
|         BeginPreproccesorBlock("WITH_EDITOR"); | ||||
|     } | ||||
|      | ||||
|     public void TryAddWithEditor(UhtProperty property) | ||||
|     { | ||||
|         if (property.HasAllFlags(EPropertyFlags.EditorOnly)) | ||||
|         { | ||||
|             BeginWithEditorPreproccesorBlock(); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     public void TryEndWithEditor(UhtProperty property) | ||||
|     { | ||||
|         if (property.HasAllFlags(EPropertyFlags.EditorOnly)) | ||||
|         { | ||||
|             EndPreproccesorBlock(); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     public void TryEndWithEditor(UhtFunction function) | ||||
|     { | ||||
|         if (function.FunctionFlags.HasAllFlags(EFunctionFlags.EditorOnly)) | ||||
|         { | ||||
|             EndPreproccesorBlock(); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     public void TryAddWithEditor(UhtFunction function) | ||||
|     { | ||||
|         if (function.FunctionFlags.HasAllFlags(EFunctionFlags.EditorOnly)) | ||||
|         { | ||||
|             BeginWithEditorPreproccesorBlock(); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     public void BeginUnsafeBlock() | ||||
|     { | ||||
|         AppendLine("unsafe"); | ||||
|         OpenBrace(); | ||||
|     } | ||||
|      | ||||
|     public void EndUnsafeBlock() | ||||
|     { | ||||
|         CloseBrace(); | ||||
|     } | ||||
|      | ||||
|     public void GenerateTypeSkeleton(string typeNameSpace, bool blittable = false, bool nullableEnabled = false) | ||||
|     { | ||||
|         if (nullableEnabled) | ||||
|         { | ||||
|             AppendLine("#nullable enable"); | ||||
|         } | ||||
|         DeclareDirective(ScriptGeneratorUtilities.AttributeNamespace); | ||||
|         DeclareDirective(ScriptGeneratorUtilities.CoreAttributeNamespace); | ||||
|         DeclareDirective(ScriptGeneratorUtilities.InteropNamespace); | ||||
|         DeclareDirective(ScriptGeneratorUtilities.MarshallerNamespace); | ||||
|          | ||||
|         if (blittable) | ||||
|         { | ||||
|             DeclareDirective(ScriptGeneratorUtilities.InteropServicesNamespace); | ||||
|         } | ||||
|  | ||||
|         AppendLine(); | ||||
|         AppendLine($"namespace {typeNameSpace};"); | ||||
|         AppendLine(); | ||||
|     } | ||||
|      | ||||
|     public void GenerateTypeSkeleton(UhtType type) | ||||
|     { | ||||
|         GenerateTypeSkeleton(type.GetNamespace()); | ||||
|     } | ||||
|      | ||||
|     public void DeclareType(UhtType? type , string typeName, string declaredTypeName, string? baseType = null, bool isPartial = true, string? modifiers = "", List<UhtClass>? nativeInterfaces = default, List<string>? csInterfaces = default) | ||||
|     { | ||||
|         string partialSpecifier = isPartial ? "partial " : string.Empty; | ||||
|         List<string> inheritingFrom = new List<string>(); | ||||
|          | ||||
|         if (!string.IsNullOrEmpty(baseType)) inheritingFrom.Add(baseType); | ||||
|  | ||||
|         if (nativeInterfaces != null) | ||||
|         { | ||||
|             foreach (UhtType @interface in nativeInterfaces) | ||||
|             { | ||||
|                 string fullInterfaceName = @interface.GetFullManagedName(); | ||||
|                 inheritingFrom.Add(fullInterfaceName); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (csInterfaces != null) | ||||
|         { | ||||
|             foreach (string @interface in csInterfaces) inheritingFrom.Add(@interface); | ||||
|         } | ||||
|  | ||||
|         string accessSpecifier = "public"; | ||||
|         if (type != null && type.HasMetadata("InternalType")) | ||||
|         { | ||||
|             accessSpecifier = "internal"; | ||||
|         } | ||||
|  | ||||
|         string inheritanceSpecifier = | ||||
|             inheritingFrom.Count > 0 ? $" : {string.Join(", ", inheritingFrom)}" : string.Empty; | ||||
|          | ||||
|         AppendLine($"{accessSpecifier}{modifiers} {partialSpecifier}{typeName} {declaredTypeName}{inheritanceSpecifier}"); | ||||
|         OpenBrace(); | ||||
|     } | ||||
|      | ||||
|     public void AppendStackAlloc(string sizeVariableName) | ||||
|     { | ||||
|         AppendLine($"byte* paramsBufferAllocation = stackalloc byte[{sizeVariableName}];"); | ||||
|         AppendLine("nint paramsBuffer = (nint) paramsBufferAllocation;"); | ||||
|     } | ||||
|  | ||||
|     public void AppendStackAllocFunction(string sizeVariableName, string structName, bool appendInitializer = true) | ||||
|     { | ||||
|         AppendStackAlloc(sizeVariableName); | ||||
|          | ||||
|         if (appendInitializer) | ||||
|         { | ||||
|             AppendLine($"{ExporterCallbacks.UFunctionCallbacks}.CallInitializeFunctionParams({structName}, paramsBuffer);"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void AppendStackAllocProperty(string sizeVariableName, string sourcePropertyName) | ||||
|     { | ||||
|         AppendStackAlloc(sizeVariableName); | ||||
|         AppendLine($"{ExporterCallbacks.FPropertyCallbacks}.CallInitializeValue({sourcePropertyName}, paramsBuffer);"); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user