• U3D C# 实现AS3事件机制


      写了很多年的AS3,最近接触U3D感觉事件机制没AS3的爽。咬紧牙关一鼓作气 基于C# 的委托实现了一版。废话不多说上干货。

    EventDispatcher代码如下:

    using UnityEngine;
    using System.Collections;
    using System;
    using System.Collections.Generic;
    /**
     * EventDispatcher 类是可调度事件的所有类的基类
     * @author 回眸笑苍生
    **/
    public abstract class EventDispatcher : MonoBehaviour
    {
     //定义委托
     public delegate void EventDelegate(EventObject evt);
     
     protected Dictionary<String,List<EventDelegate>> captureListeners = null;

     protected Dictionary<String,List<EventDelegate>> bubbleListeners = null;

     protected EventDispatcher _parent;

     public void addEventListener(String types, EventDelegate listener, bool useCapture = false, int priority = 0, bool useWeakReference=false)
     {
      Dictionary<String,List<EventDelegate>> listeners = null;
     
      if (listener == null)
      {
       throw new ArgumentNullException("Parameter listener must be non-null.");
      }
      if (useCapture)
      {
       if (captureListeners == null) captureListeners = new Dictionary<string, List<EventDelegate>>();
       listeners = captureListeners;
      }
      else
      {
       if (bubbleListeners == null) bubbleListeners = new Dictionary<string, List<EventDelegate>>();
       listeners = bubbleListeners;
      }
      List<EventDelegate> vector = null;
      if (listeners.ContainsKey (types))
      {
       vector = listeners[types];
      }
      if (vector == null)
      {
       vector = new List<EventDelegate>();
       listeners.Add(types, vector);
      }
      if (vector.IndexOf(listener) < 0)
      {
       vector.Add(listener);
      }
     }

     public void removeEventListener(String types, EventDelegate listener, bool useCapture = false)
     {
      if (listener == null)
      {
       throw new ArgumentNullException("Parameter listener must be non-null.");
      }
      Dictionary<string, List<EventDelegate>> listeners = useCapture ? captureListeners : bubbleListeners;
      if (listeners != null)
      {
       List<EventDelegate> vector = listeners [types];
       if (vector != null)
       {
        int i = vector.IndexOf(listener);
        if (i >= 0)
        {
         int length = vector.Count;
         for(int j = i+1;j < length;j++,i++)
         {
          vector[i] = vector[j];
         }

         listeners.Remove(types);

         foreach (KeyValuePair<String, List<EventDelegate>> o in listeners)
         {
          if(o.Key == null)
          {
           if (listeners == captureListeners)
           {
            captureListeners = null;
           }
           else
           {
            bubbleListeners = null;
           }
          }
         }
        }
       }
      }

     }

     public bool hasEventListener(String types)
     {
      return (captureListeners != null && captureListeners.ContainsKey(types)) || (bubbleListeners != null && bubbleListeners.ContainsKey(types));
     }

     public bool willTrigger(String types)
     {
      for (EventDispatcher _object = this; _object != null; _object = _object._parent)
      {
       if ((_object.captureListeners != null && _object.captureListeners.ContainsKey(types)) ||( _object.bubbleListeners != null && _object.bubbleListeners.ContainsKey(types)))
        return true;
      }
      return false;
     }

     public bool dispatchEvent(EventObject evt)
     {
      if (evt == null)
      {
       throw new ArgumentNullException("Parameter EventObject must be non-null.");
      }
      EventObject event3D = evt;
      if (event3D != null)
      {
       event3D.setTarget = this;
      }
      List<EventDispatcher> branch = new List<EventDispatcher> ();
      int branchLength = 0;
      EventDispatcher _object;
      int i, j = 0;
      int length;
      List<EventDelegate> vector;
      List<EventDelegate> functions;
      for (_object = this; _object !=null; _object=_object._parent)
      {
       branch.Add(_object);
       branchLength++;
      }
      for (i = branchLength - 1; i > 0; i--)
      {
       _object = branch[i];
       if (event3D != null)
       {
        event3D.setCurrentTarget = _object;
        event3D.setEventPhase = EventPhase.CAPTURING_PHASE;
       }
       if (_object.captureListeners != null)
       {
        vector = _object.captureListeners[evt.types];
        if (vector != null)
        {
         length = vector.Count;
         functions = new List<EventDelegate>();
         for (j = 0; j < length; j++) functions[j] = vector[j];
         for (j = 0; j < length; j++) (functions[j] as EventDelegate)(evt);
        }
       }
      }
      if (event3D != null)
      {
       event3D.setEventPhase = EventPhase.AT_TARGET;
      }
      for (i = 0; i < branchLength; i++) {
       _object = branch[i];
       if (event3D != null) {
        event3D.setCurrentTarget = _object;
        if (i > 0) {
         event3D.setEventPhase = EventPhase.BUBBLING_PHASE;
        }
       }
       if (_object.bubbleListeners != null) {
        vector = _object.bubbleListeners[evt.types];
        if (vector != null) {
         length = vector.Count;
         functions =  new List<EventDelegate>();
         for (j = 0; j < length; j++) functions.Add(vector[j]);
         for (j = 0; j < length; j++) (functions[j] as EventDelegate)(evt);
        }
       }
       if (!event3D.bubbles) break;
      }
      return true;
     }

    }

    EventPhase代码如下:

    using UnityEngine;
    using System.Collections;
    /**
     * EventPhase 类可为 Event 类的 eventPhase 属性提供值。
     * @author 回眸笑苍生
    **/
    public class EventPhase
    {
     
     public const int CAPTURING_PHASE = 1;
     
     public const int AT_TARGET = 2;
     
     public const int BUBBLING_PHASE = 3;
    }

    EventObject代码如下:

    using UnityEngine;
    using System.Collections;
    using System;
    /**
     * EventObject 类作为创建 Event 对象的基类,当发生事件时,Event 对象将作为参数传递给事件侦听器。
     * @author 回眸笑苍生
    **/
    public class EventObject
    {
     public const String ACTIVATE = "activate";
     public const String ADDED = "added";
     public const String ADDED_TO_STAGE = "addedToStage";
     public const String CANCEL = "cancel";
     public const String CHANGE = "change";
     public const String CLEAR = "clear";
     public const String CLOSE = "close";
     public const String CLOSING = "closing";
     public const String COMPLETE = "complete";
     public const String CONNECT = "connect";
     public const String OPEN = "open";


     private EventDispatcher _target;
     private int _eventPhase;
     private EventDispatcher _currentTarget;
     private bool _bubbles;
     private bool _cancelable;
     private String _types;

     public EventObject(String types, bool bubbles=false, bool cancelable=false)
     {
      this._types = types;
      this._bubbles= bubbles;
      this._cancelable = cancelable;
     }

     public EventDispatcher target
     {
      get { return _target; }
     }

     internal EventDispatcher setTarget
     {
      set { _target = value; }
     }

     public EventDispatcher currentTarget
     {
      get { return _currentTarget; }
     }

     internal EventDispatcher setCurrentTarget
     {
      set { _currentTarget = value; }
     }

     public int eventPhase
     {
      get { return _eventPhase; }
     }

     internal int setEventPhase
     {
      set { _eventPhase = value; }
     }

     public bool bubbles
     {
      get { return _bubbles; }
     }

     public String types
     {
      get { return _types; }
     }

     public bool cancelable
     {
      get { return _cancelable; }
     }
    }

    在使用过程中 大家可以把 U3D中新建Class 默认继承的基类 换成 EventDispatcher 这样一来就拥有了和AS3一样的 事件机制了。

    有什么Bug 欢迎大家多多指教。

  • 相关阅读:
    windows下安装redis以及redis扩展,设置redis为windows自启服务
    Redis和Memcache的区别
    Git 简单入门使用
    ssh 连接 mac osx下 virtual box虚拟机中的 cent os 记录
    把可运行jar转换成Linux服务运行
    CentOS 7 配置FTP(vsftpd)
    团队总结
    第五周小组项目总结
    第四周小组项目总结
    第三周小组项目总结
  • 原文地址:https://www.cnblogs.com/ch06src/p/3877384.html
Copyright © 2020-2023  润新知