mirror of
https://github.com/godotengine/godot.git
synced 2024-12-21 10:25:24 +08:00
88e367a406
This base implementation is still very barebones but it defines the path for how exporting will work (at least when embedding the .NET runtime). Many manual steps are still needed, which should be automatized in the future. For example, in addition to the API assemblies, now you also need to copy the GodotPlugins assembly to each game project.
60 lines
2.0 KiB
C#
60 lines
2.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using System.Runtime.Loader;
|
|
|
|
namespace GodotPlugins
|
|
{
|
|
public class PluginLoadContext : AssemblyLoadContext
|
|
{
|
|
private readonly AssemblyDependencyResolver _resolver;
|
|
private readonly ICollection<string> _sharedAssemblies;
|
|
private readonly AssemblyLoadContext _mainLoadContext;
|
|
|
|
public PluginLoadContext(string pluginPath, ICollection<string> sharedAssemblies,
|
|
AssemblyLoadContext mainLoadContext)
|
|
{
|
|
_resolver = new AssemblyDependencyResolver(pluginPath);
|
|
_sharedAssemblies = sharedAssemblies;
|
|
_mainLoadContext = mainLoadContext;
|
|
}
|
|
|
|
protected override Assembly? Load(AssemblyName assemblyName)
|
|
{
|
|
if (assemblyName.Name == null)
|
|
return null;
|
|
|
|
if (_sharedAssemblies.Contains(assemblyName.Name))
|
|
return _mainLoadContext.LoadFromAssemblyName(assemblyName);
|
|
|
|
string? assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
|
|
if (assemblyPath != null)
|
|
{
|
|
// Load in memory to prevent locking the file
|
|
using var assemblyFile = File.Open(assemblyPath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
string pdbPath = Path.ChangeExtension(assemblyPath, ".pdb");
|
|
|
|
if (File.Exists(pdbPath))
|
|
{
|
|
using var pdbFile = File.Open(pdbPath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
return LoadFromStream(assemblyFile, pdbFile);
|
|
}
|
|
|
|
return LoadFromStream(assemblyFile);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
|
|
{
|
|
string? libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
|
|
if (libraryPath != null)
|
|
return LoadUnmanagedDllFromPath(libraryPath);
|
|
|
|
return IntPtr.Zero;
|
|
}
|
|
}
|
|
}
|