文档章节

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

rise-worlds
 rise-worlds
发布于 2016/06/20 13:40
字数 599
阅读 0
收藏 0

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

本文转载自:http://www.cnblogs.com/flying_bat/archive/2007/10/11/921080.html

共有 人打赏支持
rise-worlds

rise-worlds

粉丝 2
博文 1755
码字总数 0
作品 0
深圳
程序员
私信 提问
关于LUA+Unity开发_toLua篇【一】

网上有许多的LUA与Unity插件,如toLua,uLua, sLua, xLua。 uniLua由于其复杂的集成使用过程,已经被主流所抛弃了。在对各个插件使用过之后,出此系列博客与大家分享一下心得。 前面两篇计划...

AveryHuo
2018/01/13
7
0
Unity SLua 如何调用Unity中C#方法

1.原理 就是通常在Lua框架中所说的,开放一个C#的web接口,或者叫做在Slua框架中注册函数。 2.作用 在Lua中调用C#中的方法,这个是在做热更新中很常用的一种方法,无论是slua,还是lua,都差...

吴金瑞
2018/06/26
0
0
Unity3D 下 Lua 编程解决方案--xLua

Unity3D下Lua编程支持 xLua为Unity3D增加Lua脚本编程的能力,进而提供代码逻辑增量更新的可能。当然不仅仅如此,在coco2dx上的实践告诉我们,以Lua为主打语言的游戏客户端编程是可行的。 xL...

Johnche
2017/01/04
7.6K
6
腾讯开源手游热更新方案,Unity3D 下的 Lua 编程

xLua是Unity3D下Lua编程解决方案,自2016年初推广以来,已经应用于十多款腾讯自研游戏,因其良好性能、易用性、扩展性而广受好评。现在 腾讯已经将 xLua 开源到GitHub。 2016年12月末,xLua刚...

两味真火
2017/01/04
15.9K
8
xLua 2.1.14 发布,腾讯开源的手游热更新解决方案

xLua 2.1.14 发布了。xLua 为 Unity、 .Net、 Mono 等 C# 环境增加 Lua 脚本编程的能力,借助 xLua,这些 Lua 代码可以方便的和 C# 相互调用。xLua 在功能、性能、易用性都有不少突破,这几方...

段段段落
02/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Confluence 6 升级中的一些常见问题

升级的时候遇到了问题了吗? 如果你想尝试重新进行升级的话,你需要首先重新恢复老的备份。不要尝试再次对 Confluence 进行升级或者在升级失败后重新启动老的 Confluence。 在升级过程中的一...

honeymoose
今天
2
0
C++随笔(四)Nuget打包

首先把自己编译好的包全部准备到一个文件夹 像这样 接下来新建一个文本文档,后缀名叫.nuspec 填写内容 <?xml version="1.0"?><package xmlns="http://schemas.microsoft.com/packaging/201......

Pulsar-V
今天
2
0
再谈使用开源软件搭建数据分析平台

三年前,我写了这篇博客使用开源软件快速搭建数据分析平台, 当时收到了许多的反馈,有50个点赞和300+的收藏。到现在我还能收到一些关于dataplay2的问题。在过去的三年,开源社区和新技术的发...

naughty
今天
12
0
Python3的日期和时间

python 中处理日期时间数据通常使用datetime和time库 因为这两个库中的一些功能有些重复,所以,首先我们来比较一下这两个库的区别,这可以帮助我们在适当的情况下时候合适的库。 在Python文...

编程老陆
今天
2
0
分布式面试整理

并发和并行 并行是两个任务同时进行,而并发呢,则是一会做一个任务一会又切换做另一个任务。 临界区 临界区用来表示一种公共资源或者说是共享数据,可以被多个线程使用,但是每一次,只能有...

群星纪元
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部