游戏开发笔记-消息监听及分发

一个监听器的结构通常是

  • 监听标志 消息类型
  • 回调函数 消息动作
  • target 消息来源位置
  • once 是否是一次性监听

listener={msg:msg,listener:listener,target:target,once:false}

将监听的结构放在一个字典中

msg2listDict={
    msg1:listener1,
    msg2:listener2,
    msg3:listener3,
    msg4:listener4,
    ...
}

触发监听

  1. 触发结构 msg,data
  2. 通过 msg 找到监听,并以 data 为参数执行监听函数
  3. 如果是一次性监听,执行完之后将该监听移除

code

class NotifyCenter{
	constructor(){
		this.msg2listDict = {}
	}
	static instance(){
		if (NotifyCenter.g === undefined) {
			NotifyCenter.g = new NotifyCenter()
		}
		return NotifyCenter.g
	}
	addListener(msg,listener,target){
		cc.log('NotifyCenter 监听消息',msg,listener)
		let info = {msg:msg,listener:listener,target:target}
		if (this.msg2listDict.hasOwnProperty(msg)) {
			this.msg2listDict[msg].push(info)
		} else {
			this.msg2listDict[msg] = [info]
		}
	}
	addOnceListener(msg,listener,target){
		let info = {msg:msg,listener:listener,target:target,once:true}
		this.msg2listDict[msg] = [info]

	}
	removeMsgListener(msg,listener){
		if (!this.msg2listDict.hasOwnProperty(msg)) return;
		let list = this.msg2listDict[msg]
		for (let i=0;i<list.length;i++) {
			let info = list[i]
			if (info.listener === listener) {
				list.splice(i,1)
				break
			}
		}
	}
	removeAllListener(){
		this.msg2listDict = {}
	}
	removeMsgAllListener(msg){
		if (this.msg2listDict.hasOwnProperty(msg)) {
			this.msg2listDict[msg] = []
		}
	}
	removeTargetMsgListener(msg,target){
		if (!this.msg2listDict.hasOwnProperty(msg)) return;
		let list = this.msg2listDict[msg]
		for (let i=list.length; i>=0; i--) {
			let info = list[i]
			if (info.target === target) {
				list.splice(i,1)
				break
			}
		}
	}
	removeTargetAllListener(target){
		for (let msg of this.msg2listDict) {
			let list = this.msg2listDict[msg]
			for (let i=list.length; i>=0; i--) {
				if (list[i].target === target) {
					list.splice(i,1)
					break
				}
			}
		}
	}
	notify(msg,data){
		if (!this.msg2listDict.hasOwnProperty(msg)) return;
		let list = this.msg2listDict[msg]
		for (let i=list.length-1; i>=0; i--){
			let info = list[i]
			if (info.hasOwnProperty('once') && !!info.once){
				list.splice(i,1)
			}
			this.dispatch(info, msg, data)
		}
	}
	dispatch(info,msg,data) {
		info.listener(msg,data)
	}
}

NotifyCenter.g = undefined

export default NotifyCenter.instance()

测试用例

class Notify {

}


posted @ 2019-09-11 22:39  heitufei  阅读(177)  评论(0编辑  收藏  举报