文档章节

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

rise-worlds
 rise-worlds
发布于 2016/06/20 13:39
字数 599
阅读 1
收藏 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

上一篇: 水煮TCPMP (转)
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

没有更多内容

加载失败,请刷新页面

加载更多

JWT学习总结

官方 https://jwt.io 英文原版 https://www.ietf.org/rfc/rfc7519.txt 或 https://tools.ietf.org/html/rfc7519 中文翻译 https://www.jianshu.com/p/10f5161dd9df 1. 概述 JSON Web Token(......

冷基
38分钟前
3
0
AOP的学习(1)

AOP 理解AOP编程思想(面向方法、面向切面) spring AOP的概念 方面 -- 功能 目标 -- 原有方法 通知 -- 对原有方法增强的方法 连接点 -- 可以用来连接通知的地方(方法) 切入点 -- 将用来插入...

太猪-YJ
今天
4
0
一张图看懂亮度、明度、光度、光亮度、明亮度

亮度、明度、光亮度,Luminance和Brightness、lightness其实都是一个意思,只是起名字太难了。 提出一个颜色模型后,由于明度的取值与别人的不同,为了表示区别所以就另想一个词而已。 因此在...

linsk1998
昨天
8
0
Python应用:python链表示例

前言 python链表应用源码示例,需要用到python os模块方法、函数和类的应用。 首先,先简单的来了解下什么是链表?链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是...

python小白1
昨天
4
0
Source Insight加载源码

Source Insight是一个图形化的源代码查看工具(当然也可以作为编译工具)。如果一个项目的源代码较多,此工具可以很方便地查找到源代码自建的依赖关系。 1.创建工程 下图为Snort源代码的文件...

天王盖地虎626
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部