restore InterfaceProxyFactory to encapsulate Pintail (#830)
This commit is contained in:
parent
512c2b9fb7
commit
0f987c0578
|
@ -1,5 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using Nanoray.Pintail;
|
||||
using StardewModdingAPI.Framework.Reflection;
|
||||
|
||||
namespace StardewModdingAPI.Framework.ModHelpers
|
||||
|
@ -17,10 +16,10 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
|||
private readonly IMonitor Monitor;
|
||||
|
||||
/// <summary>The mod IDs for APIs accessed by this instanced.</summary>
|
||||
private readonly HashSet<string> AccessedModApis = new HashSet<string>();
|
||||
private readonly HashSet<string> AccessedModApis = new();
|
||||
|
||||
/// <summary>Generates proxy classes to access mod APIs through an arbitrary interface.</summary>
|
||||
private readonly IProxyManager<string> ProxyManager;
|
||||
private readonly InterfaceProxyFactory ProxyFactory;
|
||||
|
||||
|
||||
/*********
|
||||
|
@ -29,13 +28,13 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
|||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="modID">The unique ID of the relevant mod.</param>
|
||||
/// <param name="registry">The underlying mod registry.</param>
|
||||
/// <param name="proxyManager">Generates proxy classes to access mod APIs through an arbitrary interface.</param>
|
||||
/// <param name="proxyFactory">Generates proxy classes to access mod APIs through an arbitrary interface.</param>
|
||||
/// <param name="monitor">Encapsulates monitoring and logging for the mod.</param>
|
||||
public ModRegistryHelper(string modID, ModRegistry registry, IProxyManager<string> proxyManager, IMonitor monitor)
|
||||
public ModRegistryHelper(string modID, ModRegistry registry, InterfaceProxyFactory proxyFactory, IMonitor monitor)
|
||||
: base(modID)
|
||||
{
|
||||
this.Registry = registry;
|
||||
this.ProxyManager = proxyManager;
|
||||
this.ProxyFactory = proxyFactory;
|
||||
this.Monitor = monitor;
|
||||
}
|
||||
|
||||
|
@ -95,9 +94,9 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
|||
}
|
||||
|
||||
// get API of type
|
||||
if (api is TInterface castApi)
|
||||
return castApi;
|
||||
return this.ProxyManager.ObtainProxy<string, TInterface>(api, this.ModID, uniqueID);
|
||||
return api is TInterface castApi
|
||||
? castApi
|
||||
: this.ProxyFactory.CreateProxy<TInterface>(api, sourceModID: this.ModID, targetModID: uniqueID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using Nanoray.Pintail;
|
||||
|
||||
namespace StardewModdingAPI.Framework.Reflection
|
||||
{
|
||||
/// <summary>Generates proxy classes to access mod APIs through an arbitrary interface.</summary>
|
||||
internal class InterfaceProxyFactory
|
||||
{
|
||||
/*********
|
||||
** Fields
|
||||
*********/
|
||||
/// <summary>The underlying proxy type builder.</summary>
|
||||
private readonly IProxyManager<string> ProxyManager;
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
public InterfaceProxyFactory()
|
||||
{
|
||||
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName($"StardewModdingAPI.Proxies, Version={this.GetType().Assembly.GetName().Version}, Culture=neutral"), AssemblyBuilderAccess.Run);
|
||||
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StardewModdingAPI.Proxies");
|
||||
this.ProxyManager = new ProxyManager<string>(moduleBuilder, new ProxyManagerConfiguration<string>(
|
||||
proxyPrepareBehavior: ProxyManagerProxyPrepareBehavior.Eager,
|
||||
proxyObjectInterfaceMarking: ProxyObjectInterfaceMarking.Disabled
|
||||
));
|
||||
}
|
||||
|
||||
/// <summary>Create an API proxy.</summary>
|
||||
/// <typeparam name="TInterface">The interface through which to access the API.</typeparam>
|
||||
/// <param name="instance">The API instance to access.</param>
|
||||
/// <param name="sourceModID">The unique ID of the mod consuming the API.</param>
|
||||
/// <param name="targetModID">The unique ID of the mod providing the API.</param>
|
||||
public TInterface CreateProxy<TInterface>(object instance, string sourceModID, string targetModID)
|
||||
where TInterface : class
|
||||
{
|
||||
return this.ProxyManager.ObtainProxy<string, TInterface>(instance, targetContext: targetModID, proxyContext: sourceModID);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -48,8 +48,6 @@ using xTile.Display;
|
|||
using MiniMonoModHotfix = MonoMod.Utils.MiniMonoModHotfix;
|
||||
using PathUtilities = StardewModdingAPI.Toolkit.Utilities.PathUtilities;
|
||||
using SObject = StardewValley.Object;
|
||||
using Nanoray.Pintail;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
namespace StardewModdingAPI.Framework
|
||||
{
|
||||
|
@ -1490,17 +1488,12 @@ namespace StardewModdingAPI.Framework
|
|||
{
|
||||
// init
|
||||
HashSet<string> suppressUpdateChecks = new HashSet<string>(this.Settings.SuppressUpdateChecks, StringComparer.OrdinalIgnoreCase);
|
||||
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName($"StardewModdingAPI.Proxies, Version={this.GetType().Assembly.GetName().Version}, Culture=neutral"), AssemblyBuilderAccess.Run);
|
||||
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StardewModdingAPI.Proxies");
|
||||
IProxyManager<string> proxyManager = new ProxyManager<string>(moduleBuilder, new ProxyManagerConfiguration<string>(
|
||||
proxyPrepareBehavior: ProxyManagerProxyPrepareBehavior.Eager,
|
||||
proxyObjectInterfaceMarking: ProxyObjectInterfaceMarking.Disabled
|
||||
));
|
||||
InterfaceProxyFactory proxyFactory = new();
|
||||
|
||||
// load mods
|
||||
foreach (IModMetadata mod in mods)
|
||||
{
|
||||
if (!this.TryLoadMod(mod, mods, modAssemblyLoader, proxyManager, jsonHelper, contentCore, modDatabase, suppressUpdateChecks, out ModFailReason? failReason, out string errorPhrase, out string errorDetails))
|
||||
if (!this.TryLoadMod(mod, mods, modAssemblyLoader, proxyFactory, jsonHelper, contentCore, modDatabase, suppressUpdateChecks, out ModFailReason? failReason, out string errorPhrase, out string errorDetails))
|
||||
{
|
||||
failReason ??= ModFailReason.LoadFailed;
|
||||
mod.SetStatus(ModMetadataStatus.Failed, failReason.Value, errorPhrase, errorDetails);
|
||||
|
@ -1603,7 +1596,7 @@ namespace StardewModdingAPI.Framework
|
|||
/// <param name="mod">The mod to load.</param>
|
||||
/// <param name="mods">The mods being loaded.</param>
|
||||
/// <param name="assemblyLoader">Preprocesses and loads mod assemblies.</param>
|
||||
/// <param name="proxyManager">Generates proxy classes to access mod APIs through an arbitrary interface.</param>
|
||||
/// <param name="proxyFactory">Generates proxy classes to access mod APIs through an arbitrary interface.</param>
|
||||
/// <param name="jsonHelper">The JSON helper with which to read mods' JSON files.</param>
|
||||
/// <param name="contentCore">The content manager to use for mod content.</param>
|
||||
/// <param name="modDatabase">Handles access to SMAPI's internal mod metadata list.</param>
|
||||
|
@ -1612,7 +1605,7 @@ namespace StardewModdingAPI.Framework
|
|||
/// <param name="errorReasonPhrase">The user-facing reason phrase explaining why the mod couldn't be loaded (if applicable).</param>
|
||||
/// <param name="errorDetails">More detailed details about the error intended for developers (if any).</param>
|
||||
/// <returns>Returns whether the mod was successfully loaded.</returns>
|
||||
private bool TryLoadMod(IModMetadata mod, IModMetadata[] mods, AssemblyLoader assemblyLoader, IProxyManager<string> proxyManager, JsonHelper jsonHelper, ContentCoordinator contentCore, ModDatabase modDatabase, HashSet<string> suppressUpdateChecks, out ModFailReason? failReason, out string errorReasonPhrase, out string errorDetails)
|
||||
private bool TryLoadMod(IModMetadata mod, IModMetadata[] mods, AssemblyLoader assemblyLoader, InterfaceProxyFactory proxyFactory, JsonHelper jsonHelper, ContentCoordinator contentCore, ModDatabase modDatabase, HashSet<string> suppressUpdateChecks, out ModFailReason? failReason, out string errorReasonPhrase, out string errorDetails)
|
||||
{
|
||||
errorDetails = null;
|
||||
|
||||
|
@ -1755,7 +1748,7 @@ namespace StardewModdingAPI.Framework
|
|||
IContentPackHelper contentPackHelper = new ContentPackHelper(manifest.UniqueID, new Lazy<IContentPack[]>(GetContentPacks), CreateFakeContentPack);
|
||||
IDataHelper dataHelper = new DataHelper(manifest.UniqueID, mod.DirectoryPath, jsonHelper);
|
||||
IReflectionHelper reflectionHelper = new ReflectionHelper(manifest.UniqueID, mod.DisplayName, this.Reflection);
|
||||
IModRegistry modRegistryHelper = new ModRegistryHelper(manifest.UniqueID, this.ModRegistry, proxyManager, monitor);
|
||||
IModRegistry modRegistryHelper = new ModRegistryHelper(manifest.UniqueID, this.ModRegistry, proxyFactory, monitor);
|
||||
IMultiplayerHelper multiplayerHelper = new MultiplayerHelper(manifest.UniqueID, this.Multiplayer);
|
||||
|
||||
modHelper = new ModHelper(manifest.UniqueID, mod.DirectoryPath, () => this.GetCurrentGameInstance().Input, events, contentHelper, contentPackHelper, commandHelper, dataHelper, modRegistryHelper, reflectionHelper, multiplayerHelper, translationHelper);
|
||||
|
|
Loading…
Reference in New Issue