diff --git a/CringePlugins/Loader/PluginInstance.cs b/CringePlugins/Loader/PluginInstance.cs index 697db4d..bd63878 100644 --- a/CringePlugins/Loader/PluginInstance.cs +++ b/CringePlugins/Loader/PluginInstance.cs @@ -2,7 +2,6 @@ using System.Runtime.Loader; using CringeBootstrap.Abstractions; using CringePlugins.Utils; -using dnlib.DotNet; using NLog; using SharedCringe.Loader; using VRage.Plugins; @@ -16,10 +15,12 @@ internal sealed class PluginInstance private readonly string _entrypointPath; private PluginAssemblyLoadContext? _context; private IPlugin? _instance; + private Action? _openConfigAction; private IHandleInputPlugin? _handleInputInstance; + private PluginWrapper? _wrappedInstance; - private static readonly NLog.ILogger Log = LogManager.GetCurrentClassLogger(); + private static readonly ILogger Log = LogManager.GetCurrentClassLogger(); public PluginMetadata Metadata { get; } public PluginInstance(PluginMetadata metadata, string entrypointPath) @@ -67,6 +68,7 @@ internal sealed class PluginInstance } _handleInputInstance = _instance as IHandleInputPlugin; + _wrappedInstance = new PluginWrapper(Metadata.Name, _instance); } public void RegisterLifetime() @@ -74,9 +76,9 @@ internal sealed class PluginInstance if (_instance is null) throw new InvalidOperationException("Must call Instantiate first"); - MyPlugins.m_plugins.Add(_instance); + MyPlugins.m_plugins.Add(_wrappedInstance); if (_handleInputInstance is not null) - MyPlugins.m_handleInputPlugins.Add(_handleInputInstance); + MyPlugins.m_handleInputPlugins.Add(_wrappedInstance); } public void OpenConfig() diff --git a/CringePlugins/Loader/PluginWrapper.cs b/CringePlugins/Loader/PluginWrapper.cs new file mode 100644 index 0000000..002231b --- /dev/null +++ b/CringePlugins/Loader/PluginWrapper.cs @@ -0,0 +1,72 @@ +using NLog; +using VRage.Plugins; + +namespace CringePlugins.Loader; + +//todo: we should patch Mysanboxgame.Run to log init of actual plugin names instead of pluginwrapper +//also, maybe we could unload the plugin if there's an error? +internal sealed class PluginWrapper(string name, IPlugin plugin) : IHandleInputPlugin +{ + public bool HasError => LastException != null; + public Exception? LastException { get; private set; } //todo: show exception when hovered in plugin menu? + + private static readonly ILogger Log = LogManager.GetCurrentClassLogger(); + + public void Dispose() + { + try + { + plugin.Dispose(); + } + catch (Exception e) + { + Log.Error(e, "Error Disposing {Name}", name); + LastException = e; + } + } + + public void HandleInput() + { + if (HasError || plugin is not IHandleInputPlugin input) + return; + + try + { + input.HandleInput(); + } + catch (Exception e) + { + Log.Error(e, "Error Updating {Name}", name); + LastException = e; + } + } + + public void Init(object gameInstance) + { + try + { + plugin.Init(gameInstance); + } + catch (Exception e) + { + Log.Error(e, "Error Initializing {Name}", name); + LastException = e; + } + } + + public void Update() + { + if (HasError) + return; + + try + { + plugin.Update(); + } + catch (Exception e) + { + Log.Error(e, "Error Updating {Name}", name); + LastException = e; + } + } +}