博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模拟EventCenter,flash自带的事件机制的一个解耦框架,callback回调方式用于模块之间的通信...
阅读量:6390 次
发布时间:2019-06-23

本文共 8533 字,大约阅读时间需要 28 分钟。

之前写了一个简化版的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个函数根本不在话下,看个人了,如果你觉的太重了,就用下面那个,呵呵。

转载于:https://www.cnblogs.com/as3lib/archive/2012/11/16/2772822.html

你可能感兴趣的文章
2018年你需要知道的13个JavaScript工具库
查看>>
当你点击按钮的时候如何设置其他按钮不可点击
查看>>
spring 高级装配
查看>>
【合集】parasoft Jtest 从安装到使用教程合集,收藏推荐!
查看>>
Python Pygame库的学习之路(1)
查看>>
信息安全与Linux系统
查看>>
Ubuntu安装mysql
查看>>
SpringCloud 微服务 (十四) 服务网关 Zuul 过滤器(Pre&Post)
查看>>
代理设计模式
查看>>
初识Shiro
查看>>
在Developerkit开发板上运行blink例程
查看>>
企业级性能、安全可靠 阿里云发布企业级大数据平台开发者版
查看>>
Spring Boot使用过程小记(一)--加载自定义的Spring XML
查看>>
Git分支关联远程GitHub分支出错
查看>>
设计模式--桥接模式
查看>>
linux笔记之进程信息查看工具
查看>>
django 自定义分页器
查看>>
Oracle命令
查看>>
转载-没有IE就没有伤害!浏览器兼容性问题解决方案汇总
查看>>
常用 tcpdump 抓包方式
查看>>