using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Windows.Forms;
namespace Trigger.Tasks
{
///
/// This takes care of all available s and automatically loads them on startup
///
public class Manager
{
#region Properties
/// Our
private Main Main;
/// A List of available s
public List TaskPluginsAvailable;
/// A List of actually loaded (=active) s
public List TaskPluginsLoaded = new List();
/// A List with the instances of the s
private List TaskPluginInstances = new List();
/// A flag that indicates whether the loading process should be aborted
private bool abort = false;
#endregion
#region Constructors
///
///
public Manager(Main Main)
{
this.Main = Main;
List types = this.getAvailableTasks();
this.TaskPluginsAvailable = types;
this.Refresh();
}
#endregion
#region Methods
///
/// Returns the current status of this
/// This includes the lists with available and with loaded s
///
///
public TreeNode GetStatus(TreeView tv)
{
TreeNode tnMain = new TreeNode("Task Manager");
TreeNode tnAvailable = tnMain.Nodes.Add("Available Tasks (" + this.TaskPluginsAvailable.Count + ")");
this.TaskPluginsAvailable.ForEach(new Action((item) => tnAvailable.Nodes.Add(new TreeNode(item.Name))));
TreeNode tnLoaded = tnMain.Nodes.Add("Loaded Tasks (" + this.TaskPluginInstances.Count + ")");
this.TaskPluginInstances.ForEach(new Action((tp) => tnLoaded.Nodes.Add(tp.GetStatus(tv))));
return tnMain;
}
///
/// Gets a list of all available s using Reflection
///
///
private List getAvailableTasks()
{
List types = new List(System.Reflection.Assembly.GetExecutingAssembly().GetTypes());
types = types.FindAll(new Predicate(item => { return item.BaseType == typeof(TaskPlugin) && item.Namespace.StartsWith("Trigger.Tasks"); }));
return types;
}
///
/// Loads all s that are not found or enabled in settings
///
private void Refresh()
{
ObservableDictionary plugins = TaskOptions.GetPluginsSetting();
List types = new List(this.TaskPluginsAvailable);
types = types.FindAll(new Predicate(item => { return !plugins.ContainsKey(item.Name) || plugins[item.Name]; }));
foreach (Type type in types)
{
if (abort)
break;
loadTask(type);
};
abort = false;
}
///
/// Loads all s that are enabled in and not yet loaded and
/// unloads all s that are disabled in and but still loaded
/// This method is used by to notify us about changes
/// The list of plugins and whether they shall be enabled
///
public void Refresh(ObservableDictionary plugins)
{
foreach (KeyValuePair plugin in plugins)
{
if (abort)
break;
Type type = this.TaskPluginsLoaded.Find(new Predicate(item => { return item.Name == plugin.Key; }));
if (plugin.Value && type == null) // task is enabled and not loaded
this.loadTask(plugin.Key);
if (!plugin.Value && type != null)
this.unloadTask(type);
}
abort = false;
}
///
/// Creates an instance of the specified
///
///
private void loadTask(string type)
{
this.loadTask(this.TaskPluginsAvailable.Find(new Predicate(item => { return item.Name == type; })));
}
///
/// Creates an instance of the specified
///
///
private void loadTask(Type type)
{
try
{
#if DEBUG
System.Diagnostics.Stopwatch swInitEvent = new System.Diagnostics.Stopwatch();
swInitEvent.Start();
#endif
TaskPlugin task = (TaskPlugin)Activator.CreateInstance(type);
#if DEBUG
if (new List(type.GetMethods()).Find(new Predicate(m => { return m.Name == "Init" && m.GetParameters().Length == 2; })) != null)
task.Init(this.Main, swInitEvent);
else
task.Init(this.Main);
#else
if (task.Init(this.Main))
#endif
{
this.TaskPluginInstances.Add(task);
this.TaskPluginsLoaded.Add(type);
#if DEBUG
swInitEvent.Stop();
this.Main.Log.LogLine("Loaded Task plugin \"" + type.Name + "\" in " + swInitEvent.ElapsedMilliseconds + "ms", Log.Type.Other);
#else
this.Main.Log.LogLine("Loaded Task plugin \"" + type.Name + "\"", Log.Type.Other);
#endif
}
}
catch (Exception e)
{
MessageBox.Show(e.Message + "\n\n" + e.StackTrace, "Error when loading Task \"" + type.Name + "\"!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
///
/// Destructs the instance of the specified
///
///
private void unloadTask(Type type)
{
try
{
TaskPlugin task = this.TaskPluginInstances.Find(new Predicate(item => { return item.GetType() == type; }));
task.Dispose();
this.TaskPluginInstances.Remove(task);
this.TaskPluginsLoaded.Remove(type);
this.Main.Log.LogLine("Unloaded Task plugin \"" + type.Name + "\"", Log.Type.Other);
}
catch (Exception e)
{
MessageBox.Show(e.Message + "\n\n" + e.StackTrace, "Error when unloading Task \"" + type.Name + "\"!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
internal void Abort()
{
this.abort = true;
}
#endregion
}
}