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); | |||
|  |     } | |||
|  | } |