U3D C# 實現AS3事件機制

來源:互聯網
上載者:User

標籤:使用   os   strong   io   for   cti   代碼   ar   

  寫了很多年的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 歡迎大家多多指教。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.