249 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			249 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 
								 | 
							
								using EpicGames.Core;
							 | 
						|||
| 
								 | 
							
								using EpicGames.UHT.Types;
							 | 
						|||
| 
								 | 
							
								using UnrealSharpScriptGenerator.Utilities;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								namespace UnrealSharpScriptGenerator.PropertyTranslators;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								public class ContainerPropertyTranslator : PropertyTranslator
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    public ContainerPropertyTranslator(string copyMarshallerName, string readOnlyMarshallerName, string marshallerName, string readOnlyInterfaceName, string interfaceName) : base(ContainerSupportedUsages)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        CopyMarshallerName = copyMarshallerName;
							 | 
						|||
| 
								 | 
							
								        ReadOnlyMarshallerName = readOnlyMarshallerName;
							 | 
						|||
| 
								 | 
							
								        MarshallerName = marshallerName;
							 | 
						|||
| 
								 | 
							
								        ReadOnlyInterfaceName = readOnlyInterfaceName;
							 | 
						|||
| 
								 | 
							
								        InterfaceName = interfaceName;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public readonly string CopyMarshallerName;
							 | 
						|||
| 
								 | 
							
								    public readonly string ReadOnlyMarshallerName;
							 | 
						|||
| 
								 | 
							
								    public readonly string MarshallerName;
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    public readonly string ReadOnlyInterfaceName;
							 | 
						|||
| 
								 | 
							
								    public readonly string InterfaceName;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public override bool IsBlittable => false;
							 | 
						|||
| 
								 | 
							
								    public override bool SupportsSetter => true;
							 | 
						|||
| 
								 | 
							
								    public override bool CacheProperty => true;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public override bool CanExport(UhtProperty property)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        UhtContainerBaseProperty containerProperty = (UhtContainerBaseProperty) property;
							 | 
						|||
| 
								 | 
							
								        PropertyTranslator? translator = PropertyTranslatorManager.GetTranslator(containerProperty.ValueProperty);
							 | 
						|||
| 
								 | 
							
								        return translator != null && translator.CanExport(containerProperty.ValueProperty) && translator.IsSupportedAsInner();
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public override string GetManagedType(UhtProperty property)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        return GetWrapperInterface(property);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public override string GetMarshaller(UhtProperty property)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        throw new System.NotImplementedException();
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public override string ExportMarshallerDelegates(UhtProperty property)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        throw new System.NotImplementedException();
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public override void ExportPropertyGetter(GeneratorStringBuilder builder, UhtProperty property, string propertyManagedName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        UhtContainerBaseProperty containerProperty = (UhtContainerBaseProperty) property;
							 | 
						|||
| 
								 | 
							
								        PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(containerProperty.ValueProperty)!;
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        string wrapperType = GetWrapperType(property);
							 | 
						|||
| 
								 | 
							
								        string marshallingDelegates = translator.ExportMarshallerDelegates(containerProperty.ValueProperty);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine($"{propertyManagedName}_Marshaller ??= new {wrapperType}({propertyManagedName}_NativeProperty, {marshallingDelegates});");
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine($"return {propertyManagedName}_Marshaller.FromNative(IntPtr.Add(NativeObject, {propertyManagedName}_Offset), 0);");
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public override void ExportPropertySetter(GeneratorStringBuilder builder, UhtProperty property, string propertyManagedName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        UhtContainerBaseProperty containerProperty = (UhtContainerBaseProperty)property;
							 | 
						|||
| 
								 | 
							
								        PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(containerProperty.ValueProperty)!;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        string wrapperType = GetWrapperType(property);
							 | 
						|||
| 
								 | 
							
								        string marshallingDelegates = translator.ExportMarshallerDelegates(containerProperty.ValueProperty);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine($"{propertyManagedName}_Marshaller ??= new {wrapperType}({propertyManagedName}_NativeProperty, {marshallingDelegates});");
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine($"{propertyManagedName}_Marshaller.ToNative(IntPtr.Add(NativeObject, {propertyManagedName}_Offset), value);");
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public override void ExportPropertyVariables(GeneratorStringBuilder builder, UhtProperty property, string propertyEngineName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        base.ExportPropertyVariables(builder, property, propertyEngineName);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (property.IsGenericType()) return;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        string wrapperType = GetWrapperType(property);
							 | 
						|||
| 
								 | 
							
								        if (property.IsOuter<UhtScriptStruct>() || property.HasAnyNativeGetterSetter())
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"static {wrapperType} {propertyEngineName}_Marshaller = null;");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"{wrapperType} {propertyEngineName}_Marshaller = null;");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public override void ExportParameterVariables(GeneratorStringBuilder builder, UhtFunction function,
							 | 
						|||
| 
								 | 
							
								        string nativeMethodName,
							 | 
						|||
| 
								 | 
							
								        UhtProperty property, string propertyEngineName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        base.ExportParameterVariables(builder, function, nativeMethodName, property, propertyEngineName);
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine($"static IntPtr {nativeMethodName}_{propertyEngineName}_NativeProperty;");
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (property.IsGenericType()) return;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        string wrapperType = GetWrapperType(property);
							 | 
						|||
| 
								 | 
							
								        if (function.FunctionFlags.HasAnyFlags(EFunctionFlags.Static))
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"static {wrapperType} {nativeMethodName}_{propertyEngineName}_Marshaller = null;");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"{wrapperType} {nativeMethodName}_{propertyEngineName}_Marshaller = null;");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public override void ExportParameterStaticConstructor(GeneratorStringBuilder builder, UhtProperty property,
							 | 
						|||
| 
								 | 
							
								        UhtFunction function, string propertyEngineName, string functionName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        base.ExportParameterStaticConstructor(builder, property, function, propertyEngineName, functionName);
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine($"{functionName}_{propertyEngineName}_NativeProperty = {ExporterCallbacks.FPropertyCallbacks}.CallGetNativePropertyFromName({functionName}_NativeFunction, \"{propertyEngineName}\");");
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public override string GetNullValue(UhtProperty property)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        return "null";
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    public override string ConvertCPPDefaultValue(string defaultValue, UhtFunction function, UhtProperty parameter)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        throw new System.NotImplementedException();
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    public override void ExportFromNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName, string assignmentOrReturn,
							 | 
						|||
| 
								 | 
							
								        string sourceBuffer, string offset, bool bCleanupSourceBuffer, bool reuseRefMarshallers)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        UhtContainerBaseProperty containerProperty = (UhtContainerBaseProperty) property;
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        UhtProperty valueProperty = containerProperty.ValueProperty;
							 | 
						|||
| 
								 | 
							
								        PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(valueProperty)!;
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        string nativeProperty = $"{propertyName}_NativeProperty";
							 | 
						|||
| 
								 | 
							
								        string marshaller = $"{propertyName}_Marshaller";
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (property.Outer is UhtFunction function)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            string nativeMethodName = function.SourceName;
							 | 
						|||
| 
								 | 
							
								            nativeProperty = $"{nativeMethodName}_{nativeProperty}";
							 | 
						|||
| 
								 | 
							
								            marshaller = $"{nativeMethodName}_{marshaller}";
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        string marshallerType = GetWrapperType(property);
							 | 
						|||
| 
								 | 
							
								        string marshallingDelegates = translator.ExportMarshallerDelegates(valueProperty);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (!reuseRefMarshallers)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (property.IsGenericType())
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                builder.AppendLine($"var {marshaller} = new {marshallerType}({nativeProperty}, {marshallingDelegates});");
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            else
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                builder.AppendLine($"{marshaller} ??= new {marshallerType}({nativeProperty}, {marshallingDelegates});");
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"IntPtr {propertyName}_NativeBuffer = IntPtr.Add({sourceBuffer}, {offset});");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine($"{assignmentOrReturn} {marshaller}.FromNative({propertyName}_NativeBuffer, 0);");
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        if (bCleanupSourceBuffer)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            ExportCleanupMarshallingBuffer(builder, property, propertyName);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    public override void ExportToNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName, string destinationBuffer,
							 | 
						|||
| 
								 | 
							
								        string offset, string source)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        UhtContainerBaseProperty containerProperty = (UhtContainerBaseProperty) property;
							 | 
						|||
| 
								 | 
							
								        UhtProperty valueProperty = containerProperty.ValueProperty;
							 | 
						|||
| 
								 | 
							
								        PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(valueProperty)!;
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        string nativeProperty = $"{propertyName}_NativeProperty";
							 | 
						|||
| 
								 | 
							
								        string marshaller = $"{propertyName}_Marshaller";
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (property.Outer is UhtFunction function)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            string nativeMethodName = function.SourceName;
							 | 
						|||
| 
								 | 
							
								            nativeProperty = $"{nativeMethodName}_{nativeProperty}";
							 | 
						|||
| 
								 | 
							
								            marshaller = $"{nativeMethodName}_{marshaller}";
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        string marshallerType = GetWrapperType(property);
							 | 
						|||
| 
								 | 
							
								        string marshallingDelegates = translator.ExportMarshallerDelegates(valueProperty);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (property.IsGenericType())
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"var {marshaller} = new {marshallerType}({nativeProperty}, {marshallingDelegates});");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            builder.AppendLine($"{marshaller} ??= new {marshallerType}({nativeProperty}, {marshallingDelegates});");
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine($"IntPtr {propertyName}_NativeBuffer = IntPtr.Add({destinationBuffer}, {offset});");
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine($"{marshaller}.ToNative({propertyName}_NativeBuffer, 0, {source});");
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public override void ExportCleanupMarshallingBuffer(GeneratorStringBuilder builder, UhtProperty property, string paramName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        string nativeMethodName = "";
							 | 
						|||
| 
								 | 
							
								        if (property.Outer is UhtFunction function)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            nativeMethodName = function.SourceName + "_";
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        
							 | 
						|||
| 
								 | 
							
								        string marshaller = $"{nativeMethodName}{paramName}_Marshaller";
							 | 
						|||
| 
								 | 
							
								        builder.AppendLine($"{marshaller}.DestructInstance({paramName}_NativeBuffer, 0);");
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    private string GetWrapperType(UhtProperty property)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        bool isStructProperty = property.IsOuter<UhtScriptStruct>();
							 | 
						|||
| 
								 | 
							
								        bool isParameter = property.IsOuter<UhtFunction>();
							 | 
						|||
| 
								 | 
							
								        bool isNativeGetterSetter = property.HasAnyNativeGetterSetter();
							 | 
						|||
| 
								 | 
							
								        UhtContainerBaseProperty containerProperty = (UhtContainerBaseProperty) property;
							 | 
						|||
| 
								 | 
							
								        PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(containerProperty.ValueProperty)!;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        string innerManagedType = property.IsGenericType() ?
							 | 
						|||
| 
								 | 
							
								            "DOT" : translator.GetManagedType(containerProperty.ValueProperty);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        string containerType = isStructProperty || isParameter || isNativeGetterSetter ? CopyMarshallerName : property.PropertyFlags.HasAnyFlags(EPropertyFlags.BlueprintReadOnly) ? ReadOnlyMarshallerName : MarshallerName;
							 | 
						|||
| 
								 | 
							
								        return $"{containerType}<{innerManagedType}>";
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    private string GetWrapperInterface(UhtProperty property)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        UhtContainerBaseProperty containerProperty = (UhtContainerBaseProperty) property;
							 | 
						|||
| 
								 | 
							
								        PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(containerProperty.ValueProperty)!;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        string innerManagedType = property.IsGenericType() ? 
							 | 
						|||
| 
								 | 
							
								            "DOT" : translator.GetManagedType(containerProperty.ValueProperty);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        string interfaceType = property.PropertyFlags.HasAnyFlags(EPropertyFlags.BlueprintReadOnly) ? ReadOnlyInterfaceName : InterfaceName;
							 | 
						|||
| 
								 | 
							
								        return $"System.Collections.Generic.{interfaceType}<{innerManagedType}>";
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public override bool CanSupportGenericType(UhtProperty property)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        UhtContainerBaseProperty containerProperty = (UhtContainerBaseProperty)property;
							 | 
						|||
| 
								 | 
							
								        PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(containerProperty.ValueProperty)!;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        return translator.CanSupportGenericType(containerProperty.ValueProperty);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 |