Lua 安全调用 metatable 的简单应用
事情的经过
我们的项目中存在好几个战斗界面,不过界面中的内容略有不同。跟同事出去吃饭的时候,他问我。我们现在的战斗界面。有很多是重复的,但是也有偶尔几个地方不太一样。我在战斗过程中驱动这些界面的时候。还需要判断一下有没有这个函数,然后在选择调用它。比较麻烦,你说怎么样才能更好的规划这件事情呢?我第一个想到的就是抽离出来一个UI的父层对象。然后父层对象实现所有的函数。然后让父层函数hook住具体的页面。然后判断具体的页面究竟有没有这个函数,如果存在这个函数那么调用,否则什么都不做就行了。不过,我突然间意识到,我们似乎存在更简单的方式来解决这个问题。
基础知识
Lua中本身是没有继承这种概念的,他里边大部分内容都是通过table来解决的。在最开始学习Lua的时候了解到。他的继承关系实际上是基于metatable的__index来实现的。原理就是当在这个table中没有找到的函数或者属性他就会从metatable中的__index属性中来找。(顺便提一句其实Cocos2dx lua中的继承类都用用的同一个,也就是内存继承,主要继承来的是对应的函数。不过这个扯得有点远了)。上文中提到的查找会分情况来定,如果metatable中的__index为nil时,则不找了,直接返回nil。如果metatable中的__index是一个table的话就尝试从这个table中匹配相关的内容,如果这个table也没有那么就按照这个规则继续往上找(如果很不幸,你的metatable的__index指向的对象就是你自己的话,那么就会进入死循环)。还有第三种情况,如果metatable的__index是一个function那么,就会以这个函数的返回结果作为查找结果(按照这个原理,你可以返回任何东西。甚至可以实现多重继承,听起来很有诱惑力,不过最好不要这么做,因为比较麻烦并且lua不是那种守规矩的语言)。
实现的思路
创建一个Table,然后让他hook住对应的实际对象,然后重写对象metatable中的__index为一个函数,让这个函数返回对应的调用函数,在返回的函数中尝试查找源数据的对应函数,如果存在就调用,不存在就什么也不做。
具体的代码
local SafeCall = {} function SafeCall:create(souce)
local instance = {}
setmetatable(instance, {__index = function(self, aname)
local attribute = self.__Souce[aname]
if type(attribute) == "function" or type(attribute) == "nil" then
return function(...)
if attribute then
local args = {...}
if #args > and args[] == self then
table.remove(args, )
return attribute(self.__Souce, unpack(args))
else
return attribute(...)
end
end
end
else
return attribute
end
end})
instance.__Souce = souce
return instance
end function SafeCall.new(souce)
return SafeCall:create(souce)
end kunpo.SafeCall = SafeCall
return SafeCall
Lua 安全调用 metatable 的简单应用的更多相关文章
- 深入xLua实现原理之Lua如何调用C#
xLua是腾讯的一个开源项目,为Unity. .Net. Mono等C#环境增加Lua脚本编程的能力.本文主要是探讨xLua下Lua调用C#的实现原理. Lua与C#数据通信机制 无论是Lua调用C# ...
- Lua中调用C函数
Lua利用一个虚拟的堆栈来给C传递值或从C获取值.每当Lua调用C函数,都会获得一个新的堆栈,该堆栈初始包含所有的调用C函数所需要的参数值(Lua传给C函数的调用实参),并且C函数执行完毕后,会把返回 ...
- LuaJavaBridge - Lua 与 Java 互操作的简单解决方案
http://dualface.github.io/blog/2013/01/01/call-java-from-lua/ 最近在游戏里要集成中国移动的 SDK,而这些 SDK 都是用 Java 编写 ...
- tolua++实现lua层调用c++技术分析
tolua++技术分析 cocos2dx+lua 前言 一直都使用 cocos2dx + lua 进行游戏开发,用 Lua 开发可以专注于游戏逻辑的实现,另外一方面可以实现热更新:而且 lua 是一个 ...
- Lua中的metatable详解
转自:http://www.jb51.net/article/56690.htm Lua 中 metatable 是一个普通的 table,但其主要有以下几个功能: 1.定义算术操作符和关系操作符的行 ...
- Lua中调用C函数(lua-5.2.3)
Lua能够调用C函数的能力将极大的提高Lua的可扩展性和可用性. 对于有些和操作系统相关的功能,或者是对效率要求较高的模块,我们全然能够通过C函数来实现,之后再通过Lua调用指定的C函数. 对于那些可 ...
- <转> lua: userdata的metatable使用
1 如何封装c++的指针 对于c++对象的lua包装,我们可以使用 template<typename T> struct luaUserdataWrapper { luaUserdat ...
- Unity3D热更新之LuaFramework篇[05]--Lua脚本调用c#以及如何在Lua中使用Dotween
在上一篇文章 Unity3D热更新之LuaFramework篇[04]--自定义UI监听方法 中,我对LuaBehaviour脚本进行了扩展,添加了两个新的UI监听方法,也提到最好能单写一个脚本处理此 ...
- 原生实现C#和Lua相互调用-Unity3D可用
引言 本篇简单介绍如何在C#中执行Lua脚本,传递数据到Lua中使用,以及Lua中调用C#导出的方法等.在Unity中开发测试,并打IL2CPP的Android包在模拟器上运行通过.Lua版本 ...
随机推荐
- Could not create SSL connection through proxy serve-svn
RA layer request failedsvn: Unable to connect to a repository at URL xxxxxx 最后:Could not create SSL ...
- GPG终极指南(加密/签名)
我们平时都听过非对称加密,公钥和私钥,签名验证,但这些证书都是怎么得到的呢?本篇文章会解答这些问题. 背景介绍 加密的一个简单但又实用的任务就是发送加密电子邮件.多年来,为电子邮件进行加密的标准一直是 ...
- 【Reading Note】算法读书杂记
1 排序 排序基本信息 稳定性:排序前大的数在排序后,大的数依然保持不变就是稳定排序,反之不稳定 内外排序:根据待排序的记录是否放在内存里面区分的.诸如:插入排序(直接插入&希尔).交换排序( ...
- ZKWeb网页框架1.2正式发布
发行日志 https://github.com/zkweb-framework/ZKWeb/blob/master/ReleaseNotes/ReleaseNote.1.2.md 主要改动 更新 ZK ...
- Java FtpClient 实现文件上传服务
一.Ubuntu 安装 Vsftpd 服务 1.安装 sudo apt-get install vsftpd 2.添加用户(uftp) sudo useradd -d /home/uftp -s /b ...
- 【JS基础】循环
for 循环的语法: for (语句 1; 语句 2; 语句 3) { 被执行的代码块 } 语句 1 在循环(代码块)开始前执行 语句 2 定义运行循环(代码块)的条件 语句 3 在循环(代码块)已被 ...
- BPM配置故事之案例11-操作外部数据源
小明:可以获取ERP数据了-- 老李:哦,这么快?小伙子,我非常看好你,来来,别急着走,再陪我聊会-- 小明:--您老人家不是又要改流程吧? 老李:没有没有,哎嘿嘿嘿,我们这不都是为公司效率着想嘛,这 ...
- Atitit.cto 与技术总监的区别
Atitit.cto 与技术总监的区别 1. 核心区别1 2. Cto主要职责1 3. 如何提升到cto1 4. CTO五种基本的必备素质:2 5. 2 1. 核心区别 技术总监(Chief Tech ...
- 排序算法----基数排序(RadixSort(L))单链表智能版本
转载http://blog.csdn.net/Shayabean_/article/details/44885917博客 先说说基数排序的思想: 基数排序是非比较型的排序算法,其原理是将整数按位数切割 ...
- tg2015 信息传递 (洛谷p2661)
题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...