using System; using System.Collections.Generic; using System.Linq; namespace DMX2 { public struct EventData { public string id; public byte value; } public interface IEventProvider { string MenuName{ get; } //ICollection GetEventList(); bool Bind (string eventId); void Unbind (string eventId); Gtk.Menu GetProviderSubMenu( EventManager.EventMenuData state, Gtk.ButtonPressEventHandler handler ); void ProcessEvents(EventManagerCallback callback); } public interface IEventTarget { bool FireEvent(EventData data); void Bind(string id); void Unbind(string id); IEnumerable IDs { get; } } public delegate void EventManagerCallback(EventData data); public delegate void EventManagerMenuCallBack(object state, string eventId); public class actionEventTarget : IEventTarget { public delegate bool EventAction (EventData data); EventAction action; List eventIds = new List(); public actionEventTarget(EventAction _action) { action=_action; } #region IEventTarget implementation bool IEventTarget.FireEvent (EventData data) { return action(data); } void IEventTarget.Bind (string id) { if(!eventIds.Contains(id)) eventIds.Add(id); } void IEventTarget.Unbind (string id) { eventIds.Remove(id); } IEnumerable IEventTarget.IDs { get { return eventIds; } } #endregion } public class EventManager { static public object StateKey = new object(); static public object EventIdKey = new object(); class eventBinding { List targets=new List(); public void AddTarget(IEventTarget target) { if(!targets.Contains(target)) targets.Add(target); } public void RemoveTarget(IEventTarget target) { targets.Remove(target); } public ICollection Targets { get { return targets; } } } Dictionary bindings = new Dictionary(); List providers = new List(); public EventManager () { } public void RegisterProvider (IEventProvider prov) { providers.Add (prov); } public class EventMenuData { public EventManagerMenuCallBack CallBack; public object state; } public Gtk.Menu GetMenu (object state, EventManagerMenuCallBack callback) { Gtk.Menu menu = new Gtk.Menu (); EventMenuData evd = new EventMenuData(); evd.CallBack = callback; evd.state = state; Gtk.ButtonPressEventHandler handler = new Gtk.ButtonPressEventHandler (HandleButtonPressEvent); foreach (IEventProvider prov in providers) { Gtk.MenuItem provitem = new Gtk.MenuItem(prov.MenuName); provitem.Submenu = prov.GetProviderSubMenu(evd, handler); if(provitem.Submenu!=null) menu.Add(provitem); } Gtk.MenuItem itemNone = new Gtk.MenuItem("Aucun"); itemNone.Data[StateKey] = evd; itemNone.Data[EventIdKey] = ""; itemNone.ButtonPressEvent += handler; menu.Add(itemNone); return menu; } void HandleButtonPressEvent (object o, Gtk.ButtonPressEventArgs args) { Gtk.MenuItem item = o as Gtk.MenuItem; EventMenuData evd = item.Data[EventManager.StateKey] as EventMenuData; string id = item.Data[EventManager.EventIdKey] as string; evd.CallBack(evd.state,id); } public void ProcessEvents () { foreach (IEventProvider prov in providers) { prov.ProcessEvents(new EventManagerCallback(EventCallBack)); } } public void UnregisterProvider (IEventProvider prov) { providers.Remove(prov); } public bool Bind (string eventId, IEventTarget target) { if(!bindings.ContainsKey(eventId)) bindings.Add (eventId,new eventBinding()); bindings[eventId].AddTarget(target); target.Bind(eventId); foreach (IEventProvider prov in providers) { if(prov.Bind(eventId)) return true; } return false; } public void Unbind (IEventTarget target) { var q = from bind in bindings where bind.Value.Targets.Contains(target) select bind.Key; foreach(string id in q.ToArray()) Unbind(id,target); } public void Unbind (string eventId, IEventTarget target) { if (!bindings.ContainsKey (eventId)) return; bindings [eventId].RemoveTarget (target); if (bindings [eventId].Targets.Count == 0) { bindings.Remove(eventId); foreach (IEventProvider prov in providers) { prov.Unbind(eventId); } } target.Unbind(eventId); } public void EventCallBack (EventData data) { Console.WriteLine("Event {0} => {1}",data.id,data.value); if (bindings.ContainsKey (data.id)) { foreach (IEventTarget target in bindings[data.id].Targets) { target.FireEvent(data); } } } public static bool SaveBindings (System.Xml.XmlElement xmlParent, IEventTarget target) { bool ret=false; System.Xml.XmlElement xmlB; foreach (string id in target.IDs) { ret=true; xmlParent.AppendChild(xmlB = xmlParent.OwnerDocument.CreateElement("EventBinding")); xmlB.SetAttribute("id",id); } return ret; } public static string[] LoadBindings (System.Xml.XmlElement xmlParent) { var all=xmlParent.GetElementsByTagName("EventBinding"); string[] ret = new string[all.Count]; int index=0; foreach (var xb in all) { ret[index++] = (xb as System.Xml.XmlElement).GetAttribute("id"); } return ret; } } }