From 0e43041777d68b96f110fa38ad7424b855db761a Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 12 Dec 2017 01:00:32 -0500 Subject: add support for casting mod-provided API to an interface without a direct assembly reference (#409) --- .../Framework/ModHelpers/ModRegistryHelper.cs | 24 ++++++++++++++++++++++ src/SMAPI/IModRegistry.cs | 5 +++++ src/SMAPI/StardewModdingAPI.csproj | 3 +++ src/SMAPI/packages.config | 1 + 4 files changed, 33 insertions(+) (limited to 'src/SMAPI') diff --git a/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs b/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs index 827c77d5..68201d9a 100644 --- a/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using ImpromptuInterface; namespace StardewModdingAPI.Framework.ModHelpers { @@ -62,5 +63,28 @@ namespace StardewModdingAPI.Framework.ModHelpers this.Monitor.Log($"Accessed mod-provided API for {mod.DisplayName}.", LogLevel.Trace); return mod?.Api; } + + /// Get the API provided by a mod, mapped to a given interface which specifies the expected properties and methods. If the mod has no API or it's not compatible with the given interface, get null. + /// The interface which matches the properties and methods you intend to access. + /// The mod's unique ID. + public TInterface GetApi(string uniqueID) where TInterface : class + { + // validate + if (!typeof(TInterface).IsInterface) + { + this.Monitor.Log("Tried to map a mod-provided API into a class; must be an interface."); + return null; + } + + // get raw API + object api = this.GetApi(uniqueID); + if (api == null) + return null; + + // get API of type + if (api is TInterface castApi) + return castApi; + return api.ActLike(); + } } } diff --git a/src/SMAPI/IModRegistry.cs b/src/SMAPI/IModRegistry.cs index f84cfcfb..a06e099e 100644 --- a/src/SMAPI/IModRegistry.cs +++ b/src/SMAPI/IModRegistry.cs @@ -20,5 +20,10 @@ namespace StardewModdingAPI /// Get the API provided by a mod, or null if it has none. This signature requires using the API to access the API's properties and methods. /// The mod's unique ID. object GetApi(string uniqueID); + + /// Get the API provided by a mod, mapped to a given interface which specifies the expected properties and methods. If the mod has no API or it's not compatible with the given interface, get null. + /// The interface which matches the properties and methods you intend to access. + /// The mod's unique ID. + TInterface GetApi(string uniqueID) where TInterface : class; } } diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index 0db94843..c585a0c4 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -53,6 +53,9 @@ icon.ico + + ..\packages\ImpromptuInterface.6.2.2\lib\net40\ImpromptuInterface.dll + ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll True diff --git a/src/SMAPI/packages.config b/src/SMAPI/packages.config index 98d742c7..60be6881 100644 --- a/src/SMAPI/packages.config +++ b/src/SMAPI/packages.config @@ -1,5 +1,6 @@  + \ No newline at end of file -- cgit