StephaneLenclud@234: // StephaneLenclud@234: using System; StephaneLenclud@234: using System.Collections.Generic; StephaneLenclud@234: using System.ComponentModel; StephaneLenclud@234: using System.Linq; StephaneLenclud@234: using System.Reflection; StephaneLenclud@234: using System.Runtime.Serialization; StephaneLenclud@234: using SharpLib.Utils; StephaneLenclud@234: StephaneLenclud@235: StephaneLenclud@234: namespace SharpLib.Ear StephaneLenclud@234: { StephaneLenclud@234: /// StephaneLenclud@234: /// Event Action Router (Ear) is a generic and extensible framework allowing users to execute actions in response to events. StephaneLenclud@234: /// Users can implement their own events and actions. StephaneLenclud@234: /// StephaneLenclud@234: [DataContract] Stephane@243: public class Manager: Object StephaneLenclud@234: { StephaneLenclud@234: /// StephaneLenclud@234: /// Our events instances. StephaneLenclud@234: /// StephaneLenclud@234: [DataMember] StephaneLenclud@234: public List Events; StephaneLenclud@234: StephaneLenclud@234: StephaneLenclud@234: /// StephaneLenclud@234: /// Executes after internalization took place. StephaneLenclud@234: /// Stephane@243: protected override void DoConstruct() StephaneLenclud@234: { Stephane@243: base.DoConstruct(); Stephane@243: StephaneLenclud@234: if (Events == null) StephaneLenclud@234: { StephaneLenclud@234: Events = new List(); StephaneLenclud@234: } Stephane@243: Stephane@243: // TODO: Object properties should be constructed too Stephane@243: foreach (Event e in Events) Stephane@243: { Stephane@243: e.Construct(); Stephane@243: } StephaneLenclud@234: StephaneLenclud@234: } StephaneLenclud@234: StephaneLenclud@234: /// StephaneLenclud@234: /// Trigger the given event. StephaneLenclud@234: /// StephaneLenclud@234: /// StephaneLenclud@260: public async void TriggerEvents() where T: class StephaneLenclud@234: { StephaneLenclud@234: //Only trigger enabled events matching the desired type StephaneLenclud@234: foreach (Event e in Events.Where(e => e.GetType() == typeof(T) && e.Enabled)) StephaneLenclud@234: { StephaneLenclud@260: await e.Trigger(); StephaneLenclud@234: } StephaneLenclud@234: } StephaneLenclud@234: StephaneLenclud@237: /// StephaneLenclud@237: /// Trigger the given event. StephaneLenclud@237: /// StephaneLenclud@237: /// StephaneLenclud@260: public async void TriggerEvents(T aEvent) where T : class StephaneLenclud@237: { StephaneLenclud@237: //Only trigger events matching the desired type StephaneLenclud@237: foreach (Event e in Events.Where(e => e.Equals(aEvent) && e.Enabled)) StephaneLenclud@237: { StephaneLenclud@260: await e.Trigger(); StephaneLenclud@237: } StephaneLenclud@237: } StephaneLenclud@237: StephaneLenclud@260: /// StephaneLenclud@260: /// StephaneLenclud@260: /// StephaneLenclud@260: /// StephaneLenclud@260: /// StephaneLenclud@260: public async void TriggerEventsByName(string aName) StephaneLenclud@260: { StephaneLenclud@260: if (string.IsNullOrEmpty(aName)) StephaneLenclud@260: { StephaneLenclud@262: //Just don't do that, that would be silly StephaneLenclud@260: return; StephaneLenclud@260: } StephaneLenclud@262: // Only trigger events matching the desired type StephaneLenclud@262: // Doing some safety checks as well to prevent crashing if name was left null for some reason StephaneLenclud@262: // This was the case when loading existing settings after event Name was introduced Stephane@267: foreach (Event e in Events.Where(e => !string.IsNullOrEmpty(e.Name) && e.Enabled && aName.Equals(e.Name))) StephaneLenclud@260: { StephaneLenclud@260: await e.Trigger(); StephaneLenclud@260: } StephaneLenclud@260: } StephaneLenclud@260: StephaneLenclud@260: StephaneLenclud@260: StephaneLenclud@234: StephaneLenclud@234: /// StephaneLenclud@234: /// Remove the specified action from the event it belongs too. StephaneLenclud@234: /// StephaneLenclud@234: /// StephaneLenclud@234: public void RemoveAction(Action aAction) StephaneLenclud@234: { StephaneLenclud@234: foreach (Event e in Events) StephaneLenclud@234: { StephaneLenclud@265: if (RemoveObject(e,aAction)) StephaneLenclud@234: { StephaneLenclud@234: //We removed our action, we are done here. StephaneLenclud@234: return; StephaneLenclud@234: } StephaneLenclud@234: } StephaneLenclud@234: } StephaneLenclud@265: StephaneLenclud@265: /// StephaneLenclud@265: /// Remove the specified action from the event it belongs too. StephaneLenclud@265: /// StephaneLenclud@265: /// StephaneLenclud@265: private static bool RemoveObject(Object aCurrent, Object aToRemove) StephaneLenclud@265: { StephaneLenclud@265: //Exit condition StephaneLenclud@265: if (aCurrent.Objects.Remove(aToRemove)) StephaneLenclud@265: { StephaneLenclud@265: //We removed our action, we are done here. StephaneLenclud@265: return true; StephaneLenclud@265: } StephaneLenclud@265: StephaneLenclud@265: foreach (Object o in aCurrent.Objects) StephaneLenclud@265: { StephaneLenclud@265: bool done = RemoveObject(o, aToRemove); StephaneLenclud@265: if (done) StephaneLenclud@265: { StephaneLenclud@265: return true; StephaneLenclud@265: } StephaneLenclud@265: } StephaneLenclud@265: StephaneLenclud@265: return false; StephaneLenclud@265: } StephaneLenclud@265: StephaneLenclud@234: } StephaneLenclud@234: }