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 欢迎大家多多指教。

U3D C# 实现AS3事件机制

时间: 2024-10-13 19:51:30

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

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

题记: 看过网上一些as3事件流的教程,觉得大多都讲得不甚清楚,让人不能喝很直观的理解.而这篇教程以将事件流过程比喻成捕鱼过程,形象简单. 在此基础上对于as3事件流总算有了全面的理解.事件流机制说白了就是为了能让开发者能更好地控制事件调用顺序. addEventListener(type:String, listener:Function, useCapture:Boolean= false, priority:int= 0, useWeakReference:Boolean= false):

Aa3.0 事件机制

说明:本文由多处网络文章整理而成,在此未一一注明原文链接,敬请谅解! AS3:事件流机制 事件流 只要发生事件,Flash Player就会调度该事件对象. 如果事件目标不在显示列表中,则Flash Player将事件对象直接调度到事件目标. 如果事件目标在显示列表中,则Flash Player将事件对象调度到显示列表,然后该事件对象将在显示列表中进行一次从舞台到“目标节点”的往返行程. 事件流说明事件对象如何在显示列表中穿行,分为三部分: 第一部分称为捕获阶段,该阶段包括从舞台到目标节点的父节

关于Flex事件机制的理解

优点:减少同一个UI树上对象监听器数量,从而带来性能优化. 1.FLEX 事件机制是分为三个阶段. 捕获---〉目标----〉冒泡 所谓捕获:即是寻找目标的过程,是目标的父节点.注:起点是Stage,终点也是Stage. 所谓目标:即是找到目标. 所谓冒泡:可以理解为捕获的返过程. 此为官方图解. 事件的派发: Flex中可以通过dispatchEvent()方法手工派发事件, 所有UIComponent的子类都可以调用此方法.   语法:   objectInstance.dispatchEv

(转)AS3 事件框架- Signals篇

这篇文章详细的介绍了Robert Penner的AS3 Signals是什么,以及如何使用它让对象间的沟通更迅捷.它可以避免你使用常规的ActionScript事件机制,用到的代码量更少.我们将通过范例来了解不同类型的signals,从而向大家描绘出如何在实际项目中应用signals.我希望你会和我一样,喜欢上AS3 Signals带来的对象沟通方便的感觉.其中一个裨益就是Signals非常容易掌握应用.你将很快实现它,它也会带来更多的便捷.那么我们开始吧!如果你想亲历亲为,也是不错的主意,可以

QT开发(六十三)——QT事件机制分析

QT开发(六十三)--QT事件机制分析 一.事件机制 事件是由系统或者QT平台本身在不同的时刻发出的.当用户按下鼠标.敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件.一些事件在对用户操作做出响应时发出,如键盘事件等:另一些事件则是由系统自动发出,如计时器事件. 事件的出现,使得程序代码不会按照原始的线性顺序执行.线性顺序的程序设计风格不适合处理复杂的用户交互,如用户交互过程中,用户点击"打开文件"将开始执行打开文件的操作,用户点击"保存文件"将开始执

Qt事件机制概览

Qt事件机制概览 Qt事件机制概览 消息循环 Qt事件循环 简介 QEventLoop 跨线程的信号和槽与事件循环 模态窗口 Native widget or Alien widget 创建Native widget 创建QApplication的message-only窗口 派发事件的公共基础方法 source code QApplication的创建过程 QWidget native QWidget 的创建过程 普通native widget回调过程 QApplication的message

JavaScript事件机制

<script type="text/javascript" src="http://runjs.cn/gist/2zmltkfa/all"></script> [前端培养-作业01]javascript事件机制 1.javascript事件模型 2.e.target与e.currentTarget是干什么的? 3.preventDefault与stopPropagation是干什么的 4.什么是dispatchEvent? 5.说一说事件代

Android-- Android事件机制之二:onTouch详解

Android事件机制之二:onTouch详解 在其中对OntouchEvent中的总结中,不是很具体.本文将主要对onTouch进行总结. onTouch是Android系统中整个事件机制的基础.Android中的其他事件,如onClick.onLongClick等都是以onTouch为基础的. onTouch包括从手指按下到离开手机屏幕的整个过程,在微观形式上,具体表现为action_down.action_move和action_up等过程. onTouch两种主要定义形式如下: (1)在

聊一聊Android的事件机制

侯 亮 1概述 在Android平台上,主要用到两种通信机制,即Binder机制和事件机制,前者用于跨进程通信,后者用于进程内部通信. 从技术实现上来说,事件机制还是比较简单的.从大的方面讲,不光是Android平台,各种平台的消息机制的原理基本上都是相近的,其中用到的主要概念大概有: 1)消息发送者: 2)消息队列: 3)消息处理循环. 示意图如下: 图中表达的基本意思是,消息发送者通过某种方式,将消息发送到某个消息队列里,同时还有一个消息处理循环,不断从消息队列里摘取消息,并进一步解析处理.