| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515 | using System;using System.Collections.Generic;namespace FairyGUI{    public delegate void EventCallback0();    public delegate void EventCallback1(EventContext context);    /// <summary>    ///     /// </summary>    public class EventDispatcher : IEventDispatcher    {        Dictionary<string, EventBridge> _dic;        public EventDispatcher()        {        }        /// <summary>        ///         /// </summary>        /// <param name="strType"></param>        /// <param name="callback"></param>        public void AddEventListener(string strType, EventCallback1 callback)        {            GetBridge(strType).Add(callback);        }        /// <summary>        ///         /// </summary>        /// <param name="strType"></param>        /// <param name="callback"></param>        public void AddEventListener(string strType, EventCallback0 callback)        {            GetBridge(strType).Add(callback);        }        /// <summary>        ///         /// </summary>        /// <param name="strType"></param>        /// <param name="callback"></param>        public void RemoveEventListener(string strType, EventCallback1 callback)        {            if (_dic == null)                return;            EventBridge bridge = null;            if (_dic.TryGetValue(strType, out bridge))                bridge.Remove(callback);        }        /// <summary>        ///         /// </summary>        /// <param name="strType"></param>        /// <param name="callback"></param>        public void RemoveEventListener(string strType, EventCallback0 callback)        {            if (_dic == null)                return;            EventBridge bridge = null;            if (_dic.TryGetValue(strType, out bridge))                bridge.Remove(callback);        }        /// <summary>        ///         /// </summary>        /// <param name="strType"></param>        /// <param name="callback"></param>        public void AddCapture(string strType, EventCallback1 callback)        {            GetBridge(strType).AddCapture(callback);        }        /// <summary>        ///         /// </summary>        /// <param name="strType"></param>        /// <param name="callback"></param>        public void RemoveCapture(string strType, EventCallback1 callback)        {            if (_dic == null)                return;            EventBridge bridge = null;            if (_dic.TryGetValue(strType, out bridge))                bridge.RemoveCapture(callback);        }        /// <summary>        ///         /// </summary>        public void RemoveEventListeners()        {            RemoveEventListeners(null);        }        /// <summary>        ///         /// </summary>        /// <param name="strType"></param>        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<string, EventBridge> kv in _dic)                    kv.Value.Clear();            }        }        /// <summary>        ///         /// </summary>        /// <param name="strType"></param>        /// <returns></returns>        public bool hasEventListeners(string strType)        {            EventBridge bridge = TryGetEventBridge(strType);            if (bridge == null)                return false;            return !bridge.isEmpty;        }        /// <summary>        ///         /// </summary>        /// <param name="strType"></param>        /// <returns></returns>        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<string, EventBridge>();            EventBridge bridge = null;            if (!_dic.TryGetValue(strType, out bridge))            {                bridge = new EventBridge(this);                _dic[strType] = bridge;            }            return bridge;        }        /// <summary>        ///         /// </summary>        /// <param name="strType"></param>        /// <returns></returns>        public bool DispatchEvent(string strType)        {            return DispatchEvent(strType, null);        }        /// <summary>        ///         /// </summary>        /// <param name="strType"></param>        /// <param name="data"></param>        /// <returns></returns>        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;        }        /// <summary>        ///         /// </summary>        /// <param name="context"></param>        /// <returns></returns>        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;        }        /// <summary>        ///         /// </summary>        /// <param name="strType"></param>        /// <param name="data"></param>        /// <param name="addChain"></param>        /// <returns></returns>        internal bool BubbleEvent(string strType, object data, List<EventBridge> 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<EventBridge> 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;        }        /// <summary>        ///         /// </summary>        /// <param name="strType"></param>        /// <param name="data"></param>        /// <returns></returns>        public bool BubbleEvent(string strType, object data)        {            return BubbleEvent(strType, data, null);        }        /// <summary>        ///         /// </summary>        /// <param name="strType"></param>        /// <param name="data"></param>        /// <returns></returns>        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<EventBridge> 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<string, EventBridge>();            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<EventBridge> 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<EventBridge> 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<EventBridge> 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);                }            }        }    }}
 |