209 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			209 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #pragma once
 | |
| 
 | |
| #include <coreclr_delegates.h>
 | |
| #include <hostfxr.h>
 | |
| #include "CSAssembly.h"
 | |
| #include "CSManagedCallbacksCache.h"
 | |
| #include "CSManager.generated.h"
 | |
| 
 | |
| class UCSTypeBuilderManager;
 | |
| class UCSInterface;
 | |
| class UCSEnum;
 | |
| class UCSScriptStruct;
 | |
| class FUnrealSharpCoreModule;
 | |
| class UFunctionsExporter;
 | |
| struct FCSNamespace;
 | |
| struct FCSTypeReferenceMetaData;
 | |
| 
 | |
| struct FCSManagedPluginCallbacks
 | |
| {
 | |
| 	using LoadPluginCallback = FGCHandleIntPtr(__stdcall*)(const TCHAR*, bool);
 | |
| 	using UnloadPluginCallback = bool(__stdcall*)(const TCHAR*);
 | |
| 
 | |
| 	LoadPluginCallback LoadPlugin = nullptr;
 | |
| 	UnloadPluginCallback UnloadPlugin = nullptr;
 | |
| };
 | |
| 
 | |
| using FInitializeRuntimeHost = bool (*)(const TCHAR*, const TCHAR*, FCSManagedPluginCallbacks*, const void*, FCSManagedCallbacks::FManagedCallbacks*);
 | |
| 
 | |
| DECLARE_MULTICAST_DELEGATE_OneParam(FOnManagedAssemblyLoaded, const FName&);
 | |
| DECLARE_MULTICAST_DELEGATE_OneParam(FOnManagedAssemblyUnloaded, const FName&);
 | |
| DECLARE_MULTICAST_DELEGATE(FOnAssembliesReloaded);
 | |
| 
 | |
| DECLARE_MULTICAST_DELEGATE_OneParam(FCSClassEvent, UCSClass*);
 | |
| DECLARE_MULTICAST_DELEGATE_OneParam(FCSStructEvent, UCSScriptStruct*);
 | |
| DECLARE_MULTICAST_DELEGATE_OneParam(FCSInterfaceEvent, UCSInterface*);
 | |
| DECLARE_MULTICAST_DELEGATE_OneParam(FCSEnumEvent, UCSEnum*);
 | |
| 
 | |
| UCLASS()
 | |
| class UNREALSHARPCORE_API UCSManager : public UObject, public FUObjectArray::FUObjectDeleteListener
 | |
| {
 | |
|     GENERATED_BODY()
 | |
| public:
 | |
| 
 | |
|     static UCSManager& GetOrCreate()
 | |
|     {
 | |
|         if (!Instance)
 | |
|         {
 | |
|             Instance = NewObject<UCSManager>(GetTransientPackage(), TEXT("CSManager"), RF_Public | RF_MarkAsRootSet);
 | |
|         }
 | |
| 
 | |
|         return *Instance;
 | |
|     }
 | |
| 
 | |
|     static UCSManager& Get() { return *Instance; }
 | |
| 
 | |
|     // The outermost package for all managed packages. If namespace support is off, this is the only package that will be used.
 | |
|     UPackage* GetGlobalManagedPackage() const { return GlobalManagedPackage; }
 | |
|     UPackage* FindOrAddManagedPackage(FCSNamespace Namespace);
 | |
| 
 | |
|     UCSAssembly* LoadAssemblyByPath(const FString& AssemblyPath, bool bIsCollectible = true);
 | |
| 
 | |
|     // Load an assembly by name that exists in the ProjectRoot/Binaries/Managed folder
 | |
|     UCSAssembly* LoadUserAssemblyByName(const FName AssemblyName, bool bIsCollectible = true);
 | |
| 
 | |
|     // Load an assembly by name that exists in the UnrealSharp/Binaries/Managed folder
 | |
|     UCSAssembly* LoadPluginAssemblyByName(const FName AssemblyName, bool bIsCollectible = true);
 | |
| 
 | |
|     UCSAssembly* FindOwningAssembly(UClass* Class);
 | |
| 
 | |
|     UCSAssembly* FindOwningAssembly(UScriptStruct* Struct);
 | |
| 
 | |
|     UCSAssembly* FindOwningAssembly(UEnum* Enum);
 | |
| 
 | |
|     UCSAssembly* FindAssembly(FName AssemblyName) const
 | |
|     {
 | |
|         return LoadedAssemblies.FindRef(AssemblyName);
 | |
|     }
 | |
| 
 | |
|     UCSAssembly* FindOrLoadAssembly(FName AssemblyName)
 | |
|     {
 | |
|         if (UCSAssembly* Assembly = FindAssembly(AssemblyName))
 | |
|         {
 | |
|             return Assembly;
 | |
|         }
 | |
| 
 | |
|         return LoadUserAssemblyByName(AssemblyName);
 | |
|     }
 | |
| 	
 | |
|     FGCHandle FindManagedObject(const UObject* Object);
 | |
|     FGCHandle FindOrCreateManagedInterfaceWrapper(UObject* Object, UClass* InterfaceClass);
 | |
| 
 | |
|     void SetCurrentWorldContext(UObject* WorldContext) { CurrentWorldContext = WorldContext; }
 | |
|     UObject* GetCurrentWorldContext() const { return CurrentWorldContext.Get(); }
 | |
| 
 | |
|     const FCSManagedPluginCallbacks& GetManagedPluginsCallbacks() const { return ManagedPluginsCallbacks; }
 | |
| 
 | |
|     FOnManagedAssemblyLoaded& OnManagedAssemblyLoadedEvent() { return OnManagedAssemblyLoaded; }
 | |
|     FOnManagedAssemblyUnloaded& OnManagedAssemblyUnloadedEvent() { return OnManagedAssemblyUnloaded; }
 | |
| 	FOnAssembliesReloaded& OnAssembliesLoadedEvent() { return OnAssembliesLoaded; }
 | |
| 
 | |
| #if WITH_EDITOR
 | |
| 	FCSClassEvent& OnNewClassEvent() { return OnNewClass; }
 | |
| 	FCSStructEvent& OnNewStructEvent() { return OnNewStruct; }
 | |
| 	FCSInterfaceEvent& OnNewInterfaceEvent() { return OnNewInterface; }
 | |
| 	FCSEnumEvent& OnNewEnumEvent() { return OnNewEnum; }
 | |
| 
 | |
| 	FSimpleMulticastDelegate& OnProcessedPendingClassesEvent() { return OnProcessedPendingClasses; }
 | |
| #endif
 | |
| 
 | |
| 	void ForEachManagedPackage(const TFunction<void(UPackage*)>& Callback) const
 | |
| 	{
 | |
| 		for (UPackage* Package : AllPackages)
 | |
| 		{
 | |
| 			Callback(Package);
 | |
| 		}
 | |
| 	}
 | |
| 	void ForEachManagedField(const TFunction<void(UObject*)>& Callback) const;
 | |
| 
 | |
| 	bool IsManagedPackage(const UPackage* Package) const { 	return AllPackages.Contains(Package); }
 | |
| 	UPackage* GetPackage(const FCSNamespace Namespace);
 | |
| 
 | |
| 	bool IsManagedType(const UObject* Field) const { return IsManagedPackage(Field->GetOutermost()); }
 | |
| 
 | |
| 	bool IsLoadingAnyAssembly() const;
 | |
| 
 | |
| 	void AddDynamicSubsystemClass(TSubclassOf<UDynamicSubsystem> SubsystemClass);
 | |
| 
 | |
| 	UCSTypeBuilderManager* GetTypeBuilderManager() const { return TypeBuilderManager; }
 | |
| 
 | |
| private:
 | |
| 
 | |
| 	friend UCSAssembly;
 | |
| 	friend FUnrealSharpCoreModule;
 | |
| 
 | |
| 	void Initialize();
 | |
| 	static void Shutdown() { Instance = nullptr; }
 | |
| 
 | |
| 	load_assembly_and_get_function_pointer_fn InitializeNativeHost() const;
 | |
| 
 | |
| 	bool LoadRuntimeHost();
 | |
| 	bool InitializeDotNetRuntime();
 | |
| 	bool LoadAllUserAssemblies();
 | |
| 
 | |
| 	// UObjectArray listener interface
 | |
| 	virtual void NotifyUObjectDeleted(const UObjectBase* Object, int32 Index) override;
 | |
| 	virtual void OnUObjectArrayShutdown() override { GUObjectArray.RemoveUObjectDeleteListener(this); }
 | |
| 	void OnEnginePreExit() { GUObjectArray.RemoveUObjectDeleteListener(this); }
 | |
| 	// End of interface
 | |
| 
 | |
| 	void OnModulesChanged(FName InModuleName, EModuleChangeReason InModuleChangeReason);
 | |
| 	void TryInitializeDynamicSubsystems();
 | |
| 
 | |
|     UCSAssembly* FindOwningAssemblySlow(UField* Field);
 | |
| 
 | |
| 	static UCSManager* Instance;
 | |
| 
 | |
| 	UPROPERTY()
 | |
| 	TArray<TObjectPtr<UPackage>> AllPackages;
 | |
| 
 | |
| 	UPROPERTY()
 | |
| 	TObjectPtr<UPackage> GlobalManagedPackage;
 | |
| 
 | |
| 	UPROPERTY(Transient)
 | |
| 	TArray<TSubclassOf<UDynamicSubsystem>> PendingDynamicSubsystemClasses;
 | |
| 
 | |
| 	UPROPERTY(Transient)
 | |
| 	TObjectPtr<UCSTypeBuilderManager> TypeBuilderManager;
 | |
| 
 | |
| 	// Handles to all active UObjects that has a C# counterpart. The key is the unique ID of the UObject.
 | |
| 	TMap<uint32, TSharedPtr<FGCHandle>> ManagedObjectHandles;
 | |
| 
 | |
| 	// Handles all active UObjects that have interface wrappers in C#. The primary key is the unique ID of the UObject.
 | |
| 	// The second key is the unique ID of the interface class.
 | |
| 	TMap<uint32, TMap<uint32, TSharedPtr<FGCHandle>>> ManagedInterfaceWrappers;
 | |
| 	
 | |
| 	// Map to cache assemblies that native classes are associated with, for quick lookup.
 | |
| 	UPROPERTY()
 | |
| 	TMap<uint32, TObjectPtr<UCSAssembly>> NativeClassToAssemblyMap;
 | |
| 
 | |
| 	UPROPERTY()
 | |
| 	TMap<FName, TObjectPtr<UCSAssembly>> LoadedAssemblies;
 | |
| 
 | |
| 	TWeakObjectPtr<UObject> CurrentWorldContext;
 | |
| 
 | |
| 	FOnManagedAssemblyLoaded OnManagedAssemblyLoaded;
 | |
|     FOnManagedAssemblyUnloaded OnManagedAssemblyUnloaded;
 | |
| 	FOnAssembliesReloaded OnAssembliesLoaded;
 | |
| 
 | |
| #if WITH_EDITORONLY_DATA
 | |
| 	FCSClassEvent OnNewClass;
 | |
| 	FCSStructEvent OnNewStruct;
 | |
| 	FCSInterfaceEvent OnNewInterface;
 | |
| 	FCSEnumEvent OnNewEnum;
 | |
| 
 | |
| 	FSimpleMulticastDelegate OnProcessedPendingClasses;
 | |
| #endif
 | |
| 
 | |
| 	FCSManagedPluginCallbacks ManagedPluginsCallbacks;
 | |
| 
 | |
| 	//.NET Core Host API
 | |
| 	hostfxr_initialize_for_dotnet_command_line_fn Hostfxr_Initialize_For_Dotnet_Command_Line = nullptr;
 | |
| 	hostfxr_initialize_for_runtime_config_fn Hostfxr_Initialize_For_Runtime_Config = nullptr;
 | |
| 	hostfxr_get_runtime_delegate_fn Hostfxr_Get_Runtime_Delegate = nullptr;
 | |
| 	hostfxr_close_fn Hostfxr_Close = nullptr;
 | |
| 
 | |
| 	void* RuntimeHost = nullptr;
 | |
| 	//End
 | |
| };
 |