173 lines
7.6 KiB
C#
173 lines
7.6 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.Linq;
|
|||
|
|
using EpicGames.Core;
|
|||
|
|
using EpicGames.UHT.Types;
|
|||
|
|
using UnrealSharpScriptGenerator.PropertyTranslators;
|
|||
|
|
using UnrealSharpScriptGenerator.Tooltip;
|
|||
|
|
using UnrealSharpScriptGenerator.Utilities;
|
|||
|
|
|
|||
|
|
namespace UnrealSharpScriptGenerator.Exporters;
|
|||
|
|
|
|||
|
|
public static class InterfaceExporter
|
|||
|
|
{
|
|||
|
|
public static void ExportInterface(UhtClass interfaceObj)
|
|||
|
|
{
|
|||
|
|
GeneratorStringBuilder stringBuilder = new();
|
|||
|
|
|
|||
|
|
bool nullableEnabled = interfaceObj.HasMetadata(UhtTypeUtilities.NullableEnable);
|
|||
|
|
string interfaceName = interfaceObj.GetStructName();
|
|||
|
|
string typeNamespace = interfaceObj.GetNamespace();
|
|||
|
|
|
|||
|
|
stringBuilder.GenerateTypeSkeleton(typeNamespace, nullableEnabled: nullableEnabled);
|
|||
|
|
stringBuilder.AppendTooltip(interfaceObj);
|
|||
|
|
|
|||
|
|
AttributeBuilder attributeBuilder = new AttributeBuilder(interfaceObj);
|
|||
|
|
attributeBuilder.AddGeneratedTypeAttribute(interfaceObj);
|
|||
|
|
attributeBuilder.Finish();
|
|||
|
|
|
|||
|
|
stringBuilder.AppendLine(attributeBuilder.ToString());
|
|||
|
|
stringBuilder.DeclareType(interfaceObj, "interface", interfaceName);
|
|||
|
|
stringBuilder.AppendLine();
|
|||
|
|
stringBuilder.AppendLine($"static {interfaceName} Wrap(UnrealSharp.CoreUObject.UObject obj)");
|
|||
|
|
stringBuilder.OpenBrace();
|
|||
|
|
stringBuilder.AppendLine($"return new {interfaceName}Wrapper(obj);");
|
|||
|
|
stringBuilder.CloseBrace();
|
|||
|
|
|
|||
|
|
List<UhtFunction> exportedFunctions = new();
|
|||
|
|
List<UhtFunction> exportedOverrides = new();
|
|||
|
|
Dictionary<string, GetterSetterPair> exportedGetterSetters = new();
|
|||
|
|
Dictionary<string, GetterSetterPair> getSetOverrides = new();
|
|||
|
|
|
|||
|
|
if (interfaceObj.AlternateObject is UhtClass alternateObject)
|
|||
|
|
{
|
|||
|
|
ScriptGeneratorUtilities.GetExportedFunctions(alternateObject, exportedFunctions, exportedOverrides, exportedGetterSetters, getSetOverrides);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ScriptGeneratorUtilities.GetExportedFunctions(interfaceObj, exportedFunctions, exportedOverrides, exportedGetterSetters, getSetOverrides);
|
|||
|
|
|
|||
|
|
ExportInterfaceProperties(stringBuilder, exportedGetterSetters);
|
|||
|
|
ExportInterfaceFunctions(stringBuilder, exportedFunctions);
|
|||
|
|
ExportInterfaceFunctions(stringBuilder, exportedOverrides);
|
|||
|
|
|
|||
|
|
stringBuilder.CloseBrace();
|
|||
|
|
|
|||
|
|
stringBuilder.AppendLine();
|
|||
|
|
stringBuilder.AppendLine($"internal sealed class {interfaceName}Wrapper : {interfaceName}, UnrealSharp.CoreUObject.IScriptInterface");
|
|||
|
|
stringBuilder.OpenBrace();
|
|||
|
|
stringBuilder.AppendLine("public UnrealSharp.CoreUObject.UObject Object { get; }");
|
|||
|
|
stringBuilder.AppendLine("private IntPtr NativeObject => Object.NativeObject;");
|
|||
|
|
stringBuilder.AppendLine();
|
|||
|
|
stringBuilder.AppendLine($"internal {interfaceName}Wrapper(UnrealSharp.CoreUObject.UObject obj)");
|
|||
|
|
stringBuilder.OpenBrace();
|
|||
|
|
stringBuilder.AppendLine("Object = obj;");
|
|||
|
|
stringBuilder.CloseBrace();
|
|||
|
|
|
|||
|
|
StaticConstructorUtilities.ExportStaticConstructor(stringBuilder, interfaceObj,
|
|||
|
|
new List<UhtProperty>(),
|
|||
|
|
exportedFunctions,
|
|||
|
|
exportedGetterSetters,
|
|||
|
|
new Dictionary<UhtProperty, GetterSetterPair>(),
|
|||
|
|
exportedOverrides,
|
|||
|
|
false, interfaceName + "Wrapper");
|
|||
|
|
|
|||
|
|
ClassExporter.ExportCustomProperties(stringBuilder, exportedGetterSetters, [], []);
|
|||
|
|
ExportWrapperFunctions(stringBuilder, exportedFunctions);
|
|||
|
|
ExportWrapperFunctions(stringBuilder, exportedOverrides);
|
|||
|
|
|
|||
|
|
stringBuilder.CloseBrace();
|
|||
|
|
|
|||
|
|
stringBuilder.AppendLine();
|
|||
|
|
stringBuilder.AppendLine($"public static class {interfaceName}Marshaller");
|
|||
|
|
stringBuilder.OpenBrace();
|
|||
|
|
stringBuilder.AppendLine($"public static void ToNative(IntPtr nativeBuffer, int arrayIndex, {interfaceName} obj)");
|
|||
|
|
stringBuilder.OpenBrace();
|
|||
|
|
stringBuilder.AppendLine($"UnrealSharp.CoreUObject.ScriptInterfaceMarshaller<{interfaceName}>.ToNative(nativeBuffer, arrayIndex, obj);");
|
|||
|
|
stringBuilder.CloseBrace();
|
|||
|
|
stringBuilder.AppendLine();
|
|||
|
|
|
|||
|
|
stringBuilder.AppendLine($"public static {interfaceName} FromNative(IntPtr nativeBuffer, int arrayIndex)");
|
|||
|
|
stringBuilder.OpenBrace();
|
|||
|
|
stringBuilder.AppendLine($"return UnrealSharp.CoreUObject.ScriptInterfaceMarshaller<{interfaceName}>.FromNative(nativeBuffer, arrayIndex);");
|
|||
|
|
stringBuilder.CloseBrace();
|
|||
|
|
stringBuilder.CloseBrace();
|
|||
|
|
|
|||
|
|
FileExporter.SaveGlueToDisk(interfaceObj, stringBuilder);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void ExportInterfaceProperties(GeneratorStringBuilder stringBuilder,
|
|||
|
|
Dictionary<string, GetterSetterPair> exportedGetterSetters)
|
|||
|
|
{
|
|||
|
|
foreach (var (_, getterSetterPair) in exportedGetterSetters)
|
|||
|
|
{
|
|||
|
|
if (getterSetterPair.Property is null)
|
|||
|
|
{
|
|||
|
|
throw new InvalidDataException("Properties should have a UProperty associated with them.");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
UhtFunction firstAccessor = getterSetterPair.Accessors.First();
|
|||
|
|
UhtProperty firstProperty = getterSetterPair.Property;
|
|||
|
|
string propertyName = getterSetterPair.PropertyName;
|
|||
|
|
|
|||
|
|
PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(firstProperty)!;
|
|||
|
|
stringBuilder.TryAddWithEditor(firstAccessor);
|
|||
|
|
string protection = firstProperty.GetProtection();
|
|||
|
|
stringBuilder.AppendTooltip(firstProperty);
|
|||
|
|
|
|||
|
|
string managedType = translator.GetManagedType(firstProperty);
|
|||
|
|
stringBuilder.AppendLine($"{managedType} {propertyName}");
|
|||
|
|
stringBuilder.OpenBrace();
|
|||
|
|
|
|||
|
|
if (getterSetterPair.Getter is not null)
|
|||
|
|
{
|
|||
|
|
AppendPropertyFunctionDeclaration(stringBuilder, getterSetterPair.Getter);
|
|||
|
|
stringBuilder.AppendLine("get;");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (getterSetterPair.Setter is not null)
|
|||
|
|
{
|
|||
|
|
AppendPropertyFunctionDeclaration(stringBuilder, getterSetterPair.Setter);
|
|||
|
|
stringBuilder.AppendLine("set;");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
stringBuilder.CloseBrace();
|
|||
|
|
stringBuilder.TryEndWithEditor(firstAccessor);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static void AppendPropertyFunctionDeclaration(GeneratorStringBuilder stringBuilder, UhtFunction function)
|
|||
|
|
{
|
|||
|
|
AttributeBuilder attributeBuilder = new AttributeBuilder(function);
|
|||
|
|
|
|||
|
|
if (function.FunctionFlags.HasAnyFlags(EFunctionFlags.BlueprintEvent))
|
|||
|
|
{
|
|||
|
|
attributeBuilder.AddArgument("FunctionFlags.BlueprintEvent");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
attributeBuilder.AddGeneratedTypeAttribute(function);
|
|||
|
|
attributeBuilder.Finish();
|
|||
|
|
|
|||
|
|
stringBuilder.AppendLine(attributeBuilder.ToString());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void ExportInterfaceFunctions(GeneratorStringBuilder stringBuilder, List<UhtFunction> exportedFunctions)
|
|||
|
|
{
|
|||
|
|
foreach (UhtFunction function in exportedFunctions)
|
|||
|
|
{
|
|||
|
|
FunctionExporter.ExportInterfaceFunction(stringBuilder, function);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void ExportWrapperFunctions(GeneratorStringBuilder stringBuilder, List<UhtFunction> exportedFunctions)
|
|||
|
|
{
|
|||
|
|
foreach (UhtFunction function in exportedFunctions)
|
|||
|
|
{
|
|||
|
|
FunctionType functionType = function.FunctionFlags.HasFlag(EFunctionFlags.BlueprintEvent)
|
|||
|
|
? FunctionType.BlueprintEvent
|
|||
|
|
: FunctionType.Normal;
|
|||
|
|
|
|||
|
|
FunctionExporter.ExportFunction(stringBuilder, function, functionType);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|