using System;
using System.Collections.Generic;
namespace FairyGUI
{
public delegate void EventCallback0();
public delegate void EventCallback1(EventContext context);
///
///
///
public class EventDispatcher : IEventDispatcher
{
Dictionary _dic;
public EventDispatcher()
{
}
///
///
///
///
///
public void AddEventListener(string strType, EventCallback1 callback)
{
GetBridge(strType).Add(callback);
}
///
///
///
///
///
public void AddEventListener(string strType, EventCallback0 callback)
{
GetBridge(strType).Add(callback);
}
///
///
///
///
///
public void RemoveEventListener(string strType, EventCallback1 callback)
{
if (_dic == null)
return;
EventBridge bridge = null;
if (_dic.TryGetValue(strType, out bridge))
bridge.Remove(callback);
}
///
///
///
///
///
public void RemoveEventListener(string strType, EventCallback0 callback)
{
if (_dic == null)
return;
EventBridge bridge = null;
if (_dic.TryGetValue(strType, out bridge))
bridge.Remove(callback);
}
///
///
///
///
///
public void AddCapture(string strType, EventCallback1 callback)
{
GetBridge(strType).AddCapture(callback);
}
///
///
///
///
///
public void RemoveCapture(string strType, EventCallback1 callback)
{
if (_dic == null)
return;
EventBridge bridge = null;
if (_dic.TryGetValue(strType, out bridge))
bridge.RemoveCapture(callback);
}
///
///
///
public void RemoveEventListeners()
{
RemoveEventListeners(null);
}
///
///
///
///
public void RemoveEventListeners(string strType)
{
if (_dic == null)
return;
if (strType != null)
{
EventBridge bridge;
if (_dic.TryGetValue(strType, out bridge))
bridge.Clear();
}
else
{
foreach (KeyValuePair kv in _dic)
kv.Value.Clear();
}
}
///
///
///
///
///
public bool hasEventListeners(string strType)
{
EventBridge bridge = TryGetEventBridge(strType);
if (bridge == null)
return false;
return !bridge.isEmpty;
}
///
///
///
///
///
public bool isDispatching(string strType)
{
EventBridge bridge = TryGetEventBridge(strType);
if (bridge == null)
return false;
return bridge._dispatching;
}
internal EventBridge TryGetEventBridge(string strType)
{
if (_dic == null)
return null;
EventBridge bridge = null;
_dic.TryGetValue(strType, out bridge);
return bridge;
}
internal EventBridge GetEventBridge(string strType)
{
if (_dic == null)
_dic = new Dictionary();
EventBridge bridge = null;
if (!_dic.TryGetValue(strType, out bridge))
{
bridge = new EventBridge(this);
_dic[strType] = bridge;
}
return bridge;
}
///
///
///
///
///
public bool DispatchEvent(string strType)
{
return DispatchEvent(strType, null);
}
///
///
///
///
///
///
public bool DispatchEvent(string strType, object data)
{
return InternalDispatchEvent(strType, null, data, null);
}
public bool DispatchEvent(string strType, object data, object initiator)
{
return InternalDispatchEvent(strType, null, data, initiator);
}
static InputEvent sCurrentInputEvent = new InputEvent();
internal bool InternalDispatchEvent(string strType, EventBridge bridge, object data, object initiator)
{
if (bridge == null)
bridge = TryGetEventBridge(strType);
EventBridge gBridge = null;
if ((this is DisplayObject) && ((DisplayObject)this).gOwner != null)
gBridge = ((DisplayObject)this).gOwner.TryGetEventBridge(strType);
bool b1 = bridge != null && !bridge.isEmpty;
bool b2 = gBridge != null && !gBridge.isEmpty;
if (b1 || b2)
{
EventContext context = EventContext.Get();
context.initiator = initiator != null ? initiator : this;
context.type = strType;
context.data = data;
if (data is InputEvent)
sCurrentInputEvent = (InputEvent)data;
context.inputEvent = sCurrentInputEvent;
if (b1)
{
bridge.CallCaptureInternal(context);
bridge.CallInternal(context);
}
if (b2)
{
gBridge.CallCaptureInternal(context);
gBridge.CallInternal(context);
}
EventContext.Return(context);
context.initiator = null;
context.sender = null;
context.data = null;
return context._defaultPrevented;
}
else
return false;
}
///
///
///
///
///
public bool DispatchEvent(EventContext context)
{
EventBridge bridge = TryGetEventBridge(context.type);
EventBridge gBridge = null;
if ((this is DisplayObject) && ((DisplayObject)this).gOwner != null)
gBridge = ((DisplayObject)this).gOwner.TryGetEventBridge(context.type);
EventDispatcher savedSender = context.sender;
if (bridge != null && !bridge.isEmpty)
{
bridge.CallCaptureInternal(context);
bridge.CallInternal(context);
}
if (gBridge != null && !gBridge.isEmpty)
{
gBridge.CallCaptureInternal(context);
gBridge.CallInternal(context);
}
context.sender = savedSender;
return context._defaultPrevented;
}
///
///
///
///
///
///
///
internal bool BubbleEvent(string strType, object data, List addChain)
{
EventContext context = EventContext.Get();
context.initiator = this;
context.type = strType;
context.data = data;
if (data is InputEvent)
sCurrentInputEvent = (InputEvent)data;
context.inputEvent = sCurrentInputEvent;
List bubbleChain = context.callChain;
bubbleChain.Clear();
GetChainBridges(strType, bubbleChain, true);
int length = bubbleChain.Count;
for (int i = length - 1; i >= 0; i--)
{
bubbleChain[i].CallCaptureInternal(context);
if (context._touchCapture)
{
context._touchCapture = false;
if (strType == "onTouchBegin")
Stage.inst.AddTouchMonitor(context.inputEvent.touchId, bubbleChain[i].owner);
}
}
if (!context._stopsPropagation)
{
for (int i = 0; i < length; ++i)
{
bubbleChain[i].CallInternal(context);
if (context._touchCapture)
{
context._touchCapture = false;
if (strType == "onTouchBegin")
Stage.inst.AddTouchMonitor(context.inputEvent.touchId, bubbleChain[i].owner);
}
if (context._stopsPropagation)
break;
}
if (addChain != null)
{
length = addChain.Count;
for (int i = 0; i < length; ++i)
{
EventBridge bridge = addChain[i];
if (bubbleChain.IndexOf(bridge) == -1)
{
bridge.CallCaptureInternal(context);
bridge.CallInternal(context);
}
}
}
}
EventContext.Return(context);
context.initiator = null;
context.sender = null;
context.data = null;
return context._defaultPrevented;
}
///
///
///
///
///
///
public bool BubbleEvent(string strType, object data)
{
return BubbleEvent(strType, data, null);
}
///
///
///
///
///
///
public bool BroadcastEvent(string strType, object data)
{
EventContext context = EventContext.Get();
context.initiator = this;
context.type = strType;
context.data = data;
if (data is InputEvent)
sCurrentInputEvent = (InputEvent)data;
context.inputEvent = sCurrentInputEvent;
List bubbleChain = context.callChain;
bubbleChain.Clear();
if (this is Container)
GetChildEventBridges(strType, (Container)this, bubbleChain);
else if (this is GComponent)
GetChildEventBridges(strType, (GComponent)this, bubbleChain);
int length = bubbleChain.Count;
for (int i = 0; i < length; ++i)
bubbleChain[i].CallInternal(context);
EventContext.Return(context);
context.initiator = null;
context.sender = null;
context.data = null;
return context._defaultPrevented;
}
EventBridge GetBridge(string strType)
{
if (strType == null)
throw new Exception("event type cant be null");
if (_dic == null)
_dic = new Dictionary();
EventBridge bridge = null;
if (!_dic.TryGetValue(strType, out bridge))
{
bridge = new EventBridge(this);
_dic[strType] = bridge;
}
return bridge;
}
static void GetChildEventBridges(string strType, Container container, List bridges)
{
EventBridge bridge = container.TryGetEventBridge(strType);
if (bridge != null)
bridges.Add(bridge);
if (container.gOwner != null)
{
bridge = container.gOwner.TryGetEventBridge(strType);
if (bridge != null && !bridge.isEmpty)
bridges.Add(bridge);
}
int count = container.numChildren;
for (int i = 0; i < count; ++i)
{
DisplayObject obj = container.GetChildAt(i);
if (obj is Container)
GetChildEventBridges(strType, (Container)obj, bridges);
else
{
bridge = obj.TryGetEventBridge(strType);
if (bridge != null && !bridge.isEmpty)
bridges.Add(bridge);
if (obj.gOwner != null)
{
bridge = obj.gOwner.TryGetEventBridge(strType);
if (bridge != null && !bridge.isEmpty)
bridges.Add(bridge);
}
}
}
}
static void GetChildEventBridges(string strType, GComponent container, List bridges)
{
EventBridge bridge = container.TryGetEventBridge(strType);
if (bridge != null)
bridges.Add(bridge);
int count = container.numChildren;
for (int i = 0; i < count; ++i)
{
GObject obj = container.GetChildAt(i);
if (obj is GComponent)
GetChildEventBridges(strType, (GComponent)obj, bridges);
else
{
bridge = obj.TryGetEventBridge(strType);
if (bridge != null)
bridges.Add(bridge);
}
}
}
internal void GetChainBridges(string strType, List chain, bool bubble)
{
EventBridge bridge = TryGetEventBridge(strType);
if (bridge != null && !bridge.isEmpty)
chain.Add(bridge);
if ((this is DisplayObject) && ((DisplayObject)this).gOwner != null)
{
bridge = ((DisplayObject)this).gOwner.TryGetEventBridge(strType);
if (bridge != null && !bridge.isEmpty)
chain.Add(bridge);
}
if (!bubble)
return;
if (this is DisplayObject)
{
DisplayObject element = (DisplayObject)this;
while ((element = element.parent) != null)
{
bridge = element.TryGetEventBridge(strType);
if (bridge != null && !bridge.isEmpty)
chain.Add(bridge);
if (element.gOwner != null)
{
bridge = element.gOwner.TryGetEventBridge(strType);
if (bridge != null && !bridge.isEmpty)
chain.Add(bridge);
}
}
}
else if (this is GObject)
{
GObject element = (GObject)this;
while ((element = element.parent) != null)
{
bridge = element.TryGetEventBridge(strType);
if (bridge != null && !bridge.isEmpty)
chain.Add(bridge);
}
}
}
}
}