Files
BusyRabbit/Plugins/UnrealSharp/Source/UnrealSharpCore/CSManager.h
wyatt 648386cd73 Lua向C#逻辑迁移 一期 #13
将整个插件代码上传
2025-10-26 21:48:39 +08:00

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