【UGUI源码解析】2、事件委托

一、功能说明

1、包含BaseEventData,有不同类型的事件接口类【都在EventInterfaces】和对应的事件点击数据结构,
 2、对外调用的统一执行接口,获取当前收到事件的对象,判断当前是否对象是否可以收到执行事件

二、重要代码说明

1、定义代理函数,使用相同的事件数据类型进行数据封装

 //事件代理函数,以及对应的数据,
        //代理函数会根据指定的T1类型去查找对应的执行函数,
        //由于参数类型不同,所以函数名可以都取同一个
        public delegate void EventFunction<T1> (T1 handler, BaseEventData eventData);

        public static T ValidateEventData<T> (BaseEventData data) where T : class {
            if ((data as T) == null)
                throw new ArgumentException (String.Format ("Invalid type: {0} passed to event expecting {1}", data.GetType (), typeof (T)));
            return data as T;
        }

2、暴露外部调用的方法--ExecuteEvents.Execute

比如在EventSystem中SelectedGameObject()函数中,对旧对象进行触发释放类型事件

ExecuteEvents.Execute (m_CurrentSelected, pointer, ExecuteEvents.deselectHandler);

对新对象触发选中事件

ExecuteEvents.Execute (m_CurrentSelected, pointer, ExecuteEvents.selectHandler);

在excute中,会先获取传入的目标对象,通过遍历目标对象所继承IEventSystemHandler类型的脚本,执行相对应的代理函数

  ///执行事件,暴露给外部调用的统一执行函数,根据不同类型的事件类型执行对应的代理函数
        /// where 表示限制类型,是一种约束
        /// 使用约束的原因
        /*https://www.cnblogs.com/colorzore/p/13953722.html
        约束指定类型参数的功能和预期。 声明这些约束意味着你可以使用约束类型的操作和方法调用。 
        如果泛型类或方法对泛型成员使用除简单赋值之外的任何操作或调用 System.Object 不支持的任何方法, 则必须对类型参数应用约束。 
        例如, 基类约束告诉编译器, 仅此类型的对象或派生自此类型的对象可用作类型参数。
         编译器有了此保证后, 就能够允许在泛型类中调用该类型的方法。 以下代码示例演示可通过应用基类约束添加到( 泛型介绍中的) GenericList<T> 类的功能。
         */
  public static bool Execute<T> (GameObject target, BaseEventData eventData, EventFunction<T> functor) where T : IEventSystemHandler {
            //需要new的地方可以设置一个队列进行空,可以减少大量的new引起的性能问题
            var internalHandlers = s_HandlerListPool.Get (); 
            GetEventList<T> (target, internalHandlers);
            // if (internalHandlers.Count > 0)
            //     Debug.Log ("Executinng " + typeof (T) + " on " + target);

            for (var i = 0; i < internalHandlers.Count; i++) {
                T arg;
                try {
                    arg = (T) internalHandlers[i];
                } catch (Exception e) {
                    var temp = internalHandlers[i];
                    Debug.LogException (new Exception (string.Format ("Type {0} expected {1} received.", typeof (T).Name, temp.GetType ().Name), e));
                    continue;
                }

                try {
                    functor (arg, eventData);
                } catch (Exception e) {
                    Debug.LogException (e);
                }
            }

            var handlerCount = internalHandlers.Count;
            s_HandlerListPool.Release (internalHandlers);
            return handlerCount > 0;
        }

 

上一篇:场景优化(一),UGUI的优化


下一篇:Unity 之 UGUI控件详解学习目录