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);");
|
|
}
|
|
} |