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 } }