Lua中实现类似C#的事件机制Lua的语法非常灵活, 使用他的metatable及metamethod可以模拟出很多语言的特性. xxx.Click += new System.EventHandler(xxx_Click);
private void xxx_Click(object sender, EventArgs e) { /**/ } 在Lua中要达到同样的效果, 并且支持事件多播机制, 其关键在于重写metamethod __call, 从而使得不光function才能被调用, table也能够被调用. --test.lua do --事件原型对象, 所有事件由此原型生成 Event = {} 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() --[[ 执行结果: > dofile 'test.lua' Click begin A Button Click On Simonw's Window Click end ]] end |
|