Lua中实现类似C#的事件机制

Lua的语法非常灵活, 使用他的metatable及metamethod可以模拟出很多语言的特性.

  C#中我们这样使用事件:

  xxx.Click += new System.EventHandler(xxx_Click);   private void xxx_Click(object sender, EventArgs e)   {   /**/   }

  在Lua中要达到同样的效果, 并且支持事件多播机制, 其关键在于重写metamethod __call, 从而使得不光function才能被调用, table也能够被调用.

  主要思想就是, 通过一个table来保存注册事件的若干响应函数, 然后拿table当function一样来调用, 重写__call后, 实现调用table时遍历执行table中的注册方法.

  需要在lua5.0 或 lua.net上执行, lua 5.1略有改动.

  切换行号显示

  1 --test.lua   2 do   3   4 --事件原型对象, 所有事件由此原型生成   5 Event = {}   6   7 function Event:New()   8 local event = {}   9 setmetatable(event, self)   10 --覆盖__index逻辑   11 self.__index = self   12 --覆盖__call逻辑   13 self.__call = self.Call   14 return event   15 end   16   17 --事件注册, 通过此方法将响应方法注册到事件上.   18 --@source:响应方法的所属对象   19 --@func:响应方法   20 function Event:Add(source, func)   21 table.insert(self, {source, func})   22 end   23   24 --内部方法, 重写了默认__call逻辑, 当event被触发调用时, 循环执行event中注册的响应方法   25 --@table:对象产生调用时将本身传入   26 --@...:调用参数   27 function Event.Call(table, ...)   28 for _, item in ipairs(table) do   29 --item[1]就是source, item[2]就是func响应方法   30 --lua 5.1中无需使用unpack(arg), 直接使用...即可   31 item[2](item[1], unpack(arg))   32 end   33 end   34   35 ------------------以下为测试用例-----------------------   36   37 --创建一个window对象, 注册按钮的点击事件   38 Window = {   39 Name = "Simonw's Window",   40 }   41   42 function Window:Init()   43 --注册事件, self即Window, 对象来源.   44 Button.ClickEvent:Add(self, self.Button_OnClick)   45 end   46   47 --响应事件方法, sender即是传来的Button对象   48 function Window:Button_OnClick(sender)   49 print(sender.Name.." Click On "..self.Name)   50 end   51   52 --创建一个button对象, 拥有ClickEvent这样的事件   53 Button = {   54 Name = "A Button",   55 --创建事件   56 ClickEvent = Event:New(),   57 }   58   59 --执行点击按钮的动作   60 function Button:Click()   61 print('Click begin')   62 --触发事件, self即sender参数   63 self.ClickEvent(self)   64 print('Click end')   65 end   66   67 --从这里执行   68 Window:Init()   69 Button:Click()   70 --[[   71 执行结果:   72 > dofile 'test.lua'   73 Click begin   74 A Button Click On Simonw's Window   75 Click end   76 ]]   77   78 end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值