事件系统

网游中,事件系统是一个不可或缺的模块。可以很方便的处理一些事件:比如杀怪,采集等。
同时也是降低模块之间耦合度的一个好办法。下面就来实现一个事件系统。
声明:很多人一看到事件系统,就联想到UI库中的事件驱动。我不得不告诉你,这是网游,不是UI。
本事件系统从设计上就是为网游服务器服务的,并不一定适合UI,网游的事件也并不复杂,也不需要上下层分发事件等。

一个事件,典型的表现就是:发生了某某事件,判断执行条件,如果满足,就执行某某行为。
在具体网游开发中,甚至会设计的更简单,发生了某某事件,执行某某函数。
#目前支持的事件列表
g_EventList = ("获得物品",)


class CEventMgr:

	def __init__(self, iID):
		self.m_ID = iID
		self.m_EventDict = {}    #事件监听器管理

	def AddEvent(self, sEventName, bSync, cbFunc):
		"""
		添加事件监听器
		@param sEventName:string,事件名称
		@param bSync:bool,是否同步处理
		@param cbFunc:function,回调函数
		"""
		global g_EventList
		if not sEventName in g_EventList:
			raise "事件%s不支持,请检查" % sEventName
		tInfo = (bSync, cbFunc)
		tEventList = self.m_EventDict.get(sEventName, [])
		if tInfo in tEventList:
			raise "事件%s %s 重复注册,请检查" % (sEventName, tInfo)
		tEventList.append(tInfo)
		self.m_EventDict[sEventName] = tEventList

	def RemoveEvent(self, sEventName, bSync, cbFunc):
		"""
		删除事件监听器
		@param sEventName:string,事件名称
		@param bSync:bool,是否同步处理
		@param cbFunc:function,回调函数
		"""
		tInfo = (bSync, cbFunc)
		if not sEventName in self.m_EventDict:
			return
		tEventList = self.m_EventDict[sEventName]
		if not tInfo in tEventList:
			return
		tEventList.remove(tInfo)
		self.m_EventDict[sEventName] = tEventList

	def FireEvent(self, sEventName, *args):
		"""
		触发事件
		@param sEventName:string,事件名称
		@param args:tuple,事件参数
		"""
		tEventList = self.m_EventDict.get(sEventName, [])
		if not tEventList:
			return
		for tEvent in tEventList:
			bSync, cbFunc = tEvent
			#过滤掉异步监听
			if not bSync:
				continue
			cbFunc(*args)
		#在下一个周期中执行异步监听的触发
		#self.FireEventAsync(sEventName, *args)

	def FireEventAsync(self, sEventName, *args):
		tEventList = self.m_EventDict.get(sEventName, [])
		if not tEventList:
			return
		for tEvent in tEventList:
			bSync, cbFunc = tEvent
			if bSync:
				continue
			cbFunc(*args)
够简单吧。
1、事件区分同步还是异步。当然了,也可以将bSync换成一个整数,表示优先级。然后FireEvent的时候,按照事件的优先级来执行。
      不过,我感觉这个用处不大,至少目前没看到。所以就只区分了同步还是异步
2、FireEvent最后,需要执行异步处理的时候,需要一个定时器,保证函数在下一个周期执行。我这里没有写出。因为定时器的代码还没整理好。
3、回调函数是可以包装一次的,这样的话,监听的时候就可以传入参数了。
4、之所以事件在初始化的时候,需要传入一个ID,目的是将事件分散开。如果事件系统全局只有一个,那么这个事件字典会异常的庞大。
      有玩家的,有怪物的,查询起来会很耗时。所以,我希望的是,每个生物类中挂接一个事件系统。自己监听自己的事件。然后保持一个全局的事件系统,
      当单个生物的事件无法实现时,就可以用全局事件来实现。
5、事件增删时,应该尽量在FireEvent之外执行,不要在事件触发的过程中进行增删事件。这个有待完善。

一个最简单的事件系统,就是这样了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值