206 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			206 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using EpicGames.Core; | |||
|  | using EpicGames.UHT.Types; | |||
|  | using UnrealSharpScriptGenerator.Utilities; | |||
|  | 
 | |||
|  | namespace UnrealSharpScriptGenerator.PropertyTranslators; | |||
|  | 
 | |||
|  | public class OptionalPropertyTranslator : PropertyTranslator | |||
|  | { | |||
|  |     public OptionalPropertyTranslator() : base(ContainerSupportedUsages) | |||
|  |     { | |||
|  |          | |||
|  |     } | |||
|  |      | |||
|  |     public override bool CacheProperty => true; | |||
|  |      | |||
|  |     public override void ExportPropertyVariables(GeneratorStringBuilder builder, UhtProperty property, string propertyEngineName) | |||
|  |     { | |||
|  |         base.ExportPropertyVariables(builder, property, propertyEngineName); | |||
|  | 
 | |||
|  |         if (property.IsGenericType()) return; | |||
|  | 
 | |||
|  |         string wrapperType = GetMarshaller(property); | |||
|  |         builder.AppendLine($"static {wrapperType} {propertyEngineName}_Marshaller = null;"); | |||
|  |     } | |||
|  |      | |||
|  |     public override void ExportPropertyGetter(GeneratorStringBuilder builder, UhtProperty property, string propertyManagedName) | |||
|  |     { | |||
|  |         var containerProperty = (UhtOptionalProperty) property; | |||
|  |         PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(containerProperty.ValueProperty)!; | |||
|  |          | |||
|  |         string wrapperType = GetMarshaller(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 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 = GetMarshaller(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 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 = GetMarshaller(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 ExportCleanupMarshallingBuffer(GeneratorStringBuilder builder, UhtProperty property, | |||
|  |                                                        string paramName) | |||
|  |     { | |||
|  |         var optionalProperty = (UhtOptionalProperty)property; | |||
|  |         PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(optionalProperty.ValueProperty)!; | |||
|  |          | |||
|  |         // Blittable types, booleans, and enums are all trivially destructible, and thus don't need a cleanup. | |||
|  |         if (translator.IsBlittable || optionalProperty.ValueProperty is UhtBoolProperty or UhtEnumProperty) | |||
|  |         { | |||
|  |             return;        | |||
|  |         } | |||
|  |          | |||
|  |         string nativeMethodName = ""; | |||
|  |         if (property.Outer is UhtFunction function) | |||
|  |         { | |||
|  |             nativeMethodName = function.SourceName + "_"; | |||
|  |         } | |||
|  |          | |||
|  |         string marshaller = $"{nativeMethodName}{paramName}_Marshaller"; | |||
|  |         builder.AppendLine($"{marshaller}.DestructInstance({paramName}_NativeBuffer, 0);"); | |||
|  |     } | |||
|  |      | |||
|  |     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 = GetMarshaller(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 string ConvertCPPDefaultValue(string defaultValue, UhtFunction function, UhtProperty parameter) | |||
|  |     { | |||
|  |         throw new System.NotImplementedException(); | |||
|  |     } | |||
|  | 
 | |||
|  |     public override string GetManagedType(UhtProperty property) | |||
|  |     { | |||
|  |         if (property.IsGenericType()) return "DOT"; | |||
|  |          | |||
|  |         var optionalProperty = (UhtOptionalProperty)property; | |||
|  |         var translator = PropertyTranslatorManager.GetTranslator(optionalProperty.ValueProperty)!; | |||
|  |         return $"UnrealSharp.TOptional<{translator.GetManagedType(optionalProperty.ValueProperty)}>"; | |||
|  |     } | |||
|  | 
 | |||
|  |     public override string GetMarshaller(UhtProperty property) | |||
|  |     { | |||
|  |         if (property.Outer is UhtProperty outerProperty && outerProperty.IsGenericType()) | |||
|  |         { | |||
|  |             return "OptionalMarshaller<DOT>"; | |||
|  |         } | |||
|  | 
 | |||
|  |         var optionalProperty = (UhtOptionalProperty)property; | |||
|  |         var translator = PropertyTranslatorManager.GetTranslator(optionalProperty.ValueProperty)!; | |||
|  |         return $"OptionalMarshaller<{translator.GetManagedType(optionalProperty.ValueProperty)}>"; | |||
|  |     } | |||
|  |      | |||
|  |     public override string ExportMarshallerDelegates(UhtProperty property) | |||
|  |     { | |||
|  |         throw new System.NotImplementedException(); | |||
|  |     } | |||
|  |      | |||
|  |     public override string GetNullValue(UhtProperty property) | |||
|  |     { | |||
|  |         var optionalProperty = (UhtOptionalProperty)property; | |||
|  |         var translator = PropertyTranslatorManager.GetTranslator(optionalProperty.ValueProperty)!; | |||
|  |         return $"UnrealSharp.TOptional<{translator.GetManagedType(optionalProperty.ValueProperty)}>.None"; | |||
|  |     } | |||
|  | 
 | |||
|  |     public override bool CanExport(UhtProperty property) | |||
|  |     { | |||
|  |         var containerProperty = (UhtOptionalProperty) property; | |||
|  |         var translator = PropertyTranslatorManager.GetTranslator(containerProperty.ValueProperty); | |||
|  |         return translator != null && translator.CanExport(containerProperty.ValueProperty) && translator.IsSupportedAsInner(); | |||
|  |     } | |||
|  |      | |||
|  |     public override bool CanSupportGenericType(UhtProperty property) => true; | |||
|  | } |