loupiottes/DMX-2.0/EventManager.cs

180 lines
4.2 KiB
C#

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<string> 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 actionEventTarget : IEventTarget {
public delegate bool EventAction (EventData data);
EventAction action;
public actionEventTarget(EventAction _action)
{
action=_action;
}
#region IEventTarget implementation
bool IEventTarget.FireEvent (EventData data)
{
return action(data);
}
#endregion
}
public class EventManager
{
static public object StateKey = new object();
static public object EventIdKey = new object();
class eventBinding
{
List<IEventTarget> targets=new List<IEventTarget>();
public void AddTarget(IEventTarget target)
{
if(!targets.Contains(target))
targets.Add(target);
}
public void RemoveTarget(IEventTarget target)
{
targets.Remove(target);
}
public ICollection<IEventTarget> Targets {
get {
return targets;
}
}
}
Dictionary<string,eventBinding> bindings = new Dictionary<string,eventBinding>();
List<IEventProvider> providers = new List<IEventProvider>();
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);
}
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);
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);
}
}
}
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);
}
}
}
}
}