一个监听器的结构通常是
- 监听标志 消息类型
- 回调函数 消息动作
- target 消息来源位置
- once 是否是一次性监听
即
listener={msg:msg,listener:listener,target:target,once:false}
将监听的结构放在一个字典中
msg2listDict={
msg1:listener1,
msg2:listener2,
msg3:listener3,
msg4:listener4,
...
}
触发监听
- 触发结构 msg,data
- 通过 msg 找到监听,并以 data 为参数执行监听函数
- 如果是一次性监听,执行完之后将该监听移除
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 {
}