using System.Collections.Generic;
using StardewModdingAPI.Framework.Reflection;
namespace StardewModdingAPI.Framework.ModHelpers
{
/// Provides metadata about installed mods.
internal class ModRegistryHelper : BaseHelper, IModRegistry
{
/*********
** Fields
*********/
/// The underlying mod registry.
private readonly ModRegistry Registry;
/// Encapsulates monitoring and logging for the mod.
private readonly IMonitor Monitor;
/// The mod IDs for APIs accessed by this instanced.
private readonly HashSet AccessedModApis = new HashSet();
/// Generates proxy classes to access mod APIs through an arbitrary interface.
private readonly InterfaceProxyFactory ProxyFactory;
/*********
** Public methods
*********/
/// Construct an instance.
/// The unique ID of the relevant mod.
/// The underlying mod registry.
/// Generates proxy classes to access mod APIs through an arbitrary interface.
/// Encapsulates monitoring and logging for the mod.
public ModRegistryHelper(string modID, ModRegistry registry, InterfaceProxyFactory proxyFactory, IMonitor monitor)
: base(modID)
{
this.Registry = registry;
this.ProxyFactory = proxyFactory;
this.Monitor = monitor;
}
///
public IEnumerable GetAll()
{
return this.Registry.GetAll();
}
///
public IModInfo Get(string uniqueID)
{
return this.Registry.Get(uniqueID);
}
///
public bool IsLoaded(string uniqueID)
{
return this.Registry.Get(uniqueID) != null;
}
///
public object GetApi(string uniqueID)
{
// validate ready
if (!this.Registry.AreAllModsInitialized)
{
this.Monitor.Log("Tried to access a mod-provided API before all mods were initialized.", LogLevel.Error);
return null;
}
// get raw API
IModMetadata mod = this.Registry.Get(uniqueID);
if (mod?.Api != null && this.AccessedModApis.Add(mod.Manifest.UniqueID))
this.Monitor.Log($"Accessed mod-provided API for {mod.DisplayName}.", LogLevel.Trace);
return mod?.Api;
}
///
public TInterface GetApi(string uniqueID) where TInterface : class
{
// get raw API
object api = this.GetApi(uniqueID);
if (api == null)
return null;
// validate mapping
if (!typeof(TInterface).IsInterface)
{
this.Monitor.Log($"Tried to map a mod-provided API to class '{typeof(TInterface).FullName}'; must be a public interface.", LogLevel.Error);
return null;
}
if (!typeof(TInterface).IsPublic)
{
this.Monitor.Log($"Tried to map a mod-provided API to non-public interface '{typeof(TInterface).FullName}'; must be a public interface.", LogLevel.Error);
return null;
}
// get API of type
if (api is TInterface castApi)
return castApi;
return this.ProxyFactory.CreateProxy(api, this.ModID, uniqueID);
}
}
}