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