Skip to content

Commit

Permalink
Use Autofac to create plugins
Browse files Browse the repository at this point in the history
LuaGlueFactories are not removed and a part of a Plugin. Upon starting
loading a lua script, it will ask all existing plugins for their glues
(if any) and apply them.

A side-effect of this meant, that Components without Plugins but with
LuaGlue wouldn't work. To fix this, two new plugins were defined:

- InternalPlugin
- UIPlugin

Could finally remove all the component registration code, so now
component is merely a directory containing plugins, factories, events
and handlers.
  • Loading branch information
dennis committed Apr 2, 2021
1 parent f226504 commit 6f28a54
Show file tree
Hide file tree
Showing 53 changed files with 245 additions and 684 deletions.
1 change: 1 addition & 0 deletions Backend/Bootstrap/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,5 @@ register_plugin({ plugin_name = "FileMonitorPlugin"})
register_plugin({ plugin_name = "PlaybackPlugin"})

-- UI to show console output
register_plugin({ plugin_name = "UIPlugin"})
register_plugin({ plugin_name = "WinFormUIPlugin"})
16 changes: 12 additions & 4 deletions Backend/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using Serilog;
using Slipstream.Components.Internal;
using Slipstream.Components.Internal.Events;
using Slipstream.Components.Internal.Services;
using Slipstream.Shared;
using Slipstream.Shared.Helpers.StrongParameters;
using System;
Expand All @@ -23,7 +22,15 @@ internal class Engine : IEngine, IDisposable
private readonly IEventHandlerController EventHandlerController;
private bool Stopped = false;

public Engine(ILogger logger, IInternalEventFactory eventFactory, IEventBus eventBus, IPluginFactory pluginFactory, IPluginManager pluginManager, IEventHandlerController eventHandlerController)
public Engine(
ILogger logger,
IInternalEventFactory eventFactory,
IEventBus eventBus,
IPluginFactory pluginFactory,
IPluginManager pluginManager,
IEventHandlerController eventHandlerController,
ILuaService luaService
)
{
EventFactory = eventFactory;
EventBus = eventBus;
Expand Down Expand Up @@ -53,8 +60,9 @@ public Engine(ILogger logger, IInternalEventFactory eventFactory, IEventBus even

Logger.Information("Loading {initcfg}", initFilename);

// FIXME: This needs to be reimplemented
var luaService = new LuaService(new System.Collections.Generic.List<Components.ILuaGlue> { new Slipstream.Components.Internal.LuaGlues.InternalLuaGlue(eventBus, EventFactory) });
// We need to bootstrap this. InternalPlugin isn't loaded yet, as we're about to parse init.lua. However
// InternalPlugin provides the register_plugin() method, so we need to add it here, to make init.lua work
PluginManager.RegisterPlugin(PluginFactory.CreatePlugin("InternalPlugin", "InternalPlugin", new Parameters()));
luaService.Parse(initFilename);
}

Expand Down
66 changes: 11 additions & 55 deletions Backend/PluginManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,63 +3,41 @@
using Autofac;
using Serilog;
using Slipstream.Components;
using Slipstream.Components.AppilcationUpdate;
using Slipstream.Components.Audio;
using Slipstream.Components.Discord;
using Slipstream.Components.FileMonitor;
using Slipstream.Components.Internal;
using Slipstream.Components.IRacing;
using Slipstream.Components.Lua;
using Slipstream.Components.Playback;
using Slipstream.Components.Twitch;
using Slipstream.Components.UI;
using Slipstream.Shared;
using Slipstream.Shared.Helpers.StrongParameters;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using static Slipstream.Components.Internal.IInternalEventFactory;

namespace Slipstream.Backend
{
public class PluginManager : IPluginManager, IPluginFactory
{
private readonly IInternalEventFactory InternalEventFactory;
private readonly IEventSerdeService EventSerdeService;
private readonly IEventBus EventBus;
private readonly IDictionary<string, PluginWorker> PluginWorkers = new Dictionary<string, PluginWorker>();
private readonly IDictionary<string, Type> PluginFactories = new Dictionary<string, Type>();
private readonly ILogger Logger;
private readonly ILifetimeScope LifetimeScope;
private readonly ComponentRegistrator Registrator;
private readonly Dictionary<string, Func<IComponentPluginCreationContext, IPlugin>> ComponentPlugins = new Dictionary<string, Func<IComponentPluginCreationContext, IPlugin>>();
private readonly IEnumerable<Type> LuaGlueTypes;

public PluginManager(
IInternalEventFactory internalEventFactory,
IEventBus eventBus,
ILogger logger,
IEventSerdeService eventSerdeService,
ILifetimeScope lifetimeScope
)
{
Registrator = new ComponentRegistrator(
ComponentPlugins,
logger,
eventBus);

foreach (var type in typeof(PluginManager).Assembly.GetTypes().Where(t => typeof(IComponent).IsAssignableFrom(t) && !t.IsAbstract && t.IsClass))
foreach (var type in lifetimeScope.GetImplementingTypes<IPlugin>())
{
logger.Information("Initializing component {pluginName}", type.Name);
((IComponent)Activator.CreateInstance(type)).Register(Registrator);
logger.Information("Found plugin {pluginName}", type.Name);
PluginFactories.Add(type.Name, type);
}

InternalEventFactory = internalEventFactory;
EventSerdeService = eventSerdeService;
EventBus = eventBus;
Logger = logger;
LifetimeScope = lifetimeScope;
LuaGlueTypes = lifetimeScope.GetImplementingTypes<ILuaGlue>();
}

public void UnregisterPlugin(IPlugin p)
Expand Down Expand Up @@ -151,37 +129,15 @@ public IPlugin CreatePlugin(string pluginId, string name, Parameters configurati

public IPlugin CreatePlugin(string pluginId, string pluginName, IEventBus eventBus, Parameters configuration)
{
List<ILuaGlue> luaGlues = new List<ILuaGlue>();

foreach (var luaGlueType in LuaGlueTypes)
{
luaGlues.Add((ILuaGlue)LifetimeScope.Resolve(luaGlueType, new NamedParameter("configuration", configuration)));
}
if (!PluginFactories.ContainsKey(pluginName))
throw new KeyNotFoundException($"Plugin name '{pluginName}' not found");

ComponentPluginCreationContext reg = new ComponentPluginCreationContext(
Registrator,
this,
this,
pluginId,
pluginName,
configuration,
EventSerdeService,
LifetimeScope.Resolve<IEventHandlerController>(),
LifetimeScope.Resolve<IInternalEventFactory>(),
LifetimeScope.Resolve<IUIEventFactory>(),
LifetimeScope.Resolve<IPlaybackEventFactory>(),
LifetimeScope.Resolve<ILuaEventFactory>(),
LifetimeScope.Resolve<IApplicationUpdateEventFactory>(),
LifetimeScope.Resolve<IFileMonitorEventFactory>(),
LifetimeScope.Resolve<IAudioEventFactory>(),
LifetimeScope.Resolve<IDiscordEventFactory>(),
LifetimeScope.Resolve<IIRacingEventFactory>(),
LifetimeScope.Resolve<ITwitchEventFactory>(),
luaGlues
return (IPlugin)LifetimeScope.Resolve(
PluginFactories[pluginName],
new NamedParameter("id", pluginId),
new NamedParameter("configuration", configuration),
new NamedParameter("eventBus", eventBus)
);
if (!ComponentPlugins.ContainsKey(pluginName))
throw new KeyNotFoundException($"Plugin name '{pluginName}' not found");
return ComponentPlugins[pluginName].Invoke(reg);
}

public void Dispose()
Expand Down
2 changes: 1 addition & 1 deletion Backend/PluginWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public PluginWorker(IPlugin plugin, IEventBusSubscription subscription, IInterna
EventFactory = eventFactory;
}

private void Plugin_OnStateChanged(object source, IPlugin plugin)
private void Plugin_OnStateChanged(object source, BasePlugin plugin)
{
EventBus.PublishEvent(EventFactory.CreateInternalPluginState(plugin.Id, plugin.Name, plugin.DisplayName, PluginStatusEnum.Registered));
}
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
- adds WinFormUI component - containing the Slipstream UI. You need to add `register_plugin({ plugin_name = "WinFormUIPlugin"})
` to you `init.lua` to get it.
- add `internal:shutdown()` lua function that quits the application
- Adds `InternalPlugin` (automatically loaded)
- Adds `UIPlugin` that handles generic UI functionality. Needs to be added to your init.lua!

## [0.5.0](https://github.com/dennis/slipstream/releases/tag/v0.5.0) (2021-03-25)
[Full Changelog](https://github.com/dennis/slipstream/compare/v0.4.1...v0.5.0)
Expand Down
26 changes: 0 additions & 26 deletions Components/AppilcationUpdate/ApplicationUpdate.cs

This file was deleted.

10 changes: 8 additions & 2 deletions Components/AppilcationUpdate/Plugins/ApplicationUpdatePlugin.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
using Serilog;
using Slipstream.Components.Internal.Events;
using Slipstream.Shared;
using Slipstream.Shared.Helpers.StrongParameters;
using Slipstream.Shared.Helpers.StrongParameters.Validators;
using Squirrel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Slipstream.Components.Internal.Events;

namespace Slipstream.Components.AppilcationUpdate.Plugins
{
public class ApplicationUpdatePlugin : BasePlugin
public class ApplicationUpdatePlugin : BasePlugin, IPlugin
{
private readonly EventHandler.ApplicationUpdateEventHandler applicationUpdate;
private readonly IApplicationUpdateEventFactory applicationUpdateEventFactory;
Expand Down Expand Up @@ -159,5 +160,10 @@ private async Task DoAppUpdates(UpdateManager updateManager)
var releaseInfo = await updateManager.UpdateApp();
Logger.Information($"Auto update, update completed for {releaseInfo.Version}");
}

public IEnumerable<ILuaGlue> CreateLuaGlues()
{
return new ILuaGlue[] { };
}
}
}
29 changes: 0 additions & 29 deletions Components/Audio/Audio.cs

This file was deleted.

8 changes: 7 additions & 1 deletion Components/Audio/Plugins/AudioPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Slipstream.Shared.Helpers.StrongParameters;
using Slipstream.Shared.Helpers.StrongParameters.Validators;
using System;
using System.Collections.Generic;
using System.IO;
using System.Speech.Synthesis;
using System.Threading;
Expand All @@ -13,7 +14,7 @@

namespace Slipstream.Components.Audio.Plugins
{
internal class AudioPlugin : BasePlugin
public class AudioPlugin : BasePlugin, IPlugin
{
public static DictionaryValidator ConfigurationValidator { get; }

Expand Down Expand Up @@ -129,5 +130,10 @@ private void Play(WaveStream stream, float volume)
Thread.Sleep(100);
}
}

public IEnumerable<ILuaGlue> CreateLuaGlues()
{
return new LuaGlue[] { new LuaGlue(EventBus, EventFactory) };
}
}
}
4 changes: 2 additions & 2 deletions Components/BasePlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Slipstream.Components
{
public class BasePlugin : IPlugin
public abstract class BasePlugin
{
public string Id { get; } = "INVALID-PLUGIN-ID";
private string name = "INVALID-PLUGIN-NAME";
Expand All @@ -24,7 +24,7 @@ public string DisplayName
set { displayName = value; OnStateChanged?.Invoke(this, this); }
}

public event EventHandler<IPlugin>? OnStateChanged;
public event EventHandler<BasePlugin>? OnStateChanged;

public bool Reconfigurable { get; }
public bool FullThreadControl { get; }
Expand Down
Loading

0 comments on commit 6f28a54

Please sign in to comment.