加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-14 22:20:05 所属栏目:大数据 来源:网络整理
导读:Lua中实现类似C#的事件机制 Lua的语法非常灵活,使用他的metatable及metamethod可以模拟出很多语言的特性.? C#中我们这样使用事件: xxx.Click?+=? new ?System.EventHandler(xxx_Click); private ? void ?xxx_Click( object ?sender,?EventArgs?e) { ???? /*

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略有改动.

--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:响应方法
Event:Add(source,?func)
????table.insert(self,?{source,?func})????
end

--内部方法,?重写了默认__call逻辑,?当event被触发调用时,?循环执行event中注册的响应方法
--@table:对象产生调用时将本身传入
--@

:调用参数
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?=? New(),
}

--执行点击按钮的动作
function?Button:Click()
???? print( ' Click?begin')
????--触发事件,?self即sender参数
????self.ClickEvent(self)
???? Click?end')
end

--从这里执行
Window:Init()
Button:Click()
--[[
执行结果:
>?dofile? test.lua'
Click?begin
A?Button?Click? On?Simonw s?Window
Click? end
]]

end http://www.cnblogs.com/simonw/archive/2006/12/20/597986.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读