在设计五中,我们把事件系统EventSystem实现一下。这个EventSystem类主要实现的是事件的注册,触发,以及分发Event消息的作用。提供接口对外使用的。在这里面为了功能扩展方便用了好多模板函数,方便大家调用。

分发消息的时候,我们采用的是队列的方式,就是先进先出原则。

首先要把消息事件注册一下,就是将其放到我们预先定义的表里面。函数代码如下所示:

int Register(string eventName, Func<object,object,object,bool> action) {int   listenID = ++mNextListenID;Listen  listen = (mFreeListen.Count == 0) ? new Listen() : mFreeListen.Pop();listen.mID = listenID;listen.mAction = action;mRegistered.Add(listenID, listen);List<int>  eventList;if(!mRegisteredEvents.TryGetValue(eventName, out eventList))eventList = mRegisteredEvents[eventName] = new List<int>();eventList.Add(listenID);return listenID;}

接下来就是 消息事件的触发代码如下:

  public void Trigger(string eventName) {Call(eventName, null, null, null);}
void Call(string eventName, object arg1, object arg2, object arg3) {List<int> listenerList;if(mRegisteredEvents.TryGetValue(eventName, out listenerList)) {for(int i = listenerList.Count - 1; i >= 0; --i) {Listen listener;if(mRegistered.TryGetValue(listenerList[i], out listener)) {if(!listener.mAction(arg1, arg2, arg3)) {mRegistered.Remove(listenerList[i]);mFreeListen.Push(listener);listenerList.RemoveAt(i);}}else {listenerList.RemoveAt(i);}}if(listenerList.Count == 0) {mRegisteredEvents.Remove(eventName);}}}

 遍历查找消息列表是否在mRegistererdEvents这个字典里面,mRegisteredEvents的定义如下:

Dictionary<string,List<int>>  mRegisteredEvents = new Dictionary<string, List<int>>();

  Listen的定义如下:

  class Listen {public int        mID;public Func<object,object,object,bool> mAction;}

 接下来就是最核心的功能了,状态机的切换功能代码:

public int On<T1,T2,T3>(string eventName, Func<T1,T2,T3,bool> action) {return Register(eventName, delegate(object arg1, object arg2, object arg3) {T1  param1;T2  param2;T3  param3;try { param1 = (T1)arg1; } catch { param1 = default(T1); }try { param2 = (T2)arg2; } catch { param2 = default(T2); }try { param3 = (T3)arg3; } catch { param3 = default(T3); }return(action(param1, param2, param3));});}public int On<T1,T2,T3>(string eventName, Action<T1,T2,T3> action) {return Register(eventName, delegate(object arg1, object arg2, object arg3) {T1  param1;T2  param2;T3  param3;try { param1 = (T1)arg1; } catch { param1 = default(T1); }try { param2 = (T2)arg2; } catch { param2 = default(T2); }try { param3 = (T3)arg3; } catch { param3 = default(T3); }action(param1, param2, param3);return true;});}

整个的EventSystem事件系统的代码如下所示:

using System;
using System.Collections;
using System.Collections.Generic;
namespace EventSystem {public class Dispatcher {  public void Trigger(string eventName) {Call(eventName, null, null, null);}public void Dispatch(string eventName) {Dispatched d = (mFreeDispatch.Count == 0) ? new Dispatched() : mFreeDispatch.Pop();mDispatched.Enqueue(d.Set(eventName));}public int On(string eventName, Func<bool> action) {return Register(eventName, delegate(object arg1, object arg2, object arg3) {return(action());});}public int On(string eventName, Action action) {return Register(eventName, delegate(object arg1, object arg2, object arg3) {action();return(true);});}public void Trigger(string eventName, object param1) {Call(eventName, param1, null, null);}public void Dispatch(string eventName, object param1) {Dispatched d = (mFreeDispatch.Count == 0) ? new Dispatched() : mFreeDispatch.Pop();mDispatched.Enqueue(d.Set(eventName, param1));}public int On<T>(string eventName, Func<T,bool> action) {return Register(eventName, delegate(object arg1, object arg2, object arg3) {T  param1;try { param1 = (T)arg1; } catch { param1 = default(T); }return(action(param1));});}public int On<T>(string eventName, Action<T> action) {return Register(eventName, delegate(object arg1, object arg2, object arg3) {T  param1;try { param1 = (T)arg1; } catch { param1 = default(T); }action(param1);return true;});}public void Trigger(string eventName, object param1, object param2) {Call(eventName, param1, param2, null);}public void Dispatch(string eventName, object param1, object param2) {Dispatched d = (mFreeDispatch.Count == 0) ? new Dispatched() : mFreeDispatch.Pop();mDispatched.Enqueue(d.Set(eventName, param1, param2));}public int On<T1,T2>(string eventName, Func<T1,T2,bool> action) {return Register(eventName, delegate(object arg1, object arg2, object arg3) {T1  param1;T2  param2;try { param1 = (T1)arg1; } catch { param1 = default(T1); }try { param2 = (T2)arg2; } catch { param2 = default(T2); }return(action(param1, param2));});}public int On<T1,T2>(string eventName, Action<T1,T2> action) {return Register(eventName, delegate(object arg1, object arg2, object arg3) {T1  param1;T2  param2;try { param1 = (T1)arg1; } catch { param1 = default(T1); }try { param2 = (T2)arg2; } catch { param2 = default(T2); }action(param1, param2);return true;});}public void Trigger(string eventName, object param1, object param2, object param3) {Call(eventName, param1, param2, param3);}public void Dispatch(string eventName, object param1, object param2, object param3){Dispatched d = (mFreeDispatch.Count == 0) ? new Dispatched() : mFreeDispatch.Pop();mDispatched.Enqueue(d.Set(eventName, param1, param2, param3));}public int On<T1,T2,T3>(string eventName, Func<T1,T2,T3,bool> action) {return Register(eventName, delegate(object arg1, object arg2, object arg3) {T1  param1;T2  param2;T3  param3;try { param1 = (T1)arg1; } catch { param1 = default(T1); }try { param2 = (T2)arg2; } catch { param2 = default(T2); }try { param3 = (T3)arg3; } catch { param3 = default(T3); }return(action(param1, param2, param3));});}public int On<T1,T2,T3>(string eventName, Action<T1,T2,T3> action) {return Register(eventName, delegate(object arg1, object arg2, object arg3) {T1  param1;T2  param2;T3  param3;try { param1 = (T1)arg1; } catch { param1 = default(T1); }try { param2 = (T2)arg2; } catch { param2 = default(T2); }try { param3 = (T3)arg3; } catch { param3 = default(T3); }action(param1, param2, param3);return true;});}public bool Cancel(int listenerID) {return mRegistered.Remove(listenerID);}public void DispatchPending() {while(mDispatched.Count > 0) {Dispatched d = mDispatched.Dequeue();Call(d.mEventName, d.mArg1, d.mArg2, d.mArg3);mFreeDispatch.Push(d);}}int Register(string eventName, Func<object,object,object,bool> action) {int   listenID = ++mNextListenID;Listen  listen = (mFreeListen.Count == 0) ? new Listen() : mFreeListen.Pop();listen.mID = listenID;listen.mAction = action;mRegistered.Add(listenID, listen);List<int>  eventList;if(!mRegisteredEvents.TryGetValue(eventName, out eventList))eventList = mRegisteredEvents[eventName] = new List<int>();eventList.Add(listenID);return listenID;}void Call(string eventName, object arg1, object arg2, object arg3) {List<int> listenerList;if(mRegisteredEvents.TryGetValue(eventName, out listenerList)) {for(int i = listenerList.Count - 1; i >= 0; --i) {Listen listener;if(mRegistered.TryGetValue(listenerList[i], out listener)) {if(!listener.mAction(arg1, arg2, arg3)) {mRegistered.Remove(listenerList[i]);mFreeListen.Push(listener);listenerList.RemoveAt(i);}}else {listenerList.RemoveAt(i);}}if(listenerList.Count == 0) {mRegisteredEvents.Remove(eventName);}}}class Listen {public int        mID;public Func<object,object,object,bool> mAction;}class Dispatched {public Dispatched Set(string eventName, object arg1=null, object arg2=null, object arg3=null) {mEventName = eventName;mArg1 = arg1;mArg2 = arg2;mArg3 = arg3;return this;}public string mEventName;public object mArg1, mArg2, mArg3;}Dictionary<string,List<int>>  mRegisteredEvents = new Dictionary<string, List<int>>();Dictionary<int,Listen>    mRegistered = new Dictionary<int, Listen>();Stack<Listen>      mFreeListen = new Stack<Listen>();Stack<Dispatched>     mFreeDispatch = new Stack<Dispatched>();Queue<Dispatched>     mDispatched = new Queue<Dispatched>();int         mNextListenID = 4711;}
}

接下来我会在最后一讲也就是设计六中,给大家说一下如何去使用。

转载于:https://blog.51cto.com/jxwgame/1613585

U3D架构系列之- FSM有限状态机设计五相关推荐

  1. FSM有限状态机设计(Logisim)

    第1关:时序逻辑电路的分类 第2关:6进制递增计数器--状态转换组合逻辑设计 实验任务 完成6进制递增计数器的状态转换组合逻辑的设计. 点击生成即可 第3关:6进制递增计数器--输出函数组合逻辑设计 ...

  2. 游戏 AI 设计之 FSM 有限状态机

    FSM 有限状态机 一.概述 有限状态机(finite-state machine,缩写:FSM)又称有限状态自动机(finite-state automaton,缩写:FSA),简称状态机,是表示有 ...

  3. 朱晔的互联网架构实践心得S1E9:架构评审一百问和设计文档五要素

    朱晔的互联网架构实践心得S1E9:架构评审一百问和设计文档五要素 [下载文本PDF进行阅读] 本文我会来说说我认为架构评审中应该看的一些点,以及我写设计文档的一些心得.助你在架构评审中过五关斩六将,助 ...

  4. C#进阶系列——DDD领域驱动设计初探(五):AutoMapper使用

    前言:前篇搭建了下WCF的代码,就提到了DTO的概念,对于为什么要有这么一个DTO的对象,上章可能对于这点不太详尽,在此不厌其烦再来提提它的作用: 从安全上面考虑,领域Model都带有领域业务,让Cl ...

  5. 架构系列---一套高并发IM通信系统完整设计和实现

    先行参考:架构秘境系列3---微信.陌陌.WNS著名IM软件设计架构详解 1. 服务器端设计 1.1 总体架构 总体架构包括5个层级,具体内容如下图. 1.1.1 用户端 移动端重点是移动端,支持IO ...

  6. IBM系统分析——架构设计五视图+数据设计

    目  录 一.架构设计五视图 1. 逻辑架构 2. 开发架构 3. 运行架构 4. 物理架构 5. 数据架构 二.数据设计 1. 数据库的逻辑模型 2. 数据库的常用模型 3. 实现从面对对象模型到表 ...

  7. 高并发架构系列:如何从0到1设计一个类Dubbo的RPC框架

    优知学院 2019-01-22 18:43:51 之前持续分享的几十期阿里Java面试题中,几乎每次必问Dubbo,比如:"如何从0到1设计一个Dubbo的RPC框架",其实主要考 ...

  8. ‘SHIT’上最全有限状态机设计研究(一)-状态机介绍

    本系列主要针对有限状态机进行分析和设计,其中主要包括两部分:时钟同步状态机的分析和时钟同步状态机的设计,预计会有五篇文章进行展开,其中介绍一篇,分析和设计分别有两篇,每一部分都会有相应的实例. 文章目 ...

  9. 微服务架构系列二:密码强度评测的实现与实验

    本文是继<微服务架构系列一:关键技术与原理研究>的后续,系列一中论述了微服务研究的背景和意义,主要调研了传统架构的发展以及存在的问题和微服务架构的由来,然后针对微服务架构的设计原则.容器技 ...

最新文章

  1. 平正真诚——记红帆公司2011年秋季旅游·衡山
  2. 互联网人不敢生孩子:加班多、想跳槽、怕被边缘化
  3. merge sort loser tree
  4. java webservice接口开发_给Java新手的一些建议----Java知识点归纳(J2EE and Web 部分)
  5. 如何解决创建Account时的error message BP category 2 does not fit the data in category 1
  6. 计算机系在职研究生 网络班,在职研究生都有网络班吗?
  7. “docker-app”实用工具分享,大大提高 Compose 文件复用率
  8. 大学计算机一级word,大学计算机基础一级考试复习资料
  9. android语法高亮编辑器,HighlightTextEditor
  10. java输出值_java参数传递(超经典)(强烈建议自己先写出程序的输出值)
  11. python爬取豆瓣电影top250的名字_Python爬虫-爬取豆瓣电影Top250
  12. [最小生成树] 继续畅通工程
  13. 华为MUX VLAN原理和实验
  14. Linux学习第一节课学习心得
  15. bzoj5336: [TJOI2018]party【状压dp】
  16. SAP跨公司销售经典场景
  17. greenplum 历史拉链表
  18. [NFC]NDEF和RTD协议介绍
  19. size balanced tree (平衡二叉树) ----- 傻X树----陈启峰论文
  20. 如何设计一条稳定的应用交付流程?

热门文章

  1. 7.Deque的应用案例-回文检查
  2. 16种JavaScript设计模式(中)
  3. 智课雅思词汇---五、优词词根字典
  4. SHOI2008仙人掌图(tarjan+dp)
  5. 小程序实现 Tab 标签栏
  6. 跨站请求伪造CSRF
  7. MySQL-WorkBench修改MySQL配置注意事项
  8. 【Linux】Linux基本命令扫盲【转】
  9. Exchange 2010 OAB无法更新
  10. Httpclient学习日记(一)