/*
* Copyright (c) 2022 Vaughn Nugent
*
* Library: VNLib
* Package: VNLib.Plugins.Runtime
* File: LoaderExtensions.cs
*
* LoaderExtensions.cs is part of VNLib.Plugins.Runtime which is part of the larger
* VNLib collection of libraries and utilities.
*
* VNLib.Plugins.Runtime is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 2 of the License,
* or (at your option) any later version.
*
* VNLib.Plugins.Runtime is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VNLib.Plugins.Runtime. If not, see http://www.gnu.org/licenses/.
*/
using System;
using System.Collections.Generic;
using System.Linq;
namespace VNLib.Plugins.Runtime
{
public static class LoaderExtensions
{
///
/// Searches all plugins within the current loader for a
/// single plugin that derrives the specified type
///
/// The type the plugin must derrive from
///
/// The instance of the plugin that derrives from the specified type
public static LivePlugin? GetExposedPlugin(this RuntimePluginLoader loader)
{
return loader.LivePlugins
.Where(static pl => typeof(T).IsAssignableFrom(pl.Plugin!.GetType()))
.SingleOrDefault();
}
///
/// Searches all plugins within the current loader for a
/// single plugin that derrives the specified type
///
/// The type the plugin must derrive from
///
/// The instance of your custom type casted, or null if not found or could not be casted
public static T? GetExposedTypeFromPlugin(this RuntimePluginLoader loader) where T: class
{
LivePlugin? plugin = loader.LivePlugins
.Where(static pl => typeof(T).IsAssignableFrom(pl.Plugin!.GetType()))
.SingleOrDefault();
return plugin?.Plugin as T;
}
///
/// Registers a listener delegate method to invoke when the
/// current is reloaded, and passes
/// the new instance of the specified type
///
/// The single plugin type to register a listener for
///
/// The delegate method to invoke when the loader has reloaded plugins
///
public static bool RegisterListenerForSingle(this RuntimePluginLoader loader, Action reloaded) where T: class
{
_ = reloaded ?? throw new ArgumentNullException(nameof(reloaded));
//try to get the casted type from the loader
T? current = loader.GetExposedTypeFromPlugin();
if (current == null)
{
return false;
}
else
{
loader.Reloaded += delegate (object? sender, EventArgs args)
{
RuntimePluginLoader wpl = (sender as RuntimePluginLoader)!;
//Get the new loaded type
T newT = (wpl.GetExposedPlugin()!.Plugin as T)!;
//Invoke reloaded action
reloaded(current, newT);
//update the new current instance
current = newT;
};
return true;
}
}
///
/// Gets all endpoints exposed by all exported plugin instances
/// within the current loader
///
///
/// An enumeration of all endpoints
public static IEnumerable GetEndpoints(this RuntimePluginLoader loader) => loader.LivePlugins.SelectMany(static pl => pl.Plugin!.GetEndpoints());
///
/// Determines if any loaded plugin types exposes an instance of the
/// specified type
///
///
///
/// True if any plugin instance exposes a the specified type, false otherwise
public static bool ExposesType(this RuntimePluginLoader loader) where T : class
{
return loader.LivePlugins.Any(static pl => typeof(T).IsAssignableFrom(pl.Plugin?.GetType()));
}
}
}