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