这两天看到原来的框架,开始事件的派发用c#写,通过接口比如使用c#写的模块和lua的模块直接可以使用同个机制来通信sendMsg,但是发现luaManager里面的luaState本来就可以在c#和lua直接通信如果这样比较多余,效率也低。花点事件把之前的事件派发重构全用lua来写。先说下自己的设想,回想下这个架构就是基于Meditor(Module)也就是说没个功能都相当于一个模块独立互相不干涉,但是需要通信不可以避免,参考PurMVC里面的controller做法。就是每个模块都基础 BaseMediator.lua。BaseMediator负责模块事件的注册,派发就好,重要就是ProcessEvent这个就是类似c#里面的接口类,在子类里面重写这个方法就可以处理事件。要修改过还是比较麻烦要做3步记录下。
题外话:PurMVC的事件派发是Controller里面做的有两种,一种是View事件,另外是全局事件。今天先搞好View事件。
第一步修改过BaseMediator 代码如下
--子类重写:监听事件
function BaseMediator:Notification( )
return {}
end
--子类重写:监督事件处理
function BaseMediator:ProcessEvent(eventtype,parm)
end
--注册监听
function BaseMediator:_RegisterNotifications()
local _Notics = self:Notification()
for i=1,table.getn(_Notics) do
LNotifier:Instance():RegisterEventListener(_Notics[i],self)
end
end
--移除所有监听
function BaseMediator:RemoveAllNotifications( )
local _Notics = self:Notification()
for i=1,table.getn(_Notics) do
LNotifier:Instance():RemoveEventListeners(_Notics[i],self)
end
end
再看看怎么使用BaseMediator.lua 如下登陆模块:
--监听事件
function LoginMediator:Notification( )
return {
LoginNotice.Show
}
end
--事件处理 EventType
function LoginMediator:ProcessEvent(evt,parm)
if evt == LoginNotice.Show then
if LoginRegister == nil then
LoginRegister = require("Mediator.LoginMediator.Views.LoginResgisterPanel").new()
end
LoginRegister:Show()
end
end
--mediator退出处理
function LoginMediator:Exit( )
--清空View
LoginRegister = nil
--调用父类的Exit
LoginMediator.super.Exit(self)
end
第二步 写LNotifer.lua就是一个基于Meditor的事件派发是个单例。
--[[
* 创建人 : 星华
]]
LNotifier = class("LNotifier")
local _Instance = nil --单例
local _eventListenerMap = nil
--构造函数
function LNotifier:ctor( )
_eventListenerMap = {}
end
--单例
function LNotifier:Instance()
if _Instance == nil then
_Instance = self.new()
end
return _Instance
end
--[[
结构和EventDispatcher一样
_eventListenerMap = {
1000 = {
1={Mediator1}
2={Mediator2}
}
}
]]
--注册监听 listener ->Mediator
function LNotifier:RegisterEventListener(eventType , listener)
if type(eventType) ~= "number" or listener == nil then
print("error : LNotifier:RegisterEventListener ")
return
end
--拿出listeners
local listenerTb = _eventListenerMap[eventType]
if listenerTb == nil then
--如果为空就新开个
listenerTb = {}
table.insert(listenerTb,listener)
_eventListenerMap[eventType] = listenerTb
else
--查找是否存在
if table.keyof(listenerTb, listener) == nil then
table.insert(listenerTb,listener)
else
error("RegisterEventListener error : listeren hai in")
end
end
print("--------LNotifier:RegisterEventListener-----------")
self:DumpEvent()
end
--[[
移除指定类型的所有关联事件侦听,如果参数为nil则删除当前注册器中所有的函数侦听
listener ~= nil 删除这个类型里面这个监听
]]
function LNotifier:RemoveEventListeners(eventType,listener)
--空删除所有清空表
if eventType == nil then
--获取keys
local keys = table.keys(_eventListenerMap)
for i,v in ipairs(keys) do
_eventListenerMap[v] = nil --设置为空
end
keys = nil
return
end
if type(eventType) ~= "number" then
error("LNotifier RemoveEventListeners error ",2)
return
end
local typeListeners = _eventListenerMap[eventType] --取出里面所有的这个类型的
--根据类型删除
if listener ~= nil then
if typeListeners ~= nil and table.nums(typeListeners) > 0 then
if table.keyof(typeListeners, listener) ~= nil then
table.removebyvalue(typeListeners, listener, true)
end
end
print("--------LNotifier:RemoveEventListeners--4444444---------")
self:DumpEvent()
return
end
--删除一个类型
if typeListeners ~= nil then
_eventListenerMap[eventType] = nil
end
end
--发送事件
function LNotifier:SendEvent(eventType ,tb)
if type(eventType) ~= "number" then
error("LNotifier SendEvent : error",1)
return
end
local listeners = _eventListenerMap[eventType]
if listeners == nil or #listeners <= 0 then
return
end
for i,v in ipairs(listeners) do
v:ProcessEvent(eventType,tb)
end
end
--打印
function LNotifier:DumpEvent( )
dump(_eventListenerMap)
end
return LNotifier
第三部 :再修改MediatorManager里面的发送改用LNotifier
--发送消息
function MediatorManager:SendEvent(evt,parm)
--是否发送消息
if type(evt) == "number" then
LNotifier:Instance():SendEvent(evt,parm)
end
end
--移除:注意不能再AddMediator命令里面做RemoverMediator
function MediatorManager:RemoveMediator(moduleType)
local tempMediator = self._mediators[moduleType]
if tempMediator ~= nil then
tempMediator:Exit() --先调用mediator
self._mediators[moduleType] = nil --设置为空
end
end
OK搞定,模块之间的通信写完了,这个通信就类似PurMVC里面的Ctroller里面的View之间通信。PurMVC里面还有个全局都可以通信的事件派发,之前已经写过但是发现有少少问题,明天再修改写。