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