您的位置:首页 > 其它

模拟EventCenter,flash自带的事件机制的一个解耦框架,callback回调方式用于模块之间的通信

2012-11-16 10:53 513 查看
之前写了一个简化版的puremvc,mvc框架,

后来参考一个ARPG项目的架构,目前用于解耦的我所了解的两种方式都罗列下:

1.EventCenter模式:

package com.cw.war.module.guide
{

import flash.events.EventDispatcher;

/**
* 用来解耦新手指引和各个模块
* @author elvisjiang
* @data 2012-9-25
*/
public class GuideEventCenter
{
private static var instance:GuideEventCenter;
public static function getInstance () : GuideEventCenter
{
if (instance == null)
{
instance = new GuideEventCenter ();
}
return instance;
}
public static function get I():GuideEventCenter
{
if (instance == null)
{
instance = new GuideEventCenter ();
}
return instance;
}
public function GuideEventCenter()
{
ed = new EventDispatcher();
if(instance != null) throw new Error ( "Singleton Error" );
}

private var ed:EventDispatcher;
private var  _listener:Array;

public function dispatchEvent(type:String,data:Object = null):void
{
ed.dispatchEvent(new GuideEvent(type,data));
}
public function addEventListener(type:String,fun:Function):void
{
if(!_listener)
{
_listener = [];
}

_listener.push({type:type,listener:fun});
ed.addEventListener(type,fun);
}
public function removeEventListener(type:String,fun:Function):void
{
ed.removeEventListener(type,fun);
}

public function destroy():void
{
//移除监听
while(_listener.length > 0)
{
var item:Object = _listener.shift();
removeEventListener(item.type,item.listener);
}
_listener.length = 0;
_listener = null;
ed = null;
instance = null;
}
}
}


上述的核心就是一个eventDispatcher用于转发,

比方说模块1 : proxy里面可以 这样写:

EventCenter.addEventListener("背包数据回包",_fun1);

服务器背包数据回包之后可以 EventCenter.dispatchEvent();

这有个缺点,整个游戏会监听很多事件,上个项目至少监听了500个,这个ed太任重道远了,

2.下面讲另一种解耦方式,函数回调的方式:

package
{
import flash.utils.Dictionary;

import net.libra.core.Notification;
import net.libra.core.interfaces.IController;
import net.libra.core.interfaces.INotifier;
import net.libra.log.Log;
import net.libra.utils.HashMap;
import net.libra.utils.StringUtils;

/**
* 事件转发器
* @author elvisjiang
* @data 2012-6-11
*/
public class CallPool
{
private static var _instance:CallPool;

public static function getInstance () : CallPool
{
if (_instance == null)
{
_instance = new CallPool (new PrivateClass());
}
return _instance;
}
public static function get I():CallPool
{
if (_instance == null)
{
_instance = new CallPool (new PrivateClass());
}
return _instance;
}
public static function get instance():CallPool
{
if (_instance == null)
{
_instance = new CallPool (new PrivateClass());
}
return _instance;
}

//---------------------------------------------------------------->
private var _callbacks:Dictionary;

public function CallPool(prv :PrivateClass)
{
_callbacks = new Dictionary(true);
}
//---------------------------------------------------------------------->
/**
* 注册消息回调
* 相当于addEventlistner;
* @param noticationName 消息Type
* @param fun 回调函数
*/
public function addCallBack(notificationName:String,callback:Function):void
{
if(_callbacks[notificationName] == null){
_callbacks[notificationName] = [];
}
var index:int = findAt(notificationName,callback);
if(index == -1){
_callbacks[notificationName].push(callback);
}
}
/**
* 销毁消息回调
* @param notificationName
* @param callback
*
*/
public function removeCallBack(notificationName:String,callback:Function):void
{
var index:int = findAt(notificationName,callback);
if(index != -1){
(_callbacks[notificationName] as Array).splice(index,1);
}
}
private function findAt(notificationName:String,callback:Function):int
{
var calls:Array = _callbacks[notificationName];
if(calls == null)
return -1;
var index:int = 0;
for each(var call:Function in calls){
if(call == callback)
return index;
index++;
}
return -1;
}

/**
* 向所有的注册的函数发消息
*/
public function sendNotification(notificationName:String,body:Object = null):void
{
if(_callbacks[notificationName] != null)
{
var calls:Array = _callbacks[notificationName];
if(calls == null || calls.length <= 0)
return ;
var index:int = 0;
for each(var call:Function in calls){
call.apply(null,[new Notification(notificationName,body)]);
index++;
}
}
}

}
}
class PrivateClass{}


模块1入口
package
{
import net.libra.core.Notification;

/**
*
* @author elvisjiang
* @data 2012-11-14
*/
public class Module1
{
public function Module1()
{
CallPool.I.addCallBack("123",_callback1);
CallPool.I.addCallBack("456",_callback1);
CallPool.I.removeCallBack("123",_callback1);
}
private function _callback1(notification:Notification):void
{
switch(notification.getName())
{
case "123":
trace("Module1收到123");
break;
case "456":
trace("Module1收到456");
break;
}
}
}
}


模块2入口
package
{
import net.libra.core.Notification;

/**
*
* @author elvisjiang
* @data 2012-11-14
*/
public class Module2
{
public function Module2()
{
CallPool.I.addCallBack("123",_callback1);
}
private function _callback1(notification:Notification):void
{
trace("Module2--123接收到",notification.getBody().name);
}
}
}


 测试类:

package
{
import flash.display.Sprite;

import net.libra.core.Notification;

/**
*
* @author elvisjiang
* @data 2012-11-14
*/
public class TestCallPool extends Sprite
{
public function TestCallPool()
{
new Module1();
//new Module2();
CallPool.I.sendNotification("123",{name:"xxx123"});
CallPool.I.sendNotification("456",{name:"xxx456"});
}
}
}


 消息体类

package net.libra.core
{
import flash.events.Event;

/**
* 事件通知
* @author elvisjiang
*/
public class Notification
{
private var name:String;
private var body : Object;
private var type : String;

/**
* 创建一个通知对象
* @param name    事件名称
* @param body    事件携带的数据参数
* @param type    事件类型
*/
public function Notification(name : String, body : Object = null,type : String = "")
{
this.name = name;
this.body = body;
this.type = type;
}

/**
* @inheritDoc
*/
public function getName() : String
{
return this.name;
}

/**
* @inheritDoc
*/
public function setBody(body : Object) : void
{
this.body = body;
}

/**
* @inheritDoc
*/
public function getBody() : Object
{
return this.body;
}

/**
* @inheritDoc
*/
public function setType(type : String) : void
{
this.type = type;
}

/**
* @inheritDoc
*/
public function getType() : String
{
return this.type;
}
}
}


这种方式是基于函数回调的,就是一个字符串对应一个函数列表,当callPool.sendNotication的时候,函数列表会挨个执行。

两种方式各有优缺点,有的人说eventdispatcher是最高效率的,但是用内存换效率了,函数回调的方式弱化了a lot of 监听,但如果是高性能要求的可以用eventCenter的方式,有人说监听500到1000个函数根本不在话下,看个人了,如果你觉的太重了,就用下面那个,呵呵。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐