207 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			207 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using Mono.Cecil;
 | |
| using Mono.Cecil.Rocks;
 | |
| using UnrealSharpWeaver.Utilities;
 | |
| 
 | |
| namespace UnrealSharpWeaver;
 | |
| 
 | |
| public class WeaverImporter
 | |
| {
 | |
|     private static WeaverImporter? _instance;
 | |
|     public static WeaverImporter Instance => _instance ??= new WeaverImporter();
 | |
| 
 | |
|     private const string Attributes = ".Attributes";
 | |
| 
 | |
|     public const string UnrealSharpNamespace = "UnrealSharp";
 | |
|     public const string UnrealSharpAttributesNamespace = UnrealSharpNamespace + Attributes;
 | |
| 
 | |
|     public const string UnrealSharpCoreNamespace = UnrealSharpNamespace + ".Core";
 | |
|     public const string UnrealSharpCoreAttributesNamespace = UnrealSharpCoreNamespace + Attributes;
 | |
|     public const string UnrealSharpCoreMarshallers = UnrealSharpCoreNamespace + ".Marshallers";
 | |
| 
 | |
|     public const string InteropNameSpace = UnrealSharpNamespace + ".Interop";
 | |
|     public const string AttributeNamespace = UnrealSharpNamespace + Attributes;
 | |
|     public const string CoreUObjectNamespace = UnrealSharpNamespace + ".CoreUObject";
 | |
|     public const string EngineNamespace = UnrealSharpNamespace + ".Engine";
 | |
| 
 | |
|     public const string UnrealSharpObject = "UnrealSharpObject";
 | |
|     public const string FPropertyCallbacks = "FPropertyExporter";
 | |
| 
 | |
|     public const string CoreUObjectCallbacks = "UCoreUObjectExporter";
 | |
|     public const string UObjectCallbacks = "UObjectExporter";
 | |
|     public const string UScriptStructCallbacks = "UScriptStructExporter";
 | |
|     public const string UFunctionCallbacks = "UFunctionExporter";
 | |
|     public const string MulticastDelegatePropertyCallbacks = "FMulticastDelegatePropertyExporter";
 | |
|     public const string UStructCallbacks = "UStructExporter";
 | |
| 
 | |
|     public const string GeneratedTypeAttribute = "GeneratedTypeAttribute";
 | |
|     
 | |
|     public MethodReference? UFunctionAttributeConstructor => UnrealSharpAssembly.FindType("UFunctionAttribute", "UnrealSharp.Attributes")?.FindMethod(".ctor");
 | |
|     public MethodReference? BlueprintInternalUseAttributeConstructor => UnrealSharpAssembly.FindType("BlueprintInternalUseOnlyAttribute", "UnrealSharp.Attributes.MetaTags")?.FindMethod(".ctor");
 | |
|     
 | |
|     public AssemblyDefinition UnrealSharpAssembly => FindAssembly(UnrealSharpNamespace);
 | |
|     public AssemblyDefinition UnrealSharpCoreAssembly => FindAssembly(UnrealSharpNamespace + ".Core");
 | |
|     
 | |
|     public AssemblyDefinition CurrentWeavingAssembly = null!;
 | |
|     public List<AssemblyDefinition> AllProjectAssemblies = [];
 | |
|     
 | |
|     public MethodReference NativeObjectGetter = null!;
 | |
|     public TypeDefinition IntPtrType = null!;
 | |
|     public MethodReference IntPtrAdd = null!;
 | |
|     public FieldReference IntPtrZero = null!;
 | |
|     public MethodReference IntPtrEqualsOperator = null!;
 | |
|     public TypeReference UnrealSharpObjectType = null!;
 | |
|     public TypeDefinition IInterfaceType = null!;
 | |
|     public MethodReference GetNativeFunctionFromInstanceAndNameMethod = null!;
 | |
|     public TypeReference Int32TypeRef = null!;
 | |
|     public TypeReference UInt64TypeRef = null!;
 | |
|     public TypeReference VoidTypeRef = null!;
 | |
|     public TypeReference ByteTypeRef = null!;
 | |
|     
 | |
|     public TypeReference MarshalledStructReference = null!;
 | |
|     
 | |
|     public MethodReference GetNativeClassFromNameMethod = null!;
 | |
|     public MethodReference GetNativeInterfaceFromNameMethod = null!;
 | |
|     public MethodReference GetNativeStructFromNameMethod = null!;
 | |
|     public MethodReference GetPropertyOffsetFromNameMethod = null!;
 | |
|     public MethodReference GetPropertyOffset = null!;
 | |
|     public MethodReference GetNativePropertyFromNameMethod = null!;
 | |
|     public MethodReference GetNativeFunctionFromClassAndNameMethod = null!;
 | |
|     public MethodReference GetNativeFunctionParamsSizeMethod = null!;
 | |
|     public MethodReference GetNativeStructSizeMethod = null!;
 | |
|     public MethodReference GetSignatureFunction = null!;
 | |
|     public MethodReference InitializeStructMethod = null!;
 | |
|     
 | |
|     public MethodReference InvokeNativeFunctionMethod = null!;
 | |
|     public MethodReference InvokeNativeNetFunction = null!;
 | |
|     public MethodReference InvokeNativeFunctionOutParms = null!;
 | |
| 
 | |
|     public MethodReference GeneratedTypeCtor = null!;
 | |
|     
 | |
|     public TypeDefinition UObjectDefinition = null!;
 | |
|     public TypeDefinition UActorComponentDefinition = null!;
 | |
|     
 | |
|     public TypeDefinition ScriptInterfaceWrapper = null!;
 | |
|     public TypeDefinition ScriptInterfaceMarshaller = null!;
 | |
|     public TypeReference ManagedObjectHandle = null!;
 | |
|     public TypeReference UnmanagedDataStore = null!;
 | |
|     
 | |
|     public MethodReference BlittableTypeConstructor = null!;
 | |
| 
 | |
|     public DefaultAssemblyResolver AssemblyResolver = null!;
 | |
|     
 | |
|     public static void Shutdown()
 | |
|     {
 | |
|         if (_instance == null)
 | |
|         {
 | |
|             return;
 | |
|         }
 | |
|         
 | |
|         foreach (AssemblyDefinition assembly in _instance.AllProjectAssemblies)
 | |
|         {
 | |
|             assembly.Dispose();
 | |
|         }
 | |
|         
 | |
|         _instance.AllProjectAssemblies = [];
 | |
|         _instance.CurrentWeavingAssembly = null!;
 | |
|         _instance = null;
 | |
|     }
 | |
|     
 | |
|     static AssemblyDefinition FindAssembly(string assemblyName)
 | |
|     {
 | |
|         return Instance.AssemblyResolver.Resolve(new AssemblyNameReference(assemblyName, new Version(0, 0)));
 | |
|     }
 | |
| 
 | |
|     public void ImportCommonTypes(AssemblyDefinition userAssembly)
 | |
|     {
 | |
|         CurrentWeavingAssembly = userAssembly;
 | |
|         
 | |
|         TypeSystem typeSystem = CurrentWeavingAssembly.MainModule.TypeSystem;
 | |
|         
 | |
|         Int32TypeRef = typeSystem.Int32;
 | |
|         UInt64TypeRef = typeSystem.UInt64;
 | |
|         VoidTypeRef = typeSystem.Void;
 | |
|         ByteTypeRef = typeSystem.Byte;
 | |
|         
 | |
|         IntPtrType = typeSystem.IntPtr.Resolve();
 | |
|         IntPtrAdd = IntPtrType.FindMethod("Add")!;
 | |
|         IntPtrZero = IntPtrType.FindField("Zero");
 | |
|         IntPtrEqualsOperator = IntPtrType.FindMethod("op_Equality")!;
 | |
| 
 | |
|         UnrealSharpObjectType = UnrealSharpCoreAssembly.FindType(UnrealSharpObject, UnrealSharpCoreNamespace)!;
 | |
|         IInterfaceType = UnrealSharpAssembly.FindType("IInterface", CoreUObjectNamespace)!.Resolve();
 | |
|         
 | |
|         MarshalledStructReference = UnrealSharpCoreAssembly.FindType("MarshalledStruct`1", "UnrealSharp")!.Resolve();
 | |
|         
 | |
|         TypeDefinition unrealSharpObjectType = UnrealSharpObjectType.Resolve();
 | |
|         NativeObjectGetter = unrealSharpObjectType.FindMethod("get_NativeObject")!;
 | |
| 
 | |
|         GetNativeFunctionFromInstanceAndNameMethod = FindExporterMethod(TypeDefinitionUtilities.UClassCallbacks, "CallGetNativeFunctionFromInstanceAndName");
 | |
|         
 | |
|         GetNativeStructFromNameMethod = FindExporterMethod(CoreUObjectCallbacks, "CallGetNativeStructFromName");
 | |
|         GetNativeClassFromNameMethod = FindExporterMethod(CoreUObjectCallbacks, "CallGetNativeClassFromName");
 | |
|         GetNativeInterfaceFromNameMethod = FindExporterMethod(CoreUObjectCallbacks, "CallGetNativeInterfaceFromName");
 | |
|         
 | |
|         GetPropertyOffsetFromNameMethod = FindExporterMethod(FPropertyCallbacks, "CallGetPropertyOffsetFromName");
 | |
|         GetPropertyOffset = FindExporterMethod(FPropertyCallbacks, "CallGetPropertyOffset");
 | |
|         
 | |
|         GetNativePropertyFromNameMethod = FindExporterMethod(FPropertyCallbacks, "CallGetNativePropertyFromName");
 | |
|         
 | |
|         GetNativeFunctionFromClassAndNameMethod = FindExporterMethod(TypeDefinitionUtilities.UClassCallbacks, "CallGetNativeFunctionFromClassAndName");
 | |
|         GetNativeFunctionParamsSizeMethod = FindExporterMethod(UFunctionCallbacks, "CallGetNativeFunctionParamsSize");
 | |
|         
 | |
|         GetNativeStructSizeMethod = FindExporterMethod(UScriptStructCallbacks, "CallGetNativeStructSize");
 | |
|         
 | |
|         InvokeNativeFunctionMethod = FindExporterMethod(UObjectCallbacks, "CallInvokeNativeFunction");
 | |
|         InvokeNativeNetFunction = FindExporterMethod(UObjectCallbacks, "CallInvokeNativeNetFunction");
 | |
|         InvokeNativeFunctionOutParms = FindExporterMethod(UObjectCallbacks, "CallInvokeNativeFunctionOutParms");
 | |
|         
 | |
|         GetSignatureFunction = FindExporterMethod(MulticastDelegatePropertyCallbacks, "CallGetSignatureFunction");
 | |
|         
 | |
|         InitializeStructMethod = FindExporterMethod(UStructCallbacks, "CallInitializeStruct");
 | |
|         
 | |
|         UObjectDefinition = UnrealSharpAssembly.FindType("UObject", CoreUObjectNamespace)!.Resolve();
 | |
|         UActorComponentDefinition = UnrealSharpAssembly.FindType("UActorComponent", EngineNamespace)!.Resolve();
 | |
|         
 | |
|         TypeReference blittableType = UnrealSharpCoreAssembly.FindType(TypeDefinitionUtilities.BlittableTypeAttribute, UnrealSharpCoreAttributesNamespace)!;
 | |
|         BlittableTypeConstructor = blittableType.FindMethod(".ctor")!;
 | |
| 
 | |
|         TypeReference generatedType = UnrealSharpCoreAssembly.FindType(GeneratedTypeAttribute, UnrealSharpCoreAttributesNamespace)!;
 | |
|         GeneratedTypeCtor = generatedType.FindMethod(".ctor")!;
 | |
|         
 | |
|         ScriptInterfaceWrapper = UnrealSharpAssembly.FindType("IScriptInterface", CoreUObjectNamespace)!.Resolve();
 | |
|         ScriptInterfaceMarshaller = UnrealSharpAssembly.FindType("ScriptInterfaceMarshaller`1", CoreUObjectNamespace)!.Resolve();
 | |
|         
 | |
|         ManagedObjectHandle = UnrealSharpAssembly.FindType("FSharedGCHandle", "UnrealSharp.UnrealSharpCore")!.Resolve();
 | |
|         UnmanagedDataStore = UnrealSharpAssembly.FindType("FUnmanagedDataStore", "UnrealSharp.UnrealSharpCore")!.Resolve();
 | |
|     }
 | |
| 
 | |
|     private static MethodReference FindBindingsStaticMethod(string findNamespace, string findClass, string findMethod)
 | |
|     {
 | |
|         foreach (var module in Instance.UnrealSharpAssembly.Modules)
 | |
|         {
 | |
|             foreach (var type in module.GetAllTypes())
 | |
|             {
 | |
|                 if (type.Namespace != findNamespace || type.Name != findClass)
 | |
|                 {
 | |
|                     continue;
 | |
|                 }
 | |
| 
 | |
|                 foreach (var method in type.Methods)
 | |
|                 {
 | |
|                     if (method.IsStatic && method.Name == findMethod)
 | |
|                     {
 | |
|                         return Instance.CurrentWeavingAssembly.MainModule.ImportReference(method);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         throw new Exception("Could not find method " + findMethod + " in class " + findClass + " in namespace " + findNamespace);
 | |
|     }
 | |
| 
 | |
|     private static MethodReference FindExporterMethod(string exporterName, string functionName)
 | |
|     {
 | |
|         return FindBindingsStaticMethod(InteropNameSpace, exporterName, functionName);
 | |
|     }
 | |
| }
 |