593 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			593 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 
								 | 
							
								using EpicGames.Core;
							 | 
						|||
| 
								 | 
							
								using EpicGames.UHT.Types;
							 | 
						|||
| 
								 | 
							
								using System;
							 | 
						|||
| 
								 | 
							
								using System.Collections.Generic;
							 | 
						|||
| 
								 | 
							
								using System.Linq;
							 | 
						|||
| 
								 | 
							
								using System.Text;
							 | 
						|||
| 
								 | 
							
								using System.Xml.Linq;
							 | 
						|||
| 
								 | 
							
								using UnrealSharpScriptGenerator.Exporters;
							 | 
						|||
| 
								 | 
							
								using UnrealSharpScriptGenerator.Tooltip;
							 | 
						|||
| 
								 | 
							
								using UnrealSharpScriptGenerator.Utilities;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								namespace UnrealSharpScriptGenerator.PropertyTranslators;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								public abstract class PropertyTranslator
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    private readonly PropertyKind _propertyKind;
							 | 
						|||
| 
								 | 
							
								    private readonly EPropertyUsageFlags _supportedPropertyUsage;
							 | 
						|||
| 
								 | 
							
								    protected const EPropertyUsageFlags ContainerSupportedUsages = EPropertyUsageFlags.Property
							 | 
						|||
| 
								 | 
							
								                                                                   | EPropertyUsageFlags.StructProperty
							 | 
						|||
| 
								 | 
							
								                                                                   | EPropertyUsageFlags.Parameter
							 | 
						|||
| 
								 | 
							
								                                                                   | EPropertyUsageFlags.ReturnValue;
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    public bool IsSupportedAsProperty() => _supportedPropertyUsage.HasFlag(EPropertyUsageFlags.Property);
							 | 
						|||
| 
								 | 
							
								    public bool IsSupportedAsParameter() => _supportedPropertyUsage.HasFlag(EPropertyUsageFlags.Parameter);
							 | 
						|||
| 
								 | 
							
								    public bool IsSupportedAsReturnValue() => _supportedPropertyUsage.HasFlag(EPropertyUsageFlags.ReturnValue);
							 | 
						|||
| 
								 | 
							
								    public bool IsSupportedAsInner() => _supportedPropertyUsage.HasFlag(EPropertyUsageFlags.Inner);
							 | 
						|||
| 
								 | 
							
								    public bool IsSupportedAsStructProperty() => _supportedPropertyUsage.HasFlag(EPropertyUsageFlags.StructProperty);
							 | 
						|||
| 
								 | 
							
								    public PropertyKind PropertyKind => _propertyKind;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public bool IsPrimitive => _propertyKind == PropertyKind.SByte ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.Byte ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.Short||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.UShort ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.Int ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.UInt ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.Long ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.ULong ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.Float ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.Double ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.Bool ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.String ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.Enum;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public bool IsNumeric => _propertyKind == PropertyKind.Byte ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.SByte ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.Short ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.UShort ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.Int ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.UInt ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.Long ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.ULong ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.Float ||
							 | 
						|||
| 
								 | 
							
								        _propertyKind == PropertyKind.Double;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    // Is this property the same memory layout as the C++ type?
							 | 
						|||
| 
								 | 
							
								    public virtual bool IsBlittable => false;
							 | 
						|||
| 
								 | 
							
								    public virtual bool SupportsSetter => true;
							 | 
						|||
| 
								 | 
							
								    public virtual bool ExportDefaultParameter => true;
							 | 
						|||
| 
								 | 
							
								    public virtual bool CacheProperty => false;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    // Should this property be declared as a parameter in the function signature? 
							 | 
						|||
| 
								 | 
							
								    // A property can support being a parameter but not be declared as one, such as WorldContextObjectPropertyTranslator
							 | 
						|||
| 
								 | 
							
								    public virtual bool ShouldBeDeclaredAsParameter => true;
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    public PropertyTranslator(EPropertyUsageFlags supportedPropertyUsage, 
							 | 
						|||
| 
								 | 
							
								        PropertyKind propertyKind = PropertyKind.Unknown)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        _supportedPropertyUsage = supportedPropertyUsage;
							 | 
						|||
| 
								 | 
							
								        _propertyKind = propertyKind;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    // Can we export this property?
							 | 
						|||
| 
								 | 
							
								    public abstract bool CanExport(UhtProperty property);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    // Can we support generic types?
							 | 
						|||
| 
								 | 
							
								    public abstract bool CanSupportGenericType(UhtProperty property);
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    // Can we support custom structs?
							 | 
						|||
| 
								 | 
							
								    public virtual bool CanSupportCustomStruct(UhtProperty property) => false;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    // Get the managed type for this property
							 | 
						|||
| 
								 | 
							
								    // Example: "int" for a property of type "int32"
							 | 
						|||
| 
								 | 
							
								    public abstract string GetManagedType(UhtProperty property);
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    // Get the marshaller for this property to marshal back and forth between C++ and C#
							 | 
						|||
| 
								 | 
							
								    public abstract string GetMarshaller(UhtProperty property);
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    // Get the marshaller delegates for this property
							 | 
						|||
| 
								 | 
							
								    public abstract string ExportMarshallerDelegates(UhtProperty property);
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    // Get the null value for this property
							 | 
						|||
| 
								 | 
							
								    public virtual string GetNullValue(UhtProperty property) => $"default({GetManagedType(property)})";
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    public virtual void ExportPropertyStaticConstructor(GeneratorStringBuilder builder, UhtProperty property, string nativePropertyName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        string propertyPointerName = property.GetNativePropertyName();
							 | 
						|||
| 
								 | 
							
								        bool hasNativeGetterSetter = property.HasAnyNativeGetterSetter();
							 | 
						|||
| 
								 | 
							
								        bool hasBlueprintGetterSetter = property.HasBlueprintGetterSetterPair();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        string adjustedNativePropertyName = nativePropertyName;
							 | 
						|||
| 
								 | 
							
								        if (property.Deprecated)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            int index = nativePropertyName.IndexOf("_DEPRECATED", StringComparison.OrdinalIgnoreCase);
							 | 
						|||
| 
								 | 
							
								            adjustedNativePropertyName = index != -1 ? nativePropertyName.Substring(0, index) : nativePropertyName;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (hasNativeGetterSetter || !hasBlueprintGetterSetter)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            string variableDeclaration = CacheProperty || hasNativeGetterSetter ? "" : "IntPtr ";
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"{variableDeclaration}{propertyPointerName} = {ExporterCallbacks.FPropertyCallbacks}.CallGetNativePropertyFromName(NativeClassPtr, \"{adjustedNativePropertyName}\");");
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"{nativePropertyName}_Offset = {ExporterCallbacks.FPropertyCallbacks}.CallGetPropertyOffset({propertyPointerName});");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        if (hasNativeGetterSetter)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"{nativePropertyName}_Size = {ExporterCallbacks.FPropertyCallbacks}.CallGetSize({propertyPointerName});");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        // Export the static constructors for the getter and setter
							 | 
						|||
| 
								 | 
							
								        TryExportGetterSetterStaticConstructor(property, builder);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    private void TryExportGetterSetterStaticConstructor(UhtProperty property, GeneratorStringBuilder builder)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        if (!property.HasNativeGetter())
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            UhtFunction? getter = property.GetBlueprintGetter();
							 | 
						|||
| 
								 | 
							
								            if (getter != null)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                StaticConstructorUtilities.ExportClassFunctionStaticConstructor(builder, getter);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        if (!property.HasNativeSetter())
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            UhtFunction? setter = property.GetBlueprintSetter();
							 | 
						|||
| 
								 | 
							
								            if (setter != null)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                StaticConstructorUtilities.ExportClassFunctionStaticConstructor(builder, setter);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    public virtual void ExportParameterStaticConstructor(GeneratorStringBuilder builder, UhtProperty property, UhtFunction function, string propertyEngineName, string functionName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        string variableName = $"{functionName}_{propertyEngineName}_{(property.GetPrecedingCustomStructParams() > 0 ? "NativeOffset" : "Offset")}";
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine($"{variableName} = {ExporterCallbacks.FPropertyCallbacks}.CallGetPropertyOffsetFromName({functionName}_NativeFunction, \"{propertyEngineName}\");");
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    public virtual void ExportPropertyVariables(GeneratorStringBuilder builder, UhtProperty property, string propertyEngineName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine($"static int {propertyEngineName}_Offset;");
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        if (property.HasAnyGetterOrSetter() || CacheProperty)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            AddNativePropertyField(builder, propertyEngineName);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        if (property.HasAnyGetterOrSetter())
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"static int {propertyEngineName}_Size;");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    public virtual void ExportParameterVariables(GeneratorStringBuilder builder, UhtFunction function, string nativeMethodName, UhtProperty property, string propertyEngineName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        if (function.HasCustomStructParamSupport())
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            List<UhtProperty> precedingParams = property.GetPrecedingParams()!;
							 | 
						|||
| 
								 | 
							
								            int precedingCustomStructProperties = precedingParams.Count(param => param.IsCustomStructureType());
							 | 
						|||
| 
								 | 
							
								            if (precedingCustomStructProperties > 0)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                builder.AppendLine($"static int {nativeMethodName}_{propertyEngineName}_NativeOffset;");
							 | 
						|||
| 
								 | 
							
								                List<string> customStructParamTypes =
							 | 
						|||
| 
								 | 
							
								                    function.GetCustomStructParamTypes().GetRange(0, precedingCustomStructProperties);
							 | 
						|||
| 
								 | 
							
								                builder.AppendLine($"static int {nativeMethodName}_{propertyEngineName}_Offset<{string.Join(", ", customStructParamTypes)}>()");
							 | 
						|||
| 
								 | 
							
								                builder.Indent();
							 | 
						|||
| 
								 | 
							
								                foreach (string customStructParamType in customStructParamTypes)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    builder.AppendLine($"where {customStructParamType} : MarshalledStruct<{customStructParamType}>");
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                string variableNames = string.Join(" + ",
							 | 
						|||
| 
								 | 
							
								                    customStructParamTypes.ConvertAll(customStructParamType =>
							 | 
						|||
| 
								 | 
							
								                        $"{customStructParamType}.GetNativeDataSize()"));
							 | 
						|||
| 
								 | 
							
								                string nativeOffsetSubtractionMultiplier = string.Empty;
							 | 
						|||
| 
								 | 
							
								                if (precedingCustomStructProperties > 1)
							 | 
						|||
| 
								 | 
							
								                    nativeOffsetSubtractionMultiplier += $"{precedingCustomStructProperties} * ";
							 | 
						|||
| 
								 | 
							
								                builder.AppendLine($"=> {nativeMethodName}_{propertyEngineName}_NativeOffset + {variableNames} - {nativeOffsetSubtractionMultiplier}sizeof(int);");
							 | 
						|||
| 
								 | 
							
								                builder.UnIndent();
							 | 
						|||
| 
								 | 
							
								                return;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine($"static int {nativeMethodName}_{propertyEngineName}_Offset;");
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public virtual void ExportPropertyGetter(GeneratorStringBuilder builder, UhtProperty property, string propertyManagedName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        ExportFromNative(builder, property, propertyManagedName, "return", "NativeObject", $"{propertyManagedName}_Offset", false, false);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public virtual void ExportPropertySetter(GeneratorStringBuilder builder, UhtProperty property, string propertyManagedName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        ExportToNative(builder, property, propertyManagedName, "NativeObject", $"{propertyManagedName}_Offset", "value");
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public virtual void ExportCppDefaultParameterAsLocalVariable(GeneratorStringBuilder builder, string variableName,
							 | 
						|||
| 
								 | 
							
								        string defaultValue, UhtFunction function, UhtProperty paramProperty)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public virtual void ExportFunctionReturnStatement(GeneratorStringBuilder builder,
							 | 
						|||
| 
								 | 
							
								        UhtProperty property,
							 | 
						|||
| 
								 | 
							
								        string nativePropertyName, 
							 | 
						|||
| 
								 | 
							
								        string functionName, 
							 | 
						|||
| 
								 | 
							
								        string paramsCallString)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        throw new NotImplementedException();
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    // Cleanup the marshalling buffer
							 | 
						|||
| 
								 | 
							
								    public virtual void ExportCleanupMarshallingBuffer(GeneratorStringBuilder builder, UhtProperty property,
							 | 
						|||
| 
								 | 
							
								        string paramName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    // Build the C# code to marshal this property from C++ to C#
							 | 
						|||
| 
								 | 
							
								    public abstract void ExportFromNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName,
							 | 
						|||
| 
								 | 
							
								        string assignmentOrReturn, string sourceBuffer, string offset, bool bCleanupSourceBuffer,
							 | 
						|||
| 
								 | 
							
								        bool reuseRefMarshallers);
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    // Build the C# code to marshal this property from C# to C++
							 | 
						|||
| 
								 | 
							
								    public abstract void ExportToNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName, string destinationBuffer, string offset, string source);
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    // Convert a C++ default value to a C# default value
							 | 
						|||
| 
								 | 
							
								    // Example: "0.0f" for a float property
							 | 
						|||
| 
								 | 
							
								    public abstract string ConvertCPPDefaultValue(string defaultValue, UhtFunction function, UhtProperty parameter);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public void ExportConstructor()
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public void ExportCustomProperty(GeneratorStringBuilder builder, GetterSetterPair getterSetterPair, 
							 | 
						|||
| 
								 | 
							
								                                     string propertyName, UhtProperty property, bool isExplicitImplementation = false,
							 | 
						|||
| 
								 | 
							
								                                     HashSet<string>? exportedFunctionNames = null)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        GetterSetterFunctionExporter? getterExporter = getterSetterPair.GetterExporter;
							 | 
						|||
| 
								 | 
							
								        GetterSetterFunctionExporter? setterExporter = getterSetterPair.SetterExporter;
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        void ExportBackingFields()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (getterExporter != null && (exportedFunctionNames is null || !exportedFunctionNames.Contains(getterExporter.Function.SourceName)))
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                getterExporter.ExportFunctionVariables(builder);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            
							 | 
						|||
| 
								 | 
							
								            if (setterExporter != null && (exportedFunctionNames is null || !exportedFunctionNames.Contains(setterExporter.Function.SourceName)))
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                setterExporter.ExportFunctionVariables(builder);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        string ExportProtection()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (setterExporter != null)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                return setterExporter.Modifiers;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            
							 | 
						|||
| 
								 | 
							
								            if (getterExporter != null)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                return getterExporter.Modifiers;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            
							 | 
						|||
| 
								 | 
							
								            throw new InvalidOperationException("No getter or setter found");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        Action? exportGetterAction = getterExporter != null ? () => AppendInvoke(builder, getterExporter) : null;
							 | 
						|||
| 
								 | 
							
								        Action? exportSetterAction = setterExporter != null ? () => AppendInvoke(builder, setterExporter) : null;
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        string? interfaceName = isExplicitImplementation ? getterSetterPair.Accessors.First().Outer?.GetFullManagedName() : null;
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        ExportProperty_Internal(builder, property, propertyName, ExportBackingFields, ExportProtection, exportGetterAction, exportSetterAction, interfaceName: interfaceName);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    public void ExportGetSetProperty(GeneratorStringBuilder builder, GetterSetterPair getterSetterPair, UhtProperty property, 
							 | 
						|||
| 
								 | 
							
								                                     Dictionary<UhtFunction, FunctionExporter> exportedGetterSetters,
							 | 
						|||
| 
								 | 
							
								                                     HashSet<string>? exportedFunctionName = null)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        void ExportNativeGetter()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.BeginUnsafeBlock();
							 | 
						|||
| 
								 | 
							
								            builder.AppendStackAllocProperty($"{property.SourceName}_Size", property.GetNativePropertyName());
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"FPropertyExporter.CallGetValue_InContainer({property.GetNativePropertyName()}, NativeObject, paramsBuffer);");
							 | 
						|||
| 
								 | 
							
								            ExportFromNative(builder, property, property.SourceName, $"{GetManagedType(property)} newValue =", "paramsBuffer", "0", true, false);
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine("return newValue;");
							 | 
						|||
| 
								 | 
							
								            builder.EndUnsafeBlock();
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        void ExportBlueprintGetter()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            AppendInvoke(builder, getterSetterPair.GetterExporter!);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        void ExportGetter()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            ExportPropertyGetter(builder, property, property.SourceName);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        void ExportNativeSetter()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.BeginUnsafeBlock();
							 | 
						|||
| 
								 | 
							
								            builder.AppendStackAllocProperty($"{property.SourceName}_Size", property.GetNativePropertyName());
							 | 
						|||
| 
								 | 
							
								            ExportToNative(builder, property, property.SourceName, "paramsBuffer", "0", "value");
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"FPropertyExporter.CallSetValue_InContainer({property.GetNativePropertyName()}, NativeObject, paramsBuffer);"); 
							 | 
						|||
| 
								 | 
							
								            ExportCleanupMarshallingBuffer(builder, property, property.SourceName);
							 | 
						|||
| 
								 | 
							
								            builder.EndUnsafeBlock();
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        void ExportBlueprintSetter()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            AppendInvoke(builder, getterSetterPair.SetterExporter!);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        void ExportSetter()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            ExportPropertySetter(builder, property, property.SourceName);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        Action? exportGetterAction;
							 | 
						|||
| 
								 | 
							
								        if (property.HasNativeGetter())
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            exportGetterAction = ExportNativeGetter;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else if (getterSetterPair.GetterExporter != null)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            exportGetterAction = ExportBlueprintGetter;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            exportGetterAction = ExportGetter;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        Action? exportSetterAction = null;
							 | 
						|||
| 
								 | 
							
								        if (property.HasNativeSetter())
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            exportSetterAction = ExportNativeSetter;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else if (getterSetterPair.SetterExporter != null)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            exportSetterAction = ExportBlueprintSetter;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else if (SupportsSetter && property.IsReadWrite())
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            exportSetterAction = ExportSetter;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        void ExportBackingFields()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (getterSetterPair.GetterExporter is not null && !exportedGetterSetters.ContainsKey(getterSetterPair.Getter!) && (exportedFunctionName is null || !exportedFunctionName.Contains(getterSetterPair.Getter!.SourceName)))
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                getterSetterPair.GetterExporter.ExportFunctionVariables(builder);
							 | 
						|||
| 
								 | 
							
								                exportedGetterSetters.Add(getterSetterPair.Getter!, getterSetterPair.GetterExporter);
							 | 
						|||
| 
								 | 
							
								            }   
							 | 
						|||
| 
								 | 
							
								            
							 | 
						|||
| 
								 | 
							
								            if (getterSetterPair.SetterExporter is not null && !exportedGetterSetters.ContainsKey(getterSetterPair.Setter!) && (exportedFunctionName is null || !exportedFunctionName.Contains(getterSetterPair.Setter!.SourceName)))
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                getterSetterPair.SetterExporter.ExportFunctionVariables(builder);
							 | 
						|||
| 
								 | 
							
								                exportedGetterSetters.Add(getterSetterPair.Setter!, getterSetterPair.SetterExporter);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            if (getterSetterPair.GetterExporter is null || getterSetterPair.SetterExporter is null)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                ExportPropertyVariables(builder, property, property.SourceName);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        ExportProperty_Internal(builder, property, getterSetterPair.PropertyName, ExportBackingFields, null, exportGetterAction, exportSetterAction); 
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    public void ExportProperty(GeneratorStringBuilder builder, UhtProperty property)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        void ExportGetter()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            ExportPropertyGetter(builder, property, property.SourceName);  
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        void ExportSetter()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            ExportPropertySetter(builder, property, property.SourceName);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        void ExportBackingFields()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            ExportPropertyVariables(builder, property, property.SourceName);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        bool isReadWrite = property.IsReadWrite();
							 | 
						|||
| 
								 | 
							
								        bool isEditDefaultsOnly = property.IsEditDefaultsOnly();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        Action? exportSetterAction = SupportsSetter && (isReadWrite || isEditDefaultsOnly) ? ExportSetter : null;
							 | 
						|||
| 
								 | 
							
								        string setterOperation = isEditDefaultsOnly && !isReadWrite ? "init" : "set";
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        ExportProperty_Internal(builder, property, property.GetPropertyName(), ExportBackingFields, null, ExportGetter, exportSetterAction, setterOperation); 
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    private void ExportProperty_Internal(GeneratorStringBuilder builder, UhtProperty property, string propertyName, 
							 | 
						|||
| 
								 | 
							
								        Action? backingFieldsExport,
							 | 
						|||
| 
								 | 
							
								        Func<string>? exportProtection,
							 | 
						|||
| 
								 | 
							
								        Action? exportGetter, 
							 | 
						|||
| 
								 | 
							
								        Action? exportSetter,
							 | 
						|||
| 
								 | 
							
								        string setterOperation = "set",
							 | 
						|||
| 
								 | 
							
								        string? interfaceName = null)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine();
							 | 
						|||
| 
								 | 
							
								        builder.TryAddWithEditor(property);
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        if (backingFieldsExport is not null)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            backingFieldsExport();
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine();
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        string protection = exportProtection != null ? exportProtection.Invoke() : property.GetProtection();
							 | 
						|||
| 
								 | 
							
								        builder.AppendTooltip(property);
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        string managedType = GetManagedType(property);
							 | 
						|||
| 
								 | 
							
								        if (interfaceName is not null)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"{managedType} {interfaceName}.{propertyName}");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"{protection}{managedType} {propertyName}");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        builder.OpenBrace();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (exportGetter is not null)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine("get");
							 | 
						|||
| 
								 | 
							
								            builder.OpenBrace();
							 | 
						|||
| 
								 | 
							
								            exportGetter();
							 | 
						|||
| 
								 | 
							
								            builder.CloseBrace();
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (exportSetter is not null)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine(setterOperation);
							 | 
						|||
| 
								 | 
							
								            builder.OpenBrace();
							 | 
						|||
| 
								 | 
							
								            exportSetter();
							 | 
						|||
| 
								 | 
							
								            builder.CloseBrace();
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        builder.CloseBrace();
							 | 
						|||
| 
								 | 
							
								        builder.TryEndWithEditor(property);
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine();
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    private void AppendInvoke(GeneratorStringBuilder builder, FunctionExporter exportedFunction)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        exportedFunction.ExportInvoke(builder);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public void ExportMirrorProperty(UhtStruct structObj, GeneratorStringBuilder builder, UhtProperty property, bool suppressOffsets, List<string> reservedNames, bool isReadOnly, bool useProperties)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        string propertyScriptName = property.GetPropertyName();
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine($"// {propertyScriptName}");
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine();
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        if (!suppressOffsets)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            ExportPropertyVariables(builder, property, property.SourceName);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        string protection = property.GetProtection();
							 | 
						|||
| 
								 | 
							
								        string managedType = GetManagedType(property);
							 | 
						|||
| 
								 | 
							
								        string required = property.HasMetadata("Required") ? "required " : "";;
							 | 
						|||
| 
								 | 
							
								        builder.AppendTooltip(property);
							 | 
						|||
| 
								 | 
							
								        if (structObj.IsStructNativelyCopyable())
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"{protection}{required}{managedType} {propertyScriptName}");
							 | 
						|||
| 
								 | 
							
								            builder.OpenBrace();
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine("get");
							 | 
						|||
| 
								 | 
							
								            builder.OpenBrace();
							 | 
						|||
| 
								 | 
							
								            GenerateMirrorPropertyBody(structObj, builder, property, true);
							 | 
						|||
| 
								 | 
							
								            builder.CloseBrace();
							 | 
						|||
| 
								 | 
							
								            
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine(isReadOnly ? "init" : "set");
							 | 
						|||
| 
								 | 
							
								            builder.OpenBrace();
							 | 
						|||
| 
								 | 
							
								            GenerateMirrorPropertyBody(structObj, builder, property, false);
							 | 
						|||
| 
								 | 
							
								            builder.CloseBrace();
							 | 
						|||
| 
								 | 
							
								            builder.CloseBrace();
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else if (useProperties)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            string setter = isReadOnly ? "init;" : "set;";
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"{protection}{required}{managedType} {propertyScriptName} {{ get; {setter} }}");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            string @readonly = isReadOnly ? "readonly " : "";
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"{protection}{required}{@readonly}{managedType} {propertyScriptName};");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine();
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    private void GenerateMirrorPropertyBody(UhtStruct structObj, GeneratorStringBuilder builder, UhtProperty property, bool isGetter)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        bool isDestructible = structObj.IsStructNativelyDestructible();
							 | 
						|||
| 
								 | 
							
								        builder.BeginUnsafeBlock();
							 | 
						|||
| 
								 | 
							
								        if (isDestructible)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine("if (NativeHandle is null)");
							 | 
						|||
| 
								 | 
							
								            builder.OpenBrace();
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine("NativeHandle = new NativeStructHandle(NativeClassPtr);");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine("if (Allocation is null)");
							 | 
						|||
| 
								 | 
							
								            builder.OpenBrace();
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine("Allocation = new byte[NativeDataSize];");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        builder.CloseBrace();
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (isDestructible)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine("fixed (NativeStructHandleData* StructDataPointer = &NativeHandle.Data)");
							 | 
						|||
| 
								 | 
							
								            builder.OpenBrace();
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"IntPtr AllocationPointer = {ExporterCallbacks.UScriptStructCallbacks}.CallGetStructLocation(StructDataPointer, NativeClassPtr);");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine("fixed (byte* AllocationPointer = Allocation)");
							 | 
						|||
| 
								 | 
							
								            builder.OpenBrace();
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (isGetter)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            ExportFromNative(builder, property, property.SourceName, "return", "(IntPtr) AllocationPointer", $"{property.SourceName}_Offset", false, false);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            ExportToNative(builder, property, property.SourceName, "(IntPtr) AllocationPointer", $"{property.SourceName}_Offset", "value");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        builder.CloseBrace();
							 | 
						|||
| 
								 | 
							
								        builder.CloseBrace();
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public string GetCppDefaultValue(UhtFunction function, UhtProperty parameter)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        string metaDataKey = $"CPP_Default_{parameter.SourceName}";
							 | 
						|||
| 
								 | 
							
								        return function.GetMetadata(metaDataKey);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    protected void AddNativePropertyField(GeneratorStringBuilder builder, string propertyName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine($"static IntPtr {GetNativePropertyField(propertyName)};");
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    protected string GetNativePropertyField(string propertyName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        return $"{propertyName}_NativeProperty";
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public virtual void ExportPropertyArithmetic(GeneratorStringBuilder stringBuilder, UhtProperty property, ArithmeticKind arithmeticKind)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        string scriptName = property.GetScriptName();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        static string Bin(string op, string lhs, string rhs) => $"{lhs} {op} {rhs}";
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        string rhsExpr = arithmeticKind switch
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            ArithmeticKind.Add => Bin("+", $"lhs.{scriptName}", $"rhs.{scriptName}"),
							 | 
						|||
| 
								 | 
							
								            ArithmeticKind.Subtract => Bin("-", $"lhs.{scriptName}", $"rhs.{scriptName}"),
							 | 
						|||
| 
								 | 
							
								            ArithmeticKind.Multiply => Bin("*", $"lhs.{scriptName}", $"rhs.{scriptName}"),
							 | 
						|||
| 
								 | 
							
								            ArithmeticKind.Divide => Bin("/", $"lhs.{scriptName}", $"rhs.{scriptName}"),
							 | 
						|||
| 
								 | 
							
								            ArithmeticKind.Modulo => Bin("%", $"lhs.{scriptName}", $"rhs.{scriptName}"),
							 | 
						|||
| 
								 | 
							
								            _ => throw new NotSupportedException($"Arithmetic kind {arithmeticKind} not supported.")
							 | 
						|||
| 
								 | 
							
								        };
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        string managedType = GetManagedType(property);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        stringBuilder.Append($"{scriptName} = ({managedType})({rhsExpr})");
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 |