using System; using System.Collections.Generic; 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); } public delegate void EventManagerCallback(EventData data); public delegate void EventManagerMenuCallBack(object state, string eventId); 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); menu.Add(provitem); } 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); foreach (IEventProvider prov in providers) { if(prov.Bind(eventId)) return true; } return false; } 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); } } } public void EventCallBack (EventData data) { if (bindings.ContainsKey (data.id)) { foreach (IEventTarget target in bindings[data.id].Targets) { target.FireEvent(data); } } } } }