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

U3D C# 实现AS3事件机制的更多相关文章

  1. AS3事件机制概述

    事件机制是AS3的核心功能之一,没有充分掌握事件机制的方方面面,就不能算是精通AS3语言. 1. AS3事件机制的主要成员 IEventDispatcher:事件派发对象接口,定义了添加.派发.移除. ...

  2. [转]as3事件流机制彻底理解

    题记: 看过网上一些as3事件流的教程,觉得大多都讲得不甚清楚,让人不能直观的理解事件流.而这篇教程以将事件流过程比喻成捕鱼过程,形象简单. 在此基础上对于as3事件流总算有了全面的理解.事件流机制说 ...

  3. (转载)AS3.0实例学习 熟悉新的事件机制和addChild的运用

    (转载)http://www.jb51.net/article/13139.htm 首先声明:本人大菜鸟一个,刚接触AS3不久,许多理念还没来得及灌输,这些case都是从网上down的,但因为解说是英 ...

  4. Aa3.0 事件机制

    说明:本文由多处网络文章整理而成,在此未一一注明原文链接,敬请谅解! AS3:事件流机制  事件流 只要发生事件,Flash Player就会调度该事件对象. 如果事件目标不在显示列表中,则Flash ...

  5. 【移动端兼容问题研究】javascript事件机制详解(涉及移动兼容)

    前言 这篇博客有点长,如果你是高手请您读一读,能对其中的一些误点提出来,以免我误人子弟,并且帮助我提高 如果你是javascript菜鸟,建议您好好读一读,真的理解下来会有不一样的收获 在下才疏学浅, ...

  6. tkinter事件机制

    一.tkinter.Event tkinter的事件机制跟js是一样的,也是只有一个Event类,这个类包罗万象,集成了键盘事件,鼠标事件,包含各种参数. 不像java swing那种强类型事件,sw ...

  7. [解惑]JavaScript事件机制

    群里童鞋问到关于事件传播的一个问题:“事件捕获的时候,阻止冒泡,事件到达目标之后,还会冒泡吗?”. 初学 JS 的童鞋经常会有诸多疑问,我在很多 QQ 群也混了好几年了,耳濡目染也也收获了不少,以后会 ...

  8. Atitit  数据库的事件机制--触发器与定时任务attilax总结

    Atitit  数据库的事件机制--触发器与定时任务attilax总结 1.1. 事件机制的图谱1 2. 触发器的类型2 3. 实现原理 After触发器 Vs Instead Of触发器2 3.1. ...

  9. 深入浅出iOS事件机制

    原文地址: http://zhoon.github.io/ios/2015/04/12/ios-event.html 本文章将讲解有关iOS事件的传递机制,如有错误或者不同的见解,欢迎留言指出. iO ...

随机推荐

  1. Windows下的 mysql 5.5主从同步配置

    环境说明:   Master:127.0.0.1 3306 Slave:127.0.0.1 3307     MySQL 的 Master 配置:   配置my.ini:   [mysqld]   # ...

  2. ubuntu14.04 开启root登陆

    想要在登录界面使用root身份登录,可编辑/usr/share/lightdm/lightdm.conf.d/50-ubuntu.conf文件, sudo gedit /usr/share/light ...

  3. [Neural Networks] Dropout阅读笔记

    多伦多大学Hinton组 http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf 一.目的 降低overfitting的风险 二.原理 ...

  4. js判断用户进入设备代码

    var system ={ win : false, mac : false, xll : false }; //检测平台 var p = navigator.platform; system.win ...

  5. ExecuteReader

    最近在做winform的编程,想到一真没有使用过ExecuteReader.可能以前以后它的用户不大,或者 不大好用,故没有用过.今天在这里将学习记录写下来,供读者参考: 1.MSDN上说:Sends ...

  6. hadoop namenode多次格式化后,导致datanode启动不了

    jps hadoop namenode -format dfs directory : /home/hadoop/dfs --data --current/VERSION #Wed Jul :: CS ...

  7. Hadoop, Python, and NoSQL lead the pack for big data jobs

    Hadoop, Python, and NoSQL lead the pack for big data jobs   Rise in cloud-based analytics could incr ...

  8. 简单学C——第五天

    结构体 首先明确,结构体是一种构造的数据类型,是一种由多个数据类型如 int,char,double,数组或者结构体......组成的类型,现在告诉大家如何定义一个结构体.在定义int整型变量时,大家 ...

  9. Spire.XLS

    又一款Excel处理神器Spire.XLS,你值得拥有(二)   前言:上篇 C#组件系列——又一款Excel处理神器Spire.XLS,你值得拥有 介绍了下组件的两个功能,说不上特色,但确实能解决我 ...

  10. 基于Java的Http服务器几种模式演进

    首先抛出问题: 程序1---错误版本 import java.io.IOException; import java.io.InputStream; import java.io.PrintWrite ...