224 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			224 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System.Collections.Generic;
 | |
| using EpicGames.Core;
 | |
| using EpicGames.UHT.Types;
 | |
| using UnrealSharpScriptGenerator.PropertyTranslators;
 | |
| 
 | |
| namespace UnrealSharpScriptGenerator.Utilities;
 | |
| 
 | |
| public static class StaticConstructorUtilities
 | |
| {
 | |
|     public static void ExportStaticConstructor(GeneratorStringBuilder generatorStringBuilder, 
 | |
|         UhtStruct structObj, 
 | |
|         List<UhtProperty> exportedProperties, 
 | |
|         List<UhtFunction> exportedFunctions,
 | |
|         Dictionary<string, GetterSetterPair> exportedGetterSetters,
 | |
|         Dictionary<UhtProperty, GetterSetterPair> getSetBackedProperties,
 | |
|         List<UhtFunction> overrides,
 | |
|         bool isBlittable = false, string? customStaticConstructorName = null)
 | |
|     {
 | |
|         UhtClass? classObj = structObj as UhtClass;
 | |
|         UhtScriptStruct? scriptStructObj = structObj as UhtScriptStruct;
 | |
|         string structName = structObj.GetStructName();
 | |
| 
 | |
|         if (classObj != null && exportedProperties.Count == 0 
 | |
|                              && exportedFunctions.Count == 0 
 | |
|                              && overrides.Count == 0 
 | |
|                              && exportedGetterSetters.Count == 0 
 | |
|                              && getSetBackedProperties.Count == 0)
 | |
|         {
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         bool hasStaticFunctions = true;
 | |
|         void CheckIfStaticFunction(UhtFunction function)
 | |
|         {
 | |
|             if (function.FunctionFlags.HasAnyFlags(EFunctionFlags.Static))
 | |
|             {
 | |
|                 hasStaticFunctions = true;
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         foreach (UhtFunction function in exportedFunctions)
 | |
|         {
 | |
|             CheckIfStaticFunction(function);
 | |
|         }
 | |
|         
 | |
|         foreach (GetterSetterPair pair in exportedGetterSetters.Values)
 | |
|         {
 | |
|             if (pair.Getter != null)
 | |
|             {
 | |
|                 CheckIfStaticFunction(pair.Getter);
 | |
|             }
 | |
|             
 | |
|             if (pair.Setter != null)
 | |
|             {
 | |
|                 CheckIfStaticFunction(pair.Setter);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         string nativeClassPtrDeclaration = string.Empty;
 | |
|         if (hasStaticFunctions)
 | |
|         {
 | |
|             generatorStringBuilder.AppendLine("static readonly IntPtr NativeClassPtr;");
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             nativeClassPtrDeclaration = "IntPtr ";
 | |
|         }
 | |
| 
 | |
|         if (scriptStructObj != null)
 | |
|         {
 | |
|             if(classObj == null) generatorStringBuilder.AppendLine("public static IntPtr GetNativeClassPtr() => NativeClassPtr;");
 | |
|             if (isBlittable)
 | |
|             {
 | |
|                 generatorStringBuilder.AppendLine("public static int GetNativeDataSize()");
 | |
|                 generatorStringBuilder.OpenBrace();
 | |
|                 generatorStringBuilder.BeginUnsafeBlock();
 | |
|                 generatorStringBuilder.AppendLine($"return sizeof({structName});");
 | |
|                 generatorStringBuilder.EndUnsafeBlock();
 | |
|                 generatorStringBuilder.CloseBrace();
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 generatorStringBuilder.AppendLine("public static readonly int NativeDataSize;");
 | |
|                 if (classObj == null)
 | |
|                 {
 | |
|                     generatorStringBuilder.AppendLine("public static int GetNativeDataSize() => NativeDataSize;");
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         string staticCtorName = customStaticConstructorName != null ? customStaticConstructorName : structName;
 | |
|         generatorStringBuilder.AppendLine($"static {staticCtorName}()");
 | |
|         generatorStringBuilder.OpenBrace();
 | |
|         
 | |
|         string type = classObj != null ? "Class" : "Struct";
 | |
|         
 | |
|         string engineName = structObj.EngineName;
 | |
|         generatorStringBuilder.AppendLine($"{nativeClassPtrDeclaration}NativeClassPtr = {ExporterCallbacks.CoreUObjectCallbacks}.CallGetNative{type}FromName({structObj.ExportGetAssemblyName()}, \"{structObj.GetNamespace()}\", \"{engineName}\");");
 | |
|         
 | |
|         ExportPropertiesStaticConstructor(generatorStringBuilder, exportedProperties);
 | |
|         ExportGetSetBackedPropertyStaticConstructor(generatorStringBuilder, getSetBackedProperties);
 | |
| 
 | |
|         if (classObj != null)
 | |
|         {
 | |
|             foreach (KeyValuePair<string, GetterSetterPair> pair in exportedGetterSetters)
 | |
|             {
 | |
|                 if (pair.Value.Getter != null)
 | |
|                 {
 | |
|                     ExportClassFunctionStaticConstructor(generatorStringBuilder, pair.Value.Getter);
 | |
|                 }
 | |
|                 
 | |
|                 if (pair.Value.Setter != null)
 | |
|                 {
 | |
|                     ExportClassFunctionStaticConstructor(generatorStringBuilder, pair.Value.Setter);
 | |
|                 }
 | |
|             }
 | |
|             
 | |
|             ExportClassFunctionsStaticConstructor(generatorStringBuilder, exportedFunctions);
 | |
|             ExportClassOverridesStaticConstructor(generatorStringBuilder, overrides);
 | |
|         }
 | |
|         else if (!isBlittable) generatorStringBuilder.AppendLine($"NativeDataSize = {ExporterCallbacks.UScriptStructCallbacks}.CallGetNativeStructSize(NativeClassPtr);");
 | |
|         
 | |
|         generatorStringBuilder.CloseBrace();
 | |
|     }
 | |
|     
 | |
|     public static void ExportClassFunctionsStaticConstructor(GeneratorStringBuilder generatorStringBuilder, List<UhtFunction> exportedFunctions)
 | |
|     {
 | |
|         foreach (UhtFunction function in exportedFunctions)
 | |
|         {
 | |
|             ExportClassFunctionStaticConstructor(generatorStringBuilder, function);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     public static void ExportClassFunctionStaticConstructor(GeneratorStringBuilder generatorStringBuilder, UhtFunction function)
 | |
|     {
 | |
|         string functionName = function.SourceName;
 | |
| 
 | |
|         string nativeFunctionName = function.GetNativeFunctionName();
 | |
|             
 | |
|         generatorStringBuilder.TryAddWithEditor(function);
 | |
|         generatorStringBuilder.AppendLine($"{nativeFunctionName} = {ExporterCallbacks.UClassCallbacks}.CallGetNativeFunctionFromClassAndName(NativeClassPtr, \"{function.EngineName}\");");
 | |
|             
 | |
|         if (function.HasParametersOrReturnValue())
 | |
|         {
 | |
|             bool hasCustomStructParams = function.HasCustomStructParamSupport();
 | |
|             string variableName = hasCustomStructParams ? $"{functionName}_NativeParamsSize" : $"{functionName}_ParamsSize";
 | |
|             generatorStringBuilder.AppendLine($"{variableName} = {ExporterCallbacks.UFunctionCallbacks}.CallGetNativeFunctionParamsSize({functionName}_NativeFunction);");
 | |
|                 
 | |
|             foreach (UhtType parameter in function.Children)
 | |
|             {
 | |
|                 if (parameter is not UhtProperty property)
 | |
|                 {
 | |
|                     continue;
 | |
|                 }
 | |
| 
 | |
|                 PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(property)!;
 | |
|                 translator.ExportParameterStaticConstructor(generatorStringBuilder, property, function, property.SourceName, functionName);
 | |
|             }
 | |
|             
 | |
|             if (hasCustomStructParams)
 | |
|             {
 | |
|                 List<string> customStructParams = function.GetCustomStructParams();
 | |
|                 List<string> initializerElements = customStructParams.ConvertAll(param =>
 | |
|                     $"{ExporterCallbacks.FPropertyCallbacks}.CallGetNativePropertyFromName({nativeFunctionName}, \"{param}\")");
 | |
|                 generatorStringBuilder.AppendLine($"{functionName}_CustomStructureNativeProperties = new IntPtr[]{{{string.Join(", ", initializerElements)}}};");
 | |
|             }
 | |
|         }
 | |
|         generatorStringBuilder.TryEndWithEditor(function);
 | |
|     }
 | |
|     
 | |
|     public static void ExportClassOverridesStaticConstructor(GeneratorStringBuilder generatorStringBuilder, List<UhtFunction> overrides)
 | |
|     {
 | |
|         foreach (UhtFunction function in overrides)
 | |
|         {
 | |
|             generatorStringBuilder.TryAddWithEditor(function);
 | |
|             string functionName = function.SourceName;
 | |
|             
 | |
|             string intPtrDeclaration = function.IsBlueprintImplementableEvent() ? "IntPtr " : "";
 | |
|             generatorStringBuilder.AppendLine($"{intPtrDeclaration}{functionName}_NativeFunction = {ExporterCallbacks.UClassCallbacks}.CallGetNativeFunctionFromClassAndName(NativeClassPtr, \"{function.EngineName}\");");
 | |
|             
 | |
|             if (function.HasParametersOrReturnValue())
 | |
|             {
 | |
|                 generatorStringBuilder.AppendLine($"{functionName}_ParamsSize = {ExporterCallbacks.UFunctionCallbacks}.CallGetNativeFunctionParamsSize({functionName}_NativeFunction);");
 | |
|             
 | |
|                 foreach (UhtType parameter in function.Children)
 | |
|                 {
 | |
|                     if (parameter is not UhtProperty property)
 | |
|                     {
 | |
|                         continue;
 | |
|                     }
 | |
|                 
 | |
|                     PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(property)!;
 | |
|                     translator.ExportParameterStaticConstructor(generatorStringBuilder, property, function, property.SourceName, functionName);
 | |
|                 }
 | |
|             }
 | |
|             
 | |
|             generatorStringBuilder.TryEndWithEditor(function);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public static void ExportPropertiesStaticConstructor(GeneratorStringBuilder generatorStringBuilder, List<UhtProperty> exportedProperties)
 | |
|     {
 | |
|         foreach (UhtProperty property in exportedProperties)
 | |
|         {
 | |
|             ExportPropertyStaticConstructor(generatorStringBuilder, property);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     public static void ExportGetSetBackedPropertyStaticConstructor(GeneratorStringBuilder generatorStringBuilder, Dictionary<UhtProperty, GetterSetterPair> getSetBackedProperties)
 | |
|     {
 | |
|         foreach (KeyValuePair<UhtProperty, GetterSetterPair> pair in getSetBackedProperties)
 | |
|         {
 | |
|             ExportPropertyStaticConstructor(generatorStringBuilder, pair.Key);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     private static void ExportPropertyStaticConstructor(GeneratorStringBuilder generatorStringBuilder, UhtProperty property)
 | |
|     {
 | |
|         generatorStringBuilder.TryAddWithEditor(property);
 | |
|         PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(property)!;
 | |
|         translator.ExportPropertyStaticConstructor(generatorStringBuilder, property, property.SourceName);
 | |
|         generatorStringBuilder.TryEndWithEditor(property);
 | |
|     }
 | |
| } |