在Lua中实现类似C#的事件机制
终极管理员 知识笔记 95阅读
Lua's语法非常灵活,很多语言特性都可以用他的元表和元方法来模拟。在C#中,我们使用事件:xxx。单击=新系统。Eventhandler (XXX _ click)这样。privatevidxxx _ click(object sender,eventargse) {/* *}在Lua中应该达到同样的效果,并且支持事件组播机制。关键是重写metamethod __call,这样不仅函数可以调用,表也可以调用。主要思想是,通过一个表保存注册事件的几个响应函数,然后把这个表作为一个函数调用。重写__call后,调用表时可以遍历表中的注册方法。需要在lua5.0或lua.net上执行,lua 5.1略有改动。-测试。luado——一个事件原型对象,所有事件都从它生成事件。
r: rgba(0, 0, 0, 1)"> = {}function Event:New()
local event = {}
setmetatable(event, self)
--覆盖__index逻辑
self.__index = self
--覆盖__call逻辑
self.__call = self.Call
return event
end
--事件注册, 通过此方法将响应方法注册到事件上.
--@source:响应方法的所属对象
--@func:响应方法
function Event:Add(source, func)
table.insert(self, {source, func})
end
--内部方法, 重写了默认__call逻辑, 当event被触发调用时, 循环执行event中注册的响应方法
--@table:对象产生调用时将本身传入
--@:调用参数
function Event.Call(table, )
for _, item in ipairs(table) do
--item[1]就是source, item[2]就是func响应方法
--lua 5.1中无需使用unpack(arg), 直接使用即可
item[2](item[1], unpack(arg))
end
end
------------------以下为测试用例-----------------------
--创建一个window对象, 注册按钮的点击事件
Window = {
Name = "Simonw's Window",
}
function Window:Init()
--注册事件, self即Window, 对象来源.
Button.ClickEvent:Add(self, self.Button_OnClick)
end
--响应事件方法, sender即是传来的Button对象
function Window:Button_OnClick(sender)
print(sender.Name.." Click On "..self.Name)
end
--创建一个button对象, 拥有ClickEvent这样的事件
Button = {
Name = "A Button",
--创建事件
ClickEvent = Event:New(),
}
--执行点击按钮的动作
function Button:Click()
print('Click begin')
--触发事件, self即sender参数
self.ClickEvent(self)
print('Click end')
end
--从这里执行
Window:Init()
Button:Click()
--[[
执行结果:
> do;'test.lua'
Click begin
A Button Click On Simonw's Window
Click end
]]
end

标签: