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