232 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			232 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 
								 | 
							
								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);");
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 |