| @ -0,0 +1,17 @@ | ||||
| using EpicGames.Core; | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class ArrayPropertyTranslator : ContainerPropertyTranslator | ||||
| { | ||||
|     public ArrayPropertyTranslator() | ||||
|         : base("ArrayCopyMarshaller", | ||||
|             "ArrayReadOnlyMarshaller", | ||||
|             "ArrayMarshaller", | ||||
|             "IReadOnlyList", | ||||
|             "IList") | ||||
|     { | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,26 @@ | ||||
| using EpicGames.UHT.Types; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class BlittableCustomStructTypePropertyTranslator : BlittableTypePropertyTranslator | ||||
| { | ||||
|     private readonly string _nativeName; | ||||
|     public override bool ExportDefaultParameter => false; | ||||
|      | ||||
|     public BlittableCustomStructTypePropertyTranslator(string nativeName, string managedType) : base(typeof(UhtStructProperty), managedType, PropertyKind.Unknown) | ||||
|     { | ||||
|         _nativeName = nativeName; | ||||
|     } | ||||
|  | ||||
|     public override bool CanExport(UhtProperty property) | ||||
|     { | ||||
|         UhtStructProperty structProperty = (UhtStructProperty) property; | ||||
|         return structProperty.ScriptStruct.SourceName == _nativeName; | ||||
|     } | ||||
|  | ||||
|     public override void ExportCppDefaultParameterAsLocalVariable(GeneratorStringBuilder builder, string variableName, string defaultValue, | ||||
|         UhtFunction function, UhtProperty paramProperty) | ||||
|     { | ||||
|         ExportDefaultStructParameter(builder, variableName, defaultValue, paramProperty, this); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,34 @@ | ||||
| using System; | ||||
| using System.Text; | ||||
| using EpicGames.Core; | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class BlittableStructPropertyTranslator : BlittableTypePropertyTranslator | ||||
| { | ||||
|     public BlittableStructPropertyTranslator() : base(typeof(UhtStructProperty), "", PropertyKind.Unknown) | ||||
|     { | ||||
|     } | ||||
|      | ||||
|     public override bool ExportDefaultParameter => false; | ||||
|  | ||||
|     public override bool CanExport(UhtProperty property) | ||||
|     { | ||||
|         UhtStructProperty structProperty = (UhtStructProperty) property; | ||||
|         return structProperty.ScriptStruct.IsStructBlittable(); | ||||
|     } | ||||
|  | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         UhtStructProperty structProperty = (UhtStructProperty) property; | ||||
|         return structProperty.ScriptStruct.GetFullManagedName(); | ||||
|     } | ||||
|  | ||||
|     public override void ExportCppDefaultParameterAsLocalVariable(GeneratorStringBuilder builder, string variableName, string defaultValue, | ||||
|         UhtFunction function, UhtProperty paramProperty) | ||||
|     { | ||||
|         ExportDefaultStructParameter(builder, variableName, defaultValue, paramProperty, this); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,28 @@ | ||||
| using System; | ||||
| using EpicGames.UHT.Types; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class BlittableTypePropertyTranslator : SimpleTypePropertyTranslator | ||||
| { | ||||
|     public BlittableTypePropertyTranslator(Type propertyType, string managedType, PropertyKind propertyKind) : | ||||
|         base(propertyType, managedType, propertyKind) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     public override bool ExportDefaultParameter => true; | ||||
|  | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
|         return $"BlittableMarshaller<{GetManagedType(property)}>"; | ||||
|     } | ||||
|      | ||||
|     public override void ExportCppDefaultParameterAsLocalVariable(GeneratorStringBuilder builder, string variableName, string defaultValue, | ||||
|         UhtFunction function, UhtProperty paramProperty) | ||||
|     { | ||||
|         string defaultValueString = ConvertCPPDefaultValue(defaultValue, function, paramProperty); | ||||
|         builder.AppendLine($"{ManagedType} {variableName} = {defaultValueString};"); | ||||
|     } | ||||
|  | ||||
|     public override bool CanSupportGenericType(UhtProperty property) => false; | ||||
| } | ||||
| @ -0,0 +1,85 @@ | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class BoolPropertyTranslator : SimpleTypePropertyTranslator | ||||
| { | ||||
|     private const string OffSetPostfix = "_Offset"; | ||||
|     private const string FieldMaskPostfix = "_FieldMask"; | ||||
|      | ||||
|     public BoolPropertyTranslator() : base(typeof(UhtBoolProperty), "bool", PropertyKind.Bool) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
|         return property.IsBitfield ? "BitfieldBoolMarshaller" : "BoolMarshaller"; | ||||
|     } | ||||
|  | ||||
|     public override void ExportPropertyStaticConstructor(GeneratorStringBuilder builder, UhtProperty property, string nativePropertyName) | ||||
|     { | ||||
|         if (property.IsBitfield && !property.HasGetterSetterPair()) | ||||
|         { | ||||
|             builder.AppendLine($"{GetFieldMaskFieldName(nativePropertyName)} = {ExporterCallbacks.FPropertyCallbacks}.CallGetBoolPropertyFieldMaskFromName(NativeClassPtr, \"{nativePropertyName}\");"); | ||||
|         } | ||||
|          | ||||
|         base.ExportPropertyStaticConstructor(builder, property, nativePropertyName); | ||||
|     } | ||||
|      | ||||
|     public override void ExportPropertyVariables(GeneratorStringBuilder builder, UhtProperty property, string propertyEngineName) | ||||
|     { | ||||
|         if (property.IsBitfield) | ||||
|         { | ||||
|             builder.AppendLine($"static byte {GetFieldMaskFieldName(propertyEngineName)};"); | ||||
|         } | ||||
|      | ||||
|         base.ExportPropertyVariables(builder, property, propertyEngineName); | ||||
|     } | ||||
|      | ||||
|     public override void ExportToNative( | ||||
|         GeneratorStringBuilder builder,  | ||||
|         UhtProperty property,  | ||||
|         string propertyName,  | ||||
|         string destinationBuffer, | ||||
|         string offset,  | ||||
|         string source) | ||||
|     { | ||||
|         if (property.IsBitfield) | ||||
|         { | ||||
|             builder.AppendLine($"{GetMarshaller(property)}.ToNative(IntPtr.Add({destinationBuffer}, {offset}), {GetFieldMaskFieldName(propertyName)}, {source});"); | ||||
|             return; | ||||
|         } | ||||
|          | ||||
|         base.ExportToNative(builder, property, propertyName, destinationBuffer, offset, source); | ||||
|     } | ||||
|  | ||||
|     public override void ExportFromNative( | ||||
|         GeneratorStringBuilder builder, | ||||
|         UhtProperty property,  | ||||
|         string propertyName, | ||||
|         string assignmentOrReturn,  | ||||
|         string sourceBuffer,  | ||||
|         string offset,  | ||||
|         bool bCleanupSourceBuffer,  | ||||
|         bool reuseRefMarshallers) | ||||
|     { | ||||
|         if (property.IsBitfield) | ||||
|         { | ||||
|             builder.AppendLine($"{assignmentOrReturn} {GetMarshaller(property)}.FromNative(IntPtr.Add({sourceBuffer}, {offset}), {GetFieldMaskFieldName(propertyName)});"); | ||||
|             return; | ||||
|         } | ||||
|          | ||||
|         base.ExportFromNative(builder, property, propertyName, assignmentOrReturn, sourceBuffer, offset, bCleanupSourceBuffer, reuseRefMarshallers); | ||||
|     } | ||||
|      | ||||
|     private string GetOffsetFieldName(string nativePropertyName) | ||||
|     { | ||||
|         return $"{nativePropertyName}{OffSetPostfix}"; | ||||
|     } | ||||
|      | ||||
|     private string GetFieldMaskFieldName(string nativePropertyName) | ||||
|     { | ||||
|         return $"{nativePropertyName}{FieldMaskPostfix}"; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,43 @@ | ||||
| using System; | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class ClassPropertyTranslator : SimpleTypePropertyTranslator | ||||
| { | ||||
|     public ClassPropertyTranslator() : base(typeof(UhtClassProperty)) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         UhtClassProperty classProperty = (UhtClassProperty)property; | ||||
|         string fullName = property.IsGenericType() ? "DOT"  | ||||
|             : classProperty.MetaClass!.GetFullManagedName(); | ||||
|  | ||||
|         return $"TSubclassOf<{fullName}>"; | ||||
|     } | ||||
|  | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
|         UhtClassProperty classProperty = (UhtClassProperty)property; | ||||
|         string fullName = property.IsGenericType() ? "DOT" | ||||
|             : classProperty.MetaClass!.GetFullManagedName(); | ||||
|  | ||||
|         return $"SubclassOfMarshaller<{fullName}>"; | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|     public override void ExportToNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName, string destinationBuffer, string offset, string source) | ||||
|     { | ||||
|         if (property.IsGenericType()) | ||||
|         { | ||||
|             builder.AppendLine($"{GetMarshaller(property)}.ToNative(IntPtr.Add({destinationBuffer}, {offset}), 0, typeof(DOT));"); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             base.ExportToNative(builder, property, propertyName, destinationBuffer, offset, source); | ||||
|         } | ||||
|     }*/ | ||||
| } | ||||
| @ -0,0 +1,249 @@ | ||||
| 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); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,74 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Exporters; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class DelegateBasePropertyTranslator : PropertyTranslator | ||||
| { | ||||
|     public DelegateBasePropertyTranslator(EPropertyUsageFlags supportedPropertyUsage) : base(supportedPropertyUsage) | ||||
|     { | ||||
|     } | ||||
|      | ||||
|     public override bool CacheProperty => true; | ||||
|  | ||||
|     public static string GetDelegateName(UhtFunction function, bool wrapperName = false) | ||||
|     { | ||||
|         string delegateName = function.EngineName; | ||||
|         int delegateSignatureIndex = delegateName.IndexOf("__DelegateSignature", StringComparison.Ordinal); | ||||
|         string strippedDelegateName = delegateName.Substring(0, delegateSignatureIndex); | ||||
|          | ||||
|         return wrapperName ? "U" + strippedDelegateName : strippedDelegateName; | ||||
|     } | ||||
|      | ||||
|     public static string GetFullDelegateName(UhtFunction function, bool wrapperName = false) | ||||
|     { | ||||
|         return $"{function.GetNamespace()}.{GetDelegateName(function, wrapperName)}"; | ||||
|     } | ||||
|      | ||||
|     public override bool CanExport(UhtProperty property) | ||||
|     { | ||||
|         throw new System.NotImplementedException(); | ||||
|     } | ||||
|  | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         throw new System.NotImplementedException(); | ||||
|     } | ||||
|  | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
|         throw new System.NotImplementedException(); | ||||
|     } | ||||
|  | ||||
|     public override string ExportMarshallerDelegates(UhtProperty property) | ||||
|     { | ||||
|         throw new System.NotImplementedException(); | ||||
|     } | ||||
|  | ||||
|     public override string GetNullValue(UhtProperty property) | ||||
|     { | ||||
|         throw new System.NotImplementedException(); | ||||
|     } | ||||
|  | ||||
|     public override void ExportFromNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName, | ||||
|         string assignmentOrReturn, string sourceBuffer, string offset, bool bCleanupSourceBuffer, bool reuseRefMarshallers) | ||||
|     { | ||||
|         throw new System.NotImplementedException(); | ||||
|     } | ||||
|  | ||||
|     public override void ExportToNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName, string destinationBuffer, | ||||
|         string offset, string source) | ||||
|     { | ||||
|         throw new System.NotImplementedException(); | ||||
|     } | ||||
|  | ||||
|     public override string ConvertCPPDefaultValue(string defaultValue, UhtFunction function, UhtProperty parameter) | ||||
|     { | ||||
|         throw new System.NotImplementedException(); | ||||
|     } | ||||
|  | ||||
|     public override bool CanSupportGenericType(UhtProperty property) => false; | ||||
| } | ||||
| @ -0,0 +1,58 @@ | ||||
| using System; | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class EnumPropertyTranslator : BlittableTypePropertyTranslator | ||||
| { | ||||
|     public EnumPropertyTranslator() : base(typeof(UhtByteProperty), "", PropertyKind.Enum) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     public override bool CanExport(UhtProperty property) | ||||
|     { | ||||
|         return property is UhtEnumProperty or UhtByteProperty && GetEnum(property) != null; | ||||
|     } | ||||
|  | ||||
|     public override string ConvertCPPDefaultValue(string defaultValue, UhtFunction function, UhtProperty parameter) | ||||
|     { | ||||
|         UhtEnum enumObj = GetEnum(parameter)!; | ||||
|         int index = enumObj.GetIndexByName(defaultValue); | ||||
|         string valueName = ScriptGeneratorUtilities.GetCleanEnumValueName(enumObj, enumObj.EnumValues[index]); | ||||
|         return $"{GetManagedType(parameter)}.{valueName}"; | ||||
|     } | ||||
|      | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         UhtEnum enumObj = GetEnum(property)!; | ||||
|         return enumObj.GetFullManagedName(); | ||||
|     } | ||||
|  | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
|         return $"EnumMarshaller<{GetManagedType(property)}>"; | ||||
|     } | ||||
|  | ||||
|     public override void ExportCppDefaultParameterAsLocalVariable(GeneratorStringBuilder builder, string variableName, string defaultValue, | ||||
|         UhtFunction function, UhtProperty paramProperty) | ||||
|     { | ||||
|         if (defaultValue.Contains("::")) | ||||
|         { | ||||
|             defaultValue = defaultValue.Substring(defaultValue.LastIndexOf("::") + 2); | ||||
|         } | ||||
|          | ||||
|         string fullEnumName = GetManagedType(paramProperty); | ||||
|         builder.AppendLine($"{fullEnumName} {variableName} = {fullEnumName}.{defaultValue};"); | ||||
|     } | ||||
|  | ||||
|     private static UhtEnum? GetEnum(UhtProperty property) | ||||
|     { | ||||
|         return property switch | ||||
|         { | ||||
|             UhtEnumProperty enumProperty => enumProperty.Enum, | ||||
|             UhtByteProperty byteProperty => byteProperty.Enum, | ||||
|             _ => throw new InvalidOperationException("Property is not an enum or byte property") | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,30 @@ | ||||
| using EpicGames.UHT.Types; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class FieldPathPropertyTranslator : SimpleTypePropertyTranslator | ||||
| { | ||||
|     public FieldPathPropertyTranslator() : base(typeof(UhtFieldPathProperty)) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     public override bool CanExport(UhtProperty property) | ||||
|     { | ||||
|         return property is UhtFieldPathProperty; | ||||
|     } | ||||
|  | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         return "FFieldPath"; | ||||
|     } | ||||
|  | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
|         return "FieldPathMarshaller"; | ||||
|     } | ||||
|  | ||||
|     public override bool CanSupportGenericType(UhtProperty property) | ||||
|     { | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,15 @@ | ||||
| using EpicGames.UHT.Types; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class FloatPropertyTranslator : BlittableTypePropertyTranslator | ||||
| { | ||||
|     public FloatPropertyTranslator() : base(typeof(UhtFloatProperty), "float", PropertyKind.Float) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     public override string ConvertCPPDefaultValue(string defaultValue, UhtFunction function, UhtProperty parameter) | ||||
|     { | ||||
|         return base.ConvertCPPDefaultValue(defaultValue, function, parameter) + "f"; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,34 @@ | ||||
| using System.Linq; | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class IntPropertyTranslator : BlittableTypePropertyTranslator | ||||
| { | ||||
|     public IntPropertyTranslator() : base(typeof(UhtIntProperty), "int", PropertyKind.Int) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         if (property.Outer is UhtFunction function && property.IsCustomStructureType()) | ||||
|         { | ||||
|             if (function.GetCustomStructParamCount() == 1) return "CSP"; | ||||
|             return $"CSP{property.GetPrecedingCustomStructParams()}"; | ||||
|         } | ||||
|          | ||||
|         return base.GetManagedType(property); | ||||
|     } | ||||
|  | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
|         if (property.Outer is UhtFunction && property.IsCustomStructureType()) | ||||
|         { | ||||
|             return $"StructMarshaller<{GetManagedType(property)}>"; | ||||
|         } | ||||
|         return base.GetMarshaller(property); | ||||
|     } | ||||
|  | ||||
|     public override bool CanSupportCustomStruct(UhtProperty property) => true; | ||||
| } | ||||
| @ -0,0 +1,24 @@ | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class InterfacePropertyTranslator : SimpleTypePropertyTranslator | ||||
| { | ||||
|     public InterfacePropertyTranslator() : base(typeof(UhtInterfaceProperty)) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         UhtInterfaceProperty interfaceProperty = (UhtInterfaceProperty)property; | ||||
|         return interfaceProperty.InterfaceClass.GetFullManagedName(); | ||||
|     } | ||||
|  | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
|         return $"{GetManagedType(property)}Marshaller"; | ||||
|     } | ||||
|  | ||||
|     public override bool CanSupportGenericType(UhtProperty property) => true; | ||||
| } | ||||
| @ -0,0 +1,238 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using EpicGames.Core; | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class MapPropertyTranslator : PropertyTranslator | ||||
| { | ||||
|     public MapPropertyTranslator() : base(ContainerSupportedUsages) | ||||
|     { | ||||
|          | ||||
|     } | ||||
|      | ||||
|     public override bool IsBlittable => false; | ||||
|     public override bool SupportsSetter => true; | ||||
|     public override bool CacheProperty => true; | ||||
|  | ||||
|     public override bool CanExport(UhtProperty property) | ||||
|     { | ||||
|         if (property is not UhtMapProperty mapProperty) | ||||
|         { | ||||
|             return false; | ||||
|         } | ||||
|          | ||||
|         PropertyTranslator? keyTranslator = PropertyTranslatorManager.GetTranslator(mapProperty.KeyProperty); | ||||
|         PropertyTranslator? valueTranslator = PropertyTranslatorManager.GetTranslator(mapProperty.ValueProperty); | ||||
|          | ||||
|         // These can be null apparently | ||||
|         if (keyTranslator == null || valueTranslator == null) | ||||
|         { | ||||
|             return false; | ||||
|         } | ||||
|          | ||||
|         return keyTranslator.IsSupportedAsInner() && valueTranslator.IsSupportedAsInner(); | ||||
|     } | ||||
|  | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         UhtMapProperty mapProperty = (UhtMapProperty) property; | ||||
|         PropertyTranslator keyTranslator = PropertyTranslatorManager.GetTranslator(mapProperty.KeyProperty)!; | ||||
|         PropertyTranslator valueTranslator = PropertyTranslatorManager.GetTranslator(mapProperty.ValueProperty)!; | ||||
|          | ||||
|         string keyManagedType = keyTranslator.GetManagedType(mapProperty.KeyProperty); | ||||
|         string valueManagedType = valueTranslator.GetManagedType(mapProperty.ValueProperty); | ||||
|          | ||||
|         string interfaceType = property.HasAnyFlags(EPropertyFlags.BlueprintReadOnly) ? "IReadOnlyDictionary" : "IDictionary"; | ||||
|         return $"System.Collections.Generic.{interfaceType}<{keyManagedType}, {valueManagedType}>"; | ||||
|     } | ||||
|  | ||||
|     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, \"{property.EngineName}\");"); | ||||
|     } | ||||
|  | ||||
|     public override void ExportParameterVariables(GeneratorStringBuilder builder, UhtFunction function, | ||||
|         string nativeMethodName, | ||||
|         UhtProperty property, string propertyEngineName) | ||||
|     { | ||||
|         base.ExportParameterVariables(builder, function, nativeMethodName, property, propertyEngineName); | ||||
|  | ||||
|         string marshaller = GetMarshaller((UhtMapProperty) property); | ||||
|          | ||||
|         builder.AppendLine($"static IntPtr {nativeMethodName}_{propertyEngineName}_NativeProperty;"); | ||||
|         if (function.FunctionFlags.HasAnyFlags(EFunctionFlags.Static)) | ||||
|         { | ||||
|             builder.AppendLine($"static {marshaller} {nativeMethodName}_{propertyEngineName}_Marshaller = null;"); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             builder.AppendLine($"{marshaller} {nativeMethodName}_{propertyEngineName}_Marshaller = null;"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public override void ExportPropertyVariables(GeneratorStringBuilder builder, UhtProperty property, string propertyEngineName) | ||||
|     { | ||||
|         base.ExportPropertyVariables(builder, property, propertyEngineName); | ||||
|          | ||||
|         string marshaller = GetMarshaller((UhtMapProperty) property); | ||||
|          | ||||
|         if (property.IsOuter<UhtScriptStruct>()) | ||||
|         { | ||||
|             builder.AppendLine($"static {marshaller} {propertyEngineName}_Marshaller = null;"); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             builder.AppendLine($"{marshaller} {propertyEngineName}_Marshaller = null;"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public override void ExportPropertyGetter(GeneratorStringBuilder builder, UhtProperty property, | ||||
|         string propertyManagedName) | ||||
|     { | ||||
|         UhtMapProperty mapProperty = (UhtMapProperty) property; | ||||
|         PropertyTranslator keyTranslator = PropertyTranslatorManager.GetTranslator(mapProperty.KeyProperty)!; | ||||
|         PropertyTranslator valueTranslator = PropertyTranslatorManager.GetTranslator(mapProperty.ValueProperty)!; | ||||
|          | ||||
|         string keyMarshallingDelegates = keyTranslator.ExportMarshallerDelegates(mapProperty.KeyProperty); | ||||
|         string valueMarshallingDelegates = valueTranslator.ExportMarshallerDelegates(mapProperty.ValueProperty); | ||||
|  | ||||
|         string marshaller = GetMarshaller(mapProperty); | ||||
|  | ||||
|         builder.AppendLine($"{property.SourceName}_Marshaller ??= new {marshaller}({property.SourceName}_NativeProperty, {keyMarshallingDelegates}, {valueMarshallingDelegates});"); | ||||
|         builder.AppendLine($"return {property.SourceName}_Marshaller.FromNative(IntPtr.Add(NativeObject, {property.SourceName}_Offset), 0);"); | ||||
|     } | ||||
|  | ||||
|     public override void ExportPropertySetter(GeneratorStringBuilder builder, UhtProperty property, string propertyManagedName) | ||||
|     { | ||||
|         UhtMapProperty mapProperty = (UhtMapProperty)property; | ||||
|         PropertyTranslator keyTranslator = PropertyTranslatorManager.GetTranslator(mapProperty.KeyProperty)!; | ||||
|         PropertyTranslator valueTranslator = PropertyTranslatorManager.GetTranslator(mapProperty.ValueProperty)!; | ||||
|  | ||||
|         string keyMarshallingDelegates = keyTranslator.ExportMarshallerDelegates(mapProperty.KeyProperty); | ||||
|         string valueMarshallingDelegates = valueTranslator.ExportMarshallerDelegates(mapProperty.ValueProperty); | ||||
|  | ||||
|         string marshaller = GetMarshaller(mapProperty); | ||||
|  | ||||
|         builder.AppendLine($"{property.SourceName}_Marshaller ??= new {marshaller}({property.SourceName}_NativeProperty, {keyMarshallingDelegates}, {valueMarshallingDelegates});"); | ||||
|         builder.AppendLine($"{property.SourceName}_Marshaller.ToNative(IntPtr.Add(NativeObject, {property.SourceName}_Offset), 0, value);"); | ||||
|     } | ||||
|  | ||||
|     public override void ExportFromNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName, string assignmentOrReturn, | ||||
|         string sourceBuffer, string offset, bool bCleanupSourceBuffer, bool reuseRefMarshallers) | ||||
|     { | ||||
|         UhtMapProperty mapProperty = (UhtMapProperty) property; | ||||
|         PropertyTranslator keyTranslator = PropertyTranslatorManager.GetTranslator(mapProperty.KeyProperty)!; | ||||
|         PropertyTranslator valueTranslator = PropertyTranslatorManager.GetTranslator(mapProperty.ValueProperty)!; | ||||
|         | ||||
|         string nativePropertyName = $"{propertyName}_NativeProperty"; | ||||
|         string marshaller = $"{propertyName}_Marshaller"; | ||||
|  | ||||
|         if (property.Outer is UhtFunction function) | ||||
|         { | ||||
|             string nativeMethodName = function.SourceName; | ||||
|             nativePropertyName = $"{nativeMethodName}_{nativePropertyName}"; | ||||
|             marshaller = $"{nativeMethodName}_{marshaller}"; | ||||
|         } | ||||
|         | ||||
|         string keyType = keyTranslator.GetManagedType(mapProperty.KeyProperty); | ||||
|         string valueType = valueTranslator.GetManagedType(mapProperty.ValueProperty); | ||||
|         string marshallerType = $"MapCopyMarshaller<{keyType}, {valueType}>"; | ||||
|  | ||||
|         if (!reuseRefMarshallers) | ||||
|         { | ||||
|             string keyMarshallingDelegates = keyTranslator.ExportMarshallerDelegates(mapProperty.KeyProperty); | ||||
|             string valueMarshallingDelegates = valueTranslator.ExportMarshallerDelegates(mapProperty.ValueProperty); | ||||
|         | ||||
|             builder.AppendLine($"{marshaller} ??= new {marshallerType}({nativePropertyName}, {keyMarshallingDelegates}, {valueMarshallingDelegates});"); | ||||
|             builder.AppendLine($"IntPtr {nativePropertyName}_ParamsBuffer = IntPtr.Add({sourceBuffer}, {offset});"); | ||||
|         } | ||||
|  | ||||
|         builder.AppendLine($"{assignmentOrReturn} {marshaller}.FromNative({sourceBuffer}, 0);"); | ||||
|  | ||||
|         if (bCleanupSourceBuffer) | ||||
|         { | ||||
|             ExportCleanupMarshallingBuffer(builder, property, propertyName); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public override void ExportToNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName, string destinationBuffer, | ||||
|         string offset, string source) | ||||
|     { | ||||
|        UhtMapProperty mapProperty = (UhtMapProperty) property; | ||||
|        PropertyTranslator keyTranslator = PropertyTranslatorManager.GetTranslator(mapProperty.KeyProperty)!; | ||||
|        PropertyTranslator valueTranslator = PropertyTranslatorManager.GetTranslator(mapProperty.ValueProperty)!; | ||||
|         | ||||
|        string nativePropertyName = $"{propertyName}_NativeProperty"; | ||||
|        string marshaller = $"{propertyName}_Marshaller"; | ||||
|  | ||||
|        if (property.Outer is UhtFunction function) | ||||
|        { | ||||
|            string nativeMethodName = function.SourceName; | ||||
|            nativePropertyName = $"{nativeMethodName}_{nativePropertyName}"; | ||||
|            marshaller = $"{nativeMethodName}_{marshaller}"; | ||||
|        } | ||||
|         | ||||
|        string keyType = keyTranslator.GetManagedType(mapProperty.KeyProperty); | ||||
|        string valueType = valueTranslator.GetManagedType(mapProperty.ValueProperty); | ||||
|         | ||||
|        string marshallerType = GetWrapperType(property, keyType, valueType); | ||||
|        string keyMarshallingDelegates = keyTranslator.ExportMarshallerDelegates(mapProperty.KeyProperty); | ||||
|        string valueMarshallingDelegates = valueTranslator.ExportMarshallerDelegates(mapProperty.ValueProperty); | ||||
|         | ||||
|        builder.AppendLine($"{marshaller} ??= new {marshallerType}({nativePropertyName}, {keyMarshallingDelegates}, {valueMarshallingDelegates});"); | ||||
|        builder.AppendLine($"IntPtr {nativePropertyName}_NativeBuffer = IntPtr.Add({destinationBuffer}, {offset});"); | ||||
|        builder.AppendLine($"{marshaller}.ToNative({nativePropertyName}_NativeBuffer, 0, {source});"); | ||||
|     } | ||||
|  | ||||
|     private string GetWrapperType(UhtProperty property, string keyType, string valueType) | ||||
|     { | ||||
|         bool isStructProperty = property.IsOuter<UhtScriptStruct>(); | ||||
|         bool isParameter = property.IsOuter<UhtFunction>() || (property.Getter is not null && property.Setter is not null); | ||||
|         string containerType = isStructProperty || isParameter ? "MapCopyMarshaller" : property.PropertyFlags.HasAnyFlags(EPropertyFlags.BlueprintReadOnly) ? "MapReadOnlyMarshaller" : "MapMarshaller"; | ||||
|         return $"{containerType}<{keyType}, {valueType}>"; | ||||
|     } | ||||
|      | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
|         throw new System.NotImplementedException(); | ||||
|     } | ||||
|  | ||||
|     public override string ExportMarshallerDelegates(UhtProperty property) | ||||
|     { | ||||
|         throw new System.NotImplementedException(); | ||||
|     } | ||||
|  | ||||
|     public override string GetNullValue(UhtProperty property) | ||||
|     { | ||||
|         return "null"; | ||||
|     } | ||||
|  | ||||
|     public override string ConvertCPPDefaultValue(string defaultValue, UhtFunction function, UhtProperty parameter) | ||||
|     { | ||||
|         throw new System.NotImplementedException(); | ||||
|     } | ||||
|  | ||||
|     private string GetMarshaller(UhtMapProperty property) | ||||
|     { | ||||
|         bool isStructProperty = property.IsOuter<UhtScriptStruct>(); | ||||
|         bool isParameter = property.IsOuter<UhtFunction>() || property.HasAnyGetter(); | ||||
|          | ||||
|         PropertyTranslator keyTranslator = PropertyTranslatorManager.GetTranslator(property.KeyProperty)!; | ||||
|         PropertyTranslator valueTranslator = PropertyTranslatorManager.GetTranslator(property.ValueProperty)!; | ||||
|          | ||||
|         string marshallerType = isStructProperty || isParameter ? "MapCopyMarshaller"  | ||||
|             : property.PropertyFlags.HasAnyFlags(EPropertyFlags.BlueprintReadOnly) ? "MapReadOnlyMarshaller" : "MapMarshaller"; | ||||
|  | ||||
|         string keyType = keyTranslator.GetManagedType(property.KeyProperty); | ||||
|         string valueType = valueTranslator.GetManagedType(property.ValueProperty); | ||||
|          | ||||
|         return $"{marshallerType}<{keyType}, {valueType}>"; | ||||
|     } | ||||
|  | ||||
|     public override bool CanSupportGenericType(UhtProperty property) => false; | ||||
| } | ||||
| @ -0,0 +1,87 @@ | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class MulticastDelegatePropertyTranslator : DelegateBasePropertyTranslator | ||||
| { | ||||
|     public MulticastDelegatePropertyTranslator() : base(EPropertyUsageFlags.Property) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     private string GetBackingField(UhtProperty property) | ||||
|     { | ||||
|         return $"{property.SourceName}_BackingField"; | ||||
|     } | ||||
|  | ||||
|     public override bool CanExport(UhtProperty property) | ||||
|     { | ||||
|         UhtMulticastDelegateProperty multicastDelegateProperty = (UhtMulticastDelegateProperty) property; | ||||
|         return ScriptGeneratorUtilities.CanExportParameters(multicastDelegateProperty.Function); | ||||
|     } | ||||
|  | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         UhtMulticastDelegateProperty multicastDelegateProperty = (UhtMulticastDelegateProperty) property; | ||||
|         return $"TMulticastDelegate<{GetFullDelegateName(multicastDelegateProperty.Function)}>"; | ||||
|     } | ||||
|  | ||||
|     public override void ExportPropertyStaticConstructor(GeneratorStringBuilder builder, UhtProperty property, string nativePropertyName) | ||||
|     { | ||||
|         base.ExportPropertyStaticConstructor(builder, property, nativePropertyName); | ||||
|          | ||||
|         UhtMulticastDelegateProperty multicastDelegateProperty = (UhtMulticastDelegateProperty) property; | ||||
|         if (multicastDelegateProperty.Function.HasParameters) | ||||
|         { | ||||
|             string fullDelegateName = GetFullDelegateName(((UhtMulticastDelegateProperty) property).Function, true); | ||||
|             builder.AppendLine($"{fullDelegateName}.InitializeUnrealDelegate({nativePropertyName}_NativeProperty);"); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     public override void ExportPropertyVariables(GeneratorStringBuilder builder, UhtProperty property, string propertyEngineName) | ||||
|     { | ||||
|         base.ExportPropertyVariables(builder, property, propertyEngineName); | ||||
|         string backingField = GetBackingField(property); | ||||
|          | ||||
|         UhtMulticastDelegateProperty multicastDelegateProperty = (UhtMulticastDelegateProperty) property; | ||||
|         string fullDelegateName = GetFullDelegateName(multicastDelegateProperty.Function); | ||||
|          | ||||
|         builder.AppendLine($"private TMulticastDelegate<{fullDelegateName}> {backingField};"); | ||||
|     } | ||||
|  | ||||
|     public override void ExportPropertySetter(GeneratorStringBuilder builder, UhtProperty property, | ||||
|         string propertyManagedName) | ||||
|     { | ||||
|         string backingField = GetBackingField(property); | ||||
|          | ||||
|         UhtMulticastDelegateProperty multicastDelegateProperty = (UhtMulticastDelegateProperty) property; | ||||
|         string fullDelegateName = GetFullDelegateName(multicastDelegateProperty.Function); | ||||
|          | ||||
|         builder.AppendLine($"if (value == {backingField})"); | ||||
|         builder.OpenBrace(); | ||||
|         builder.AppendLine("return;"); | ||||
|         builder.CloseBrace(); | ||||
|         builder.AppendLine($"{backingField} = value;"); | ||||
|         builder.AppendLine($"MulticastDelegateMarshaller<{fullDelegateName}>.ToNative(IntPtr.Add(NativeObject, {propertyManagedName}_Offset), 0, value);"); | ||||
|     } | ||||
|  | ||||
|     public override void ExportPropertyGetter(GeneratorStringBuilder builder, UhtProperty property, string propertyManagedName) | ||||
|     { | ||||
|         string backingField = GetBackingField(property); | ||||
|         string propertyFieldName = GetNativePropertyField(propertyManagedName); | ||||
|          | ||||
|         UhtMulticastDelegateProperty multicastDelegateProperty = (UhtMulticastDelegateProperty) property; | ||||
|         string fullDelegateName = GetFullDelegateName(multicastDelegateProperty.Function); | ||||
|          | ||||
|         builder.AppendLine($"if ({backingField} == null)"); | ||||
|         builder.OpenBrace(); | ||||
|         builder.AppendLine($"{backingField} = MulticastDelegateMarshaller<{fullDelegateName}>.FromNative(IntPtr.Add(NativeObject, {propertyManagedName}_Offset), {propertyFieldName}, 0);"); | ||||
|         builder.CloseBrace(); | ||||
|         builder.AppendLine($"return {backingField};"); | ||||
|     } | ||||
|  | ||||
|     public override string GetNullValue(UhtProperty property) | ||||
|     { | ||||
|         return "null"; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,31 @@ | ||||
| using System; | ||||
| using EpicGames.UHT.Types; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class NamePropertyTranslator : BlittableTypePropertyTranslator | ||||
| { | ||||
|     public NamePropertyTranslator() : base(typeof(UhtNameProperty), "FName", PropertyKind.Unknown) | ||||
|     { | ||||
|     } | ||||
|      | ||||
|     public override bool ExportDefaultParameter => false; | ||||
|  | ||||
|     public override string GetNullValue(UhtProperty property) | ||||
|     { | ||||
|         return "default(FName)"; | ||||
|     } | ||||
|  | ||||
|     public override void ExportCppDefaultParameterAsLocalVariable(GeneratorStringBuilder builder, string variableName, string defaultValue, | ||||
|         UhtFunction function, UhtProperty paramProperty) | ||||
|     { | ||||
|         if (defaultValue == "None") | ||||
|         { | ||||
|             builder.AppendLine($"FName {variableName} = FName.None;"); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             builder.AppendLine($"FName {variableName} = new FName(\"{defaultValue}\");"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,59 @@ | ||||
| using EpicGames.Core; | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class ObjectPropertyTranslator : SimpleTypePropertyTranslator | ||||
| { | ||||
|     public ObjectPropertyTranslator() : base(typeof(UhtObjectProperty)) | ||||
|     { | ||||
|          | ||||
|     } | ||||
|  | ||||
|     public override bool CanExport(UhtProperty property) | ||||
|     { | ||||
|         UhtObjectPropertyBase objectProperty = (UhtObjectPropertyBase) property; | ||||
|         UhtClass? metaClass = objectProperty.Class; | ||||
|          | ||||
|         if (metaClass.HasAnyFlags(EClassFlags.Interface) || | ||||
|             metaClass.EngineType == UhtEngineType.Interface ||  | ||||
|             metaClass.EngineType == UhtEngineType.NativeInterface) | ||||
|         { | ||||
|             return false; | ||||
|         } | ||||
|          | ||||
|         return base.CanExport(property); | ||||
|     } | ||||
|  | ||||
|     public override string GetNullValue(UhtProperty property) | ||||
|     { | ||||
|         return "null"; | ||||
|     } | ||||
|  | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         return GetManagedType(property, property.HasMetadata("Nullable"));    | ||||
|     } | ||||
|  | ||||
|     private static string GetManagedType(UhtProperty property, bool isNullable) | ||||
|     { | ||||
|         string nullableAnnotation = isNullable ? "?" : ""; | ||||
|         if (property.IsGenericType()) return $"DOT{nullableAnnotation}"; | ||||
|  | ||||
|         UhtObjectProperty objectProperty = (UhtObjectProperty)property; | ||||
|         return $"{objectProperty.Class.GetFullManagedName()}{nullableAnnotation}"; | ||||
|     } | ||||
|  | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
|         if (property.Outer is UhtProperty outerProperty && outerProperty.IsGenericType()) | ||||
|         { | ||||
|             return "ObjectMarshaller<DOT>"; | ||||
|         } | ||||
|  | ||||
|         return $"ObjectMarshaller<{GetManagedType(property, false)}>"; | ||||
|     } | ||||
|  | ||||
|     public override bool CanSupportGenericType(UhtProperty property) => true; | ||||
| } | ||||
| @ -0,0 +1,206 @@ | ||||
| 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; | ||||
| } | ||||
| @ -0,0 +1,593 @@ | ||||
| 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})"); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,242 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Model; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public static class PropertyTranslatorManager | ||||
| { | ||||
|     private static readonly Dictionary<Type, List<PropertyTranslator>?> RegisteredTranslators = new(); | ||||
|     private static readonly HashSet<Type> RegisteredPrimitives = new(); | ||||
|     private static readonly HashSet<Type> RegisteredNumerics = new(); | ||||
|  | ||||
|     public static SpecialTypeInfo SpecialTypeInfo { get; } = new(); | ||||
|      | ||||
|     static PropertyTranslatorManager() | ||||
|     { | ||||
|         var projectDirectory = Program.Factory.Session.ProjectDirectory; | ||||
|         var configDirectory = Path.Combine(projectDirectory!, "Config"); | ||||
|          | ||||
|         var pluginDirectory = Path.Combine(projectDirectory!, "Plugins"); | ||||
|         var pluginDirInfo = new DirectoryInfo(pluginDirectory); | ||||
|  | ||||
|         var files = pluginDirInfo.GetFiles("*.uplugin", SearchOption.AllDirectories) | ||||
|             .Select(x => x.DirectoryName!) | ||||
|             .Select(x => Path.Combine(x, "Config")) | ||||
|             .Concat(new List<string> { configDirectory }) | ||||
|             .Select(x => new DirectoryInfo(x)) | ||||
|             .Where(x => x.Exists) | ||||
|             .SelectMany(x => x.GetFiles("*.UnrealSharpTypes.json", SearchOption.AllDirectories)) | ||||
|             .Select(x => x.FullName); | ||||
|         foreach (var pluginFile in files) | ||||
|         { | ||||
|             using var fileStream = File.OpenRead(pluginFile); | ||||
|             try | ||||
|             { | ||||
|                 var manifest = JsonSerializer.Deserialize<TypeTranslationManifest>(fileStream); | ||||
|                 AddTranslationManifest(manifest!); | ||||
|             } | ||||
|             catch (JsonException e) | ||||
|             { | ||||
|                 Console.WriteLine($"Error reading {pluginFile}: {e.Message}"); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         EnumPropertyTranslator enumPropertyTranslator = new(); | ||||
|         AddPropertyTranslator(typeof(UhtEnumProperty), enumPropertyTranslator); | ||||
|         AddPropertyTranslator(typeof(UhtByteProperty), enumPropertyTranslator); | ||||
|          | ||||
|         AddBlittablePropertyTranslator(typeof(UhtInt8Property), "sbyte", PropertyKind.SByte); | ||||
|         AddBlittablePropertyTranslator(typeof(UhtInt16Property), "short", PropertyKind.Short); | ||||
|         AddBlittablePropertyTranslator(typeof(UhtInt64Property), "long", PropertyKind.Long); | ||||
|         AddBlittablePropertyTranslator(typeof(UhtUInt16Property), "ushort", PropertyKind.UShort); | ||||
|         AddBlittablePropertyTranslator(typeof(UhtUInt32Property), "uint", PropertyKind.UInt); | ||||
|         AddBlittablePropertyTranslator(typeof(UhtUInt64Property), "ulong", PropertyKind.ULong); | ||||
|         AddBlittablePropertyTranslator(typeof(UhtDoubleProperty), "double", PropertyKind.Double); | ||||
|         AddBlittablePropertyTranslator(typeof(UhtByteProperty), "byte", PropertyKind.Byte); | ||||
|         AddBlittablePropertyTranslator(typeof(UhtLargeWorldCoordinatesRealProperty), "double", PropertyKind.Double); | ||||
|         AddPropertyTranslator(typeof(UhtFloatProperty), new FloatPropertyTranslator()); | ||||
|         AddPropertyTranslator(typeof(UhtIntProperty), new IntPropertyTranslator()); | ||||
|  | ||||
|         MulticastDelegatePropertyTranslator multicastDelegatePropertyTranslator = new(); | ||||
|         AddPropertyTranslator(typeof(UhtMulticastSparseDelegateProperty), multicastDelegatePropertyTranslator); | ||||
|         AddPropertyTranslator(typeof(UhtMulticastDelegateProperty), multicastDelegatePropertyTranslator); | ||||
|         AddPropertyTranslator(typeof(UhtMulticastInlineDelegateProperty), multicastDelegatePropertyTranslator); | ||||
|         AddPropertyTranslator(typeof(UhtDelegateProperty), new SinglecastDelegatePropertyTranslator()); | ||||
|          | ||||
|         AddBlittablePropertyTranslator(typeof(UhtByteProperty), "byte", PropertyKind.Byte); | ||||
|          | ||||
|         AddPropertyTranslator(typeof(UhtBoolProperty), new BoolPropertyTranslator()); | ||||
|         AddPropertyTranslator(typeof(UhtStrProperty), new StringPropertyTranslator()); | ||||
|         AddPropertyTranslator(typeof(UhtNameProperty), new NamePropertyTranslator()); | ||||
|         AddPropertyTranslator(typeof(UhtTextProperty), new TextPropertyTranslator()); | ||||
|          | ||||
|         AddPropertyTranslator(typeof(UhtWeakObjectPtrProperty), new WeakObjectPropertyTranslator()); | ||||
|          | ||||
|         WorldContextObjectPropertyTranslator worldContextObjectPropertyTranslator = new(); | ||||
|         AddPropertyTranslator(typeof(UhtObjectPropertyBase), worldContextObjectPropertyTranslator); | ||||
| #if !UE_5_6_OR_LATER | ||||
|         AddPropertyTranslator(typeof(UhtObjectPtrProperty), worldContextObjectPropertyTranslator); | ||||
| #endif | ||||
|         AddPropertyTranslator(typeof(UhtObjectProperty), worldContextObjectPropertyTranslator); | ||||
|         AddPropertyTranslator(typeof(UhtLazyObjectPtrProperty), worldContextObjectPropertyTranslator); | ||||
|          | ||||
|         ObjectPropertyTranslator objectPropertyTranslator = new(); | ||||
|         AddPropertyTranslator(typeof(UhtObjectPropertyBase), objectPropertyTranslator); | ||||
| #if !UE_5_6_OR_LATER | ||||
|         AddPropertyTranslator(typeof(UhtObjectPtrProperty), objectPropertyTranslator); | ||||
| #endif | ||||
|         AddPropertyTranslator(typeof(UhtObjectProperty), objectPropertyTranslator); | ||||
|         AddPropertyTranslator(typeof(UhtLazyObjectPtrProperty), objectPropertyTranslator); | ||||
|          | ||||
|         AddPropertyTranslator(typeof(UhtInterfaceProperty), new InterfacePropertyTranslator()); | ||||
|          | ||||
|         AddPropertyTranslator(typeof(UhtClassProperty), new ClassPropertyTranslator()); | ||||
| #if !UE_5_6_OR_LATER | ||||
|         AddPropertyTranslator(typeof(UhtClassPtrProperty), new ClassPropertyTranslator()); | ||||
| #endif | ||||
|         AddPropertyTranslator(typeof(UhtSoftClassProperty), new SoftClassPropertyTranslator()); | ||||
|         AddPropertyTranslator(typeof(UhtSoftObjectProperty), new SoftObjectPropertyTranslator()); | ||||
|         AddPropertyTranslator(typeof(UhtFieldPathProperty), new FieldPathPropertyTranslator()); | ||||
|  | ||||
|         foreach (var (nativeName, managedType) in SpecialTypeInfo.Structs.BlittableTypes.Values) | ||||
|         { | ||||
|             if (managedType is null) | ||||
|             { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             AddBlittableCustomStructPropertyTranslator(nativeName, managedType); | ||||
|         } | ||||
|  | ||||
|         AddPropertyTranslator(typeof(UhtArrayProperty), new ArrayPropertyTranslator()); | ||||
|         AddPropertyTranslator(typeof(UhtMapProperty), new MapPropertyTranslator()); | ||||
|         AddPropertyTranslator(typeof(UhtSetProperty), new SetPropertyTranslator()); | ||||
|          | ||||
|         AddPropertyTranslator(typeof(UhtStructProperty), new BlittableStructPropertyTranslator()); | ||||
|         AddPropertyTranslator(typeof(UhtStructProperty), new StructPropertyTranslator()); | ||||
|          | ||||
|         AddPropertyTranslator(typeof(UhtOptionalProperty), new OptionalPropertyTranslator()); | ||||
|          | ||||
|         // Manually exported properties | ||||
|         InclusionLists.BanProperty("UWorld", "GameState"); | ||||
|         InclusionLists.BanProperty("UWorld", "AuthorityGameMode"); | ||||
|  | ||||
|         // Some reason == equality differs from .Equals | ||||
|         InclusionLists.BanEquality("FRandomStream"); | ||||
|  | ||||
|         // Renamed variables X/Y/Z to Pitch/Yaw/Roll | ||||
|         InclusionLists.BanEquality("FRotator"); | ||||
|  | ||||
|         // Fields not generating correctly | ||||
|         InclusionLists.BanEquality("FVector3f"); | ||||
|         InclusionLists.BanEquality("FVector2f"); | ||||
|         InclusionLists.BanEquality("FVector4f"); | ||||
|         InclusionLists.BanEquality("FVector_NetQuantize"); | ||||
|         InclusionLists.BanEquality("FVector_NetQuantize10"); | ||||
|         InclusionLists.BanEquality("FVector_NetQuantize100"); | ||||
|         InclusionLists.BanEquality("FVector_NetQuantizeNormal"); | ||||
|  | ||||
|         // Doesn't have any fields | ||||
|         InclusionLists.BanEquality("FSubsystemCollectionBaseRef"); | ||||
|  | ||||
|         // Custom arithmetic needed | ||||
|         InclusionLists.BanArithmetic("FQuat"); | ||||
|     } | ||||
|  | ||||
|     public static void AddTranslationManifest(TypeTranslationManifest manifest) | ||||
|     { | ||||
|         foreach (var skippedStruct in manifest.Structs.CustomTypes) | ||||
|         { | ||||
|             SpecialTypeInfo.Structs.SkippedTypes.Add(skippedStruct); | ||||
|         } | ||||
|          | ||||
|         foreach (var structInfo in manifest.Structs.BlittableTypes) | ||||
|         { | ||||
|             if (SpecialTypeInfo.Structs.NativelyCopyableTypes.ContainsKey(structInfo.Name)) | ||||
|             { | ||||
|                 throw new InvalidOperationException( | ||||
|                     $"A struct cannot be both blittable and natively copyable: {structInfo.Name}"); | ||||
|             } | ||||
|              | ||||
|             if (SpecialTypeInfo.Structs.BlittableTypes.TryGetValue(structInfo.Name, out var existing)) | ||||
|             { | ||||
|                 if (structInfo.ManagedType is not null && existing.ManagedType is not null && | ||||
|                     structInfo.ManagedType != existing.ManagedType) | ||||
|                 { | ||||
|                     throw new InvalidOperationException($"Duplicate struct name specified: {structInfo.Name}"); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 SpecialTypeInfo.Structs.BlittableTypes.Add(structInfo.Name, structInfo); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         foreach (var structInfo in manifest.Structs.NativelyTranslatableTypes) | ||||
|         { | ||||
|             if (SpecialTypeInfo.Structs.NativelyCopyableTypes.TryGetValue(structInfo.Name, out var existing)) | ||||
|             { | ||||
|                 SpecialTypeInfo.Structs.NativelyCopyableTypes[structInfo.Name] = existing with { HasDestructor = existing.HasDestructor || structInfo.HasDestructor }; | ||||
|                 continue; | ||||
|             } | ||||
|              | ||||
|             if (SpecialTypeInfo.Structs.BlittableTypes.ContainsKey(structInfo.Name)) | ||||
|             { | ||||
|                 throw new InvalidOperationException( | ||||
|                     $"A struct cannot be both blittable and natively copyable: {structInfo.Name}"); | ||||
|             } | ||||
|  | ||||
|             SpecialTypeInfo.Structs.NativelyCopyableTypes.Add(structInfo.Name, structInfo); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     public static PropertyTranslator? GetTranslator(UhtProperty property) | ||||
|     { | ||||
|         if (!RegisteredTranslators.TryGetValue(property.GetType(), out var translator)) | ||||
|         { | ||||
|             return null; | ||||
|         } | ||||
|          | ||||
|         foreach (PropertyTranslator propertyTranslator in translator!) | ||||
|         { | ||||
|             if (propertyTranslator.CanExport(property)) | ||||
|             { | ||||
|                 return propertyTranslator; | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         return null; | ||||
|     } | ||||
|      | ||||
|     public static void AddBlittablePropertyTranslator(Type propertyType, string managedType, PropertyKind propertyKind = PropertyKind.Unknown) | ||||
|     { | ||||
|         if (RegisteredTranslators.TryGetValue(propertyType, out var translators)) | ||||
|         { | ||||
|             translators!.Add(new BlittableTypePropertyTranslator(propertyType, managedType, propertyKind)); | ||||
|             return; | ||||
|         } | ||||
|          | ||||
|         RegisteredTranslators.Add(propertyType, new List<PropertyTranslator> {new BlittableTypePropertyTranslator(propertyType, managedType, propertyKind) }); | ||||
|     } | ||||
|  | ||||
|     private static void AddPropertyTranslator(Type propertyClass, PropertyTranslator translator) | ||||
|     { | ||||
|         if (RegisteredTranslators.TryGetValue(propertyClass, out var translators)) | ||||
|         { | ||||
|             translators!.Add(translator); | ||||
|             return; | ||||
|         } | ||||
|          | ||||
|         RegisteredTranslators.Add(propertyClass, new List<PropertyTranslator> {translator}); | ||||
|     } | ||||
|      | ||||
|     private static void AddBlittableCustomStructPropertyTranslator(string nativeName, string managedType) | ||||
|     { | ||||
|         AddPropertyTranslator(typeof(UhtStructProperty), new BlittableCustomStructTypePropertyTranslator(nativeName, managedType)); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,13 @@ | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class SetPropertyTranslator : ContainerPropertyTranslator | ||||
| { | ||||
|     public SetPropertyTranslator() | ||||
|         : base("SetCopyMarshaller",  | ||||
|             "SetReadOnlyMarshaller",  | ||||
|             "SetMarshaller",  | ||||
|             "IReadOnlySet",  | ||||
|             "ISet") | ||||
|     { | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,149 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class SimpleTypePropertyTranslator : PropertyTranslator | ||||
| { | ||||
|     public override bool IsBlittable => true; | ||||
|  | ||||
|     private readonly Type _propertyType; | ||||
|     protected readonly string ManagedType; | ||||
|  | ||||
|     protected SimpleTypePropertyTranslator(Type propertyType, string managedType = "", PropertyKind propertyKind = PropertyKind.Unknown)  | ||||
| 		: base(EPropertyUsageFlags.Any, propertyKind) | ||||
|     { | ||||
|         _propertyType = propertyType; | ||||
|         ManagedType = managedType; | ||||
|     } | ||||
|  | ||||
|     public override string ConvertCPPDefaultValue(string defaultValue, UhtFunction function, UhtProperty parameter) | ||||
|     { | ||||
|         if (defaultValue == "None") | ||||
|         { | ||||
|             return GetNullValue(parameter); | ||||
|         } | ||||
|          | ||||
|         return defaultValue; | ||||
|     } | ||||
|      | ||||
|     public override string GetNullValue(UhtProperty property) | ||||
|     { | ||||
|         string managedType = GetManagedType(property); | ||||
|         return $"default({managedType})"; | ||||
|     } | ||||
|  | ||||
|     public override void ExportFromNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName, | ||||
|         string assignmentOrReturn, string sourceBuffer, string offset, bool bCleanupSourceBuffer, | ||||
|         bool reuseRefMarshallers) | ||||
|     { | ||||
|         builder.AppendLine($"{assignmentOrReturn} {GetMarshaller(property)}.FromNative(IntPtr.Add({sourceBuffer}, {offset}), 0);"); | ||||
|     } | ||||
|  | ||||
|     public override void ExportToNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName, string destinationBuffer, | ||||
| 	    string offset, string source) | ||||
|     { | ||||
| 	    builder.AppendLine($"{GetMarshaller(property)}.ToNative(IntPtr.Add({destinationBuffer}, {offset}), 0, {source});"); | ||||
|     } | ||||
|  | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
| 	    throw new NotImplementedException(); | ||||
|     } | ||||
|      | ||||
|     public virtual string GetPropertyName(UhtProperty property) | ||||
| 	{ | ||||
| 		return property.GetParameterName(); | ||||
| 	} | ||||
|  | ||||
|     public override string ExportMarshallerDelegates(UhtProperty property) | ||||
|     { | ||||
|         string marshaller = GetMarshaller(property); | ||||
|         return $"{marshaller}.ToNative, {marshaller}.FromNative"; | ||||
|     } | ||||
|  | ||||
|     public override bool CanExport(UhtProperty property) | ||||
|     { | ||||
|         return property.GetType() == _propertyType || property.GetType().IsSubclassOf(_propertyType); | ||||
|     } | ||||
|  | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         return property.IsGenericType() ? "DOT" : ManagedType; | ||||
|     } | ||||
|  | ||||
|     protected void ExportDefaultStructParameter(GeneratorStringBuilder builder, string variableName, string cppDefaultValue, | ||||
|         UhtProperty paramProperty, PropertyTranslator translator) | ||||
|     { | ||||
| 	    UhtStructProperty structProperty = (UhtStructProperty)paramProperty; | ||||
| 	    string structName = structProperty.ScriptStruct.GetStructName(); | ||||
|  | ||||
| 	    string fieldInitializerList; | ||||
| 	    if (cppDefaultValue.StartsWith("(") && cppDefaultValue.EndsWith(")")) | ||||
| 	    { | ||||
| 		    fieldInitializerList = cppDefaultValue.Substring(1, cppDefaultValue.Length - 2); | ||||
| 	    } | ||||
| 	    else | ||||
| 	    { | ||||
| 		    fieldInitializerList = cppDefaultValue; | ||||
| 	    } | ||||
| 	     | ||||
| 	    if (fieldInitializerList.Length == 0) | ||||
| 	    { | ||||
| 		    return; | ||||
| 	    } | ||||
| 	     | ||||
| 	    List<string> fieldInitializers = new List<string>(); | ||||
| 	    string[] parts = fieldInitializerList.Split(','); | ||||
|  | ||||
| 	    foreach (string part in parts) | ||||
| 	    { | ||||
| 		    fieldInitializers.Add(part.Trim()); | ||||
| 	    } | ||||
|  | ||||
| 		string foundCSharpType = translator.GetManagedType(paramProperty); | ||||
| 		builder.AppendLine($"{foundCSharpType} {variableName} = new {foundCSharpType}"); | ||||
| 		builder.OpenBrace(); | ||||
| 		 | ||||
| 		if (structName == "Color") | ||||
| 		{ | ||||
| 			(fieldInitializers[0], fieldInitializers[2]) = (fieldInitializers[2], fieldInitializers[0]); | ||||
| 		} | ||||
| 		 | ||||
| 		int fieldCount = fieldInitializers.Count; | ||||
| 		for (int i = 0; i < fieldCount; i++) | ||||
| 		{ | ||||
| 			UhtProperty property = (UhtProperty) structProperty.ScriptStruct.Children[i]; | ||||
| 			PropertyTranslator propertyTranslator = PropertyTranslatorManager.GetTranslator(property)!; | ||||
| 			 | ||||
| 			string managedType = propertyTranslator.GetManagedType(property); | ||||
| 			bool isFloat = managedType is "float" or "double"; | ||||
| 			 | ||||
| 			string scriptName = property.SourceName; | ||||
| 			string fieldInitializer = fieldInitializers[i]; | ||||
|  | ||||
| 			int pos = fieldInitializer.IndexOf("=", StringComparison.Ordinal); | ||||
| 			if (pos < 0) | ||||
| 			{ | ||||
| 				builder.AppendLine(isFloat ? $"{scriptName}={fieldInitializer}f," : $"{scriptName}={fieldInitializer},"); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				builder.AppendLine(isFloat ? $"{fieldInitializer}f," : $"{fieldInitializer},"); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		builder.CloseBrace(); | ||||
| 		builder.Append(";"); | ||||
|     } | ||||
|  | ||||
|     public override void ExportCleanupMarshallingBuffer(GeneratorStringBuilder builder, UhtProperty property, | ||||
| 	    string paramName) | ||||
|     { | ||||
| 	    // No cleanup needed | ||||
|     } | ||||
|  | ||||
| 	public override bool CanSupportGenericType(UhtProperty property) => true; | ||||
| } | ||||
| @ -0,0 +1,65 @@ | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class SinglecastDelegatePropertyTranslator : DelegateBasePropertyTranslator | ||||
| { | ||||
|     public SinglecastDelegatePropertyTranslator() : base(EPropertyUsageFlags.Parameter) | ||||
|     { | ||||
|     } | ||||
|      | ||||
|     public override bool CanExport(UhtProperty property) | ||||
|     { | ||||
|         UhtDelegateProperty delegateProperty = (UhtDelegateProperty) property; | ||||
|         bool hasReturnValue = delegateProperty.Function.ReturnProperty != null; | ||||
|         return ScriptGeneratorUtilities.CanExportParameters(delegateProperty.Function) && !hasReturnValue; | ||||
|     } | ||||
|      | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         return $"TDelegate<{GetFullDelegateName(((UhtDelegateProperty) property).Function)}>"; | ||||
|     } | ||||
|  | ||||
|     public override void ExportPropertyStaticConstructor(GeneratorStringBuilder builder, UhtProperty property, string nativePropertyName) | ||||
|     { | ||||
|         base.ExportPropertyStaticConstructor(builder, property, nativePropertyName); | ||||
|          | ||||
|         UhtDelegateProperty delegateProperty = (UhtDelegateProperty) property; | ||||
|          | ||||
|         if (!delegateProperty.Function.HasParameters) | ||||
|         { | ||||
|             return; | ||||
|         } | ||||
|          | ||||
|         string fullDelegateName = GetFullDelegateName(delegateProperty.Function, true); | ||||
|         builder.AppendLine($"{fullDelegateName}.InitializeUnrealDelegate({nativePropertyName}_NativeProperty);"); | ||||
|     } | ||||
|  | ||||
|     public override void ExportToNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName, string destinationBuffer, | ||||
|         string offset, string source) | ||||
|     { | ||||
|         UhtDelegateProperty delegateProperty = (UhtDelegateProperty) property; | ||||
|         string fullDelegateName = GetFullDelegateName(delegateProperty.Function); | ||||
|         builder.AppendLine($"SingleDelegateMarshaller<{fullDelegateName}>.ToNative(IntPtr.Add({destinationBuffer}, {offset}), 0, {source});"); | ||||
|     } | ||||
|  | ||||
|     public override void ExportFromNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName, | ||||
|         string assignmentOrReturn, string sourceBuffer, string offset, bool bCleanupSourceBuffer, bool reuseRefMarshallers) | ||||
|     { | ||||
|         UhtDelegateProperty delegateProperty = (UhtDelegateProperty) property; | ||||
|         string fullDelegateName = GetFullDelegateName(delegateProperty.Function); | ||||
|         builder.AppendLine($"{assignmentOrReturn} SingleDelegateMarshaller<{fullDelegateName}>.FromNative(IntPtr.Add({sourceBuffer}, {offset}), 0);"); | ||||
|     } | ||||
|  | ||||
|     public override string GetNullValue(UhtProperty property) | ||||
|     { | ||||
|         return "null"; | ||||
|     } | ||||
|  | ||||
|     public override void ExportCleanupMarshallingBuffer(GeneratorStringBuilder builder, UhtProperty property, | ||||
|         string paramName) | ||||
|     { | ||||
|          | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,35 @@ | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class SoftClassPropertyTranslator : SimpleTypePropertyTranslator | ||||
| { | ||||
|     public SoftClassPropertyTranslator() : base(typeof(UhtSoftClassProperty)) | ||||
|     { | ||||
|          | ||||
|     } | ||||
|      | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         UhtSoftClassProperty softClassProperty = (UhtSoftClassProperty)property; | ||||
|         string fullName = property.IsGenericType() | ||||
|              ? "DOT" : softClassProperty.MetaClass!.GetFullManagedName(); | ||||
|  | ||||
|         return $"TSoftClassPtr<{fullName}>"; | ||||
|     } | ||||
|  | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
|         UhtSoftClassProperty softClassProperty = (UhtSoftClassProperty) property; | ||||
|         string fullName = property.IsGenericType() | ||||
|              ? "DOT" : softClassProperty.MetaClass!.GetFullManagedName(); | ||||
|  | ||||
|         return $"SoftClassMarshaller<{fullName}>"; | ||||
|     } | ||||
|  | ||||
|     public override bool CanExport(UhtProperty property) | ||||
|     { | ||||
|         return property is UhtSoftClassProperty; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,33 @@ | ||||
| using System.Collections.Generic; | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class SoftObjectPropertyTranslator : SimpleTypePropertyTranslator | ||||
| { | ||||
|     public SoftObjectPropertyTranslator() : base(typeof(UhtSoftObjectProperty)) | ||||
|     { | ||||
|     } | ||||
|      | ||||
|     public override bool CanExport(UhtProperty property) | ||||
|     { | ||||
|         return property is UhtSoftObjectProperty; | ||||
|     } | ||||
|  | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         UhtSoftObjectProperty softObjectProperty = (UhtSoftObjectProperty)property; | ||||
|         string fullName = softObjectProperty.Class.GetFullManagedName(); | ||||
|         return $"TSoftObjectPtr<{fullName}>"; | ||||
|     } | ||||
|  | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
|         UhtSoftObjectProperty softClassProperty = (UhtSoftObjectProperty) property; | ||||
|         string fullName = softClassProperty.Class.GetFullManagedName(); | ||||
|         return $"SoftObjectMarshaller<{fullName}>"; | ||||
|     } | ||||
|  | ||||
|     public override bool CanSupportGenericType(UhtProperty property) => false; | ||||
| } | ||||
| @ -0,0 +1,74 @@ | ||||
| using System; | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class StringPropertyTranslator : PropertyTranslator | ||||
| { | ||||
|     public StringPropertyTranslator() : base(EPropertyUsageFlags.Any, PropertyKind.String) | ||||
|     { | ||||
|     } | ||||
|      | ||||
|     public override bool CacheProperty => true; | ||||
|  | ||||
|     public override bool CanExport(UhtProperty property) | ||||
|     { | ||||
|         return property is UhtStrProperty; | ||||
|     } | ||||
|  | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         return "string"; | ||||
|     } | ||||
|  | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
|         return "StringMarshaller"; | ||||
|     } | ||||
|  | ||||
|     public override string ExportMarshallerDelegates(UhtProperty property) | ||||
|     { | ||||
|         return "StringMarshaller.ToNative, StringMarshaller.FromNative"; | ||||
|     } | ||||
|  | ||||
|     public override string GetNullValue(UhtProperty property) | ||||
|     { | ||||
|         return "\"\""; | ||||
|     } | ||||
|  | ||||
|     public override void ExportFunctionReturnStatement(GeneratorStringBuilder builder, UhtProperty property, string nativePropertyName, | ||||
|         string functionName, string paramsCallString) | ||||
|     { | ||||
|         builder.AppendLine($"return {ExporterCallbacks.FStringCallbacks}.CallConvertTCHARToUTF8(Invoke_{functionName}(NativeObject, {functionName}_NativeFunction{paramsCallString}));"); | ||||
|     } | ||||
|  | ||||
|     public override void ExportCleanupMarshallingBuffer(GeneratorStringBuilder builder, UhtProperty property, | ||||
|         string paramName) | ||||
|     { | ||||
|         builder.AppendLine($"StringMarshaller.DestructInstance({paramName}_NativePtr, 0);"); | ||||
|     } | ||||
|  | ||||
|     public override void ExportFromNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName, string assignmentOrReturn, | ||||
|         string sourceBuffer, string offset, bool bCleanupSourceBuffer, bool reuseRefMarshallers) | ||||
|     { | ||||
|         if (!reuseRefMarshallers) | ||||
|         { | ||||
|             builder.AppendLine($"IntPtr {propertyName}_NativePtr = IntPtr.Add({sourceBuffer},{offset});"); | ||||
|         } | ||||
|         builder.AppendLine($"{assignmentOrReturn} StringMarshaller.FromNative({propertyName}_NativePtr,0);"); | ||||
|     } | ||||
|  | ||||
|     public override void ExportToNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName, string destinationBuffer, string offset, string source) | ||||
|     { | ||||
|         builder.AppendLine($"IntPtr {propertyName}_NativePtr = IntPtr.Add({destinationBuffer}, {offset});"); | ||||
|         builder.AppendLine($"StringMarshaller.ToNative({propertyName}_NativePtr,0,{source});"); | ||||
|     } | ||||
|  | ||||
|     public override string ConvertCPPDefaultValue(string defaultValue, UhtFunction function, UhtProperty parameter) | ||||
|     { | ||||
|         return "\"" + defaultValue + "\""; | ||||
|     } | ||||
|  | ||||
|     public override bool CanSupportGenericType(UhtProperty property) => false; | ||||
| } | ||||
| @ -0,0 +1,33 @@ | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class StructPropertyTranslator : SimpleTypePropertyTranslator | ||||
| { | ||||
|     public StructPropertyTranslator() : base(typeof(UhtStructProperty)) | ||||
|     { | ||||
|     } | ||||
|      | ||||
|     public override bool ExportDefaultParameter => false; | ||||
|     public override bool IsBlittable => false; | ||||
|  | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|        UhtStructProperty structProperty = (UhtStructProperty)property;  | ||||
|        return structProperty.ScriptStruct.GetFullManagedName(); | ||||
|     } | ||||
|  | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
|         return $"StructMarshaller<{GetManagedType(property)}>"; | ||||
|     } | ||||
|  | ||||
|     public override void ExportCppDefaultParameterAsLocalVariable(GeneratorStringBuilder builder, string variableName, string defaultValue, | ||||
|         UhtFunction function, UhtProperty paramProperty) | ||||
|     { | ||||
|         ExportDefaultStructParameter(builder, variableName, defaultValue, paramProperty, this); | ||||
|     } | ||||
|  | ||||
|     public override bool CanSupportGenericType(UhtProperty property) => false; | ||||
| } | ||||
| @ -0,0 +1,32 @@ | ||||
| using System; | ||||
| using System.Text; | ||||
| using EpicGames.UHT.Types; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class TextPropertyTranslator : BlittableTypePropertyTranslator | ||||
| { | ||||
|     public TextPropertyTranslator() : base(typeof(UhtTextProperty), "FText", PropertyKind.Unknown) | ||||
|     { | ||||
|     } | ||||
|      | ||||
|     public override bool ExportDefaultParameter => false; | ||||
|      | ||||
|     public override string GetNullValue(UhtProperty property) | ||||
|     { | ||||
|         return "FText.None"; | ||||
|     } | ||||
|  | ||||
|     public override void ExportCppDefaultParameterAsLocalVariable(GeneratorStringBuilder builder, string variableName, string defaultValue, | ||||
|         UhtFunction function, UhtProperty paramProperty) | ||||
|     { | ||||
|         builder.AppendLine($"FText {variableName} = FText.None;"); | ||||
|     } | ||||
|  | ||||
|     public override string GetMarshaller(UhtProperty property) | ||||
|     { | ||||
|         return "TextMarshaller"; | ||||
|     } | ||||
|  | ||||
|     public override bool CanSupportGenericType(UhtProperty property) => false; | ||||
| } | ||||
| @ -0,0 +1,29 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class WeakObjectPropertyTranslator : BlittableTypePropertyTranslator | ||||
| { | ||||
|     public WeakObjectPropertyTranslator() : base(typeof(UhtWeakObjectPtrProperty), "TWeakObjectPtr", PropertyKind.Unknown) | ||||
|     { | ||||
|     } | ||||
|      | ||||
|     public override bool ExportDefaultParameter => false; | ||||
|  | ||||
|     public override string GetManagedType(UhtProperty property) | ||||
|     { | ||||
|         UhtWeakObjectPtrProperty weakObjectProperty = (UhtWeakObjectPtrProperty)property; | ||||
|         string fullName = weakObjectProperty.Class.GetFullManagedName(); | ||||
|         return $"TWeakObjectPtr<{fullName}>"; | ||||
|     } | ||||
|  | ||||
|     public override bool CanExport(UhtProperty property) | ||||
|     { | ||||
|         return property is UhtWeakObjectPtrProperty; | ||||
|     } | ||||
|  | ||||
|     public override bool CanSupportGenericType(UhtProperty property) => false; | ||||
| } | ||||
| @ -0,0 +1,22 @@ | ||||
| using EpicGames.UHT.Types; | ||||
| using UnrealSharpScriptGenerator.Utilities; | ||||
|  | ||||
| namespace UnrealSharpScriptGenerator.PropertyTranslators; | ||||
|  | ||||
| public class WorldContextObjectPropertyTranslator : ObjectPropertyTranslator | ||||
| { | ||||
|     public override bool ShouldBeDeclaredAsParameter => false; | ||||
|  | ||||
|     public override bool CanExport(UhtProperty property) | ||||
|     { | ||||
|         return base.CanExport(property) && property.IsWorldContextParameter(); | ||||
|     } | ||||
|  | ||||
|     public override void ExportToNative(GeneratorStringBuilder builder, UhtProperty property, string propertyName, string destinationBuffer, | ||||
|         string offset, string source) | ||||
|     { | ||||
|         builder.AppendLine($"BlittableMarshaller<IntPtr>.ToNative(IntPtr.Add({destinationBuffer}, {offset}), 0, UnrealSharp.Core.FCSManagerExporter.CallGetCurrentWorldContext());"); | ||||
|     } | ||||
|  | ||||
|     public override bool CanSupportGenericType(UhtProperty property) => false; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user