事情的经过

我们的项目中存在好几个战斗界面,不过界面中的内容略有不同。跟同事出去吃饭的时候,他问我。我们现在的战斗界面。有很多是重复的,但是也有偶尔几个地方不太一样。我在战斗过程中驱动这些界面的时候。还需要判断一下有没有这个函数,然后在选择调用它。比较麻烦,你说怎么样才能更好的规划这件事情呢?我第一个想到的就是抽离出来一个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 的简单应用的更多相关文章

  1. 深入xLua实现原理之Lua如何调用C#

    xLua是腾讯的一个开源项目,为Unity. .Net. Mono等C#环境增加Lua脚本编程的能力.本文主要是探讨xLua下Lua调用C#的实现原理. Lua与C#数据通信机制 无论是Lua调用C# ...

  2. Lua中调用C函数

    Lua利用一个虚拟的堆栈来给C传递值或从C获取值.每当Lua调用C函数,都会获得一个新的堆栈,该堆栈初始包含所有的调用C函数所需要的参数值(Lua传给C函数的调用实参),并且C函数执行完毕后,会把返回 ...

  3. LuaJavaBridge - Lua 与 Java 互操作的简单解决方案

    http://dualface.github.io/blog/2013/01/01/call-java-from-lua/ 最近在游戏里要集成中国移动的 SDK,而这些 SDK 都是用 Java 编写 ...

  4. tolua++实现lua层调用c++技术分析

    tolua++技术分析 cocos2dx+lua 前言 一直都使用 cocos2dx + lua 进行游戏开发,用 Lua 开发可以专注于游戏逻辑的实现,另外一方面可以实现热更新:而且 lua 是一个 ...

  5. Lua中的metatable详解

    转自:http://www.jb51.net/article/56690.htm Lua 中 metatable 是一个普通的 table,但其主要有以下几个功能: 1.定义算术操作符和关系操作符的行 ...

  6. Lua中调用C函数(lua-5.2.3)

    Lua能够调用C函数的能力将极大的提高Lua的可扩展性和可用性. 对于有些和操作系统相关的功能,或者是对效率要求较高的模块,我们全然能够通过C函数来实现,之后再通过Lua调用指定的C函数. 对于那些可 ...

  7. <转> lua: userdata的metatable使用

    1 如何封装c++的指针 对于c++对象的lua包装,我们可以使用 template<typename T> struct luaUserdataWrapper {  luaUserdat ...

  8. Unity3D热更新之LuaFramework篇[05]--Lua脚本调用c#以及如何在Lua中使用Dotween

    在上一篇文章 Unity3D热更新之LuaFramework篇[04]--自定义UI监听方法 中,我对LuaBehaviour脚本进行了扩展,添加了两个新的UI监听方法,也提到最好能单写一个脚本处理此 ...

  9. 原生实现C#和Lua相互调用-Unity3D可用

    引言     本篇简单介绍如何在C#中执行Lua脚本,传递数据到Lua中使用,以及Lua中调用C#导出的方法等.在Unity中开发测试,并打IL2CPP的Android包在模拟器上运行通过.Lua版本 ...

随机推荐

  1. [APUE]文件和目录(中)

    一.link.unlink.remove和rename 一个文件可以有多个目录项指向其i节点.使用link函数可以创建一个指向现存文件连接 #include <unistd.h> int ...

  2. JavaScript动画-碰撞检测

    ▓▓▓▓▓▓ 大致介绍 碰撞检测是指在页面中有多个元素时,拖拽一个元素会出现碰撞问题,碰撞检测是以模拟拖拽和磁性吸附中的范围限定为基础的 效果:碰撞检测 ▓▓▓▓▓▓ 碰撞检测 先来看看碰撞检测的原理 ...

  3. IE8/9 JQuery.Ajax 上传文件无效

    IE8/9 JQuery.Ajax 上传文件有两个限制: 使用 JQuery.Ajax 无法上传文件(因为无法使用 FormData,FormData 是 HTML5 的一个特性,IE8/9 不支持) ...

  4. 前端性能优化的另一种方式——HTTP2.0

    最近在读一本书叫<web性能权威指南>谷歌公司高性能团队核心成员的权威之作. 一直听说HTTP2.0,对此也仅仅是耳闻,没有具体研读过,这次正好有两个篇章,分别讲HTTP1.1和HTTP2 ...

  5. 编写高质量代码:改善Java程序的151个建议(第8章:多线程和并发___建议126~128)

    建议126:适时选择不同的线程池来实现 Java的线程池实现从根本上来说只有两个:ThreadPoolExecutor类和ScheduledThreadPoolExecutor类,这两个类还是父子关系 ...

  6. java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)

    一.Condition 类 在前面我们学习与synchronized锁配合的线程等待(Object.wait)与线程通知(Object.notify),那么对于JDK1.5 的 java.util.c ...

  7. Java程序:从命令行接收多个数字,求和并输出结果

    一.设计思想:由于命令行接收的是字符串类型,因此应先将字符串类型转化为整型或其他字符型,然后利用for循环求和并输出结果 二.程序流程图: 三.源程序代码:   //王荣荣 2016/9/23     ...

  8. jQuery可自动播放动画焦点图插件Koala

    Koala是一款简单而实用的jQuery焦点图幻灯片插件,焦点图不仅可以在播放图片的时候让图片有淡入淡出的动画效果,而且图片可以自动播放.该jQuery焦点图的每一张图片都可以设置文字描述,并浮动在图 ...

  9. maven 快照

    大型应用软件一般由多个模块组成,一般它是多个团队开发同一个应用程序的不同模块,这是比较常见的场景.例如,一个团队正在对应用程序的应用程序,用户界面项目(app-ui.jar:1.0) 的前端进行开发, ...

  10. 海鑫智圣:物联网漫谈之MQTT协议

    什么是MQTT协议 MQTT(消息队列遥测传输协议)是IBM在1999年专门针对物联网等应用场景来制订的轻量级双向消息传输协议,它主要是为了解决物联网上使用到的设备的互相通信的问题,以及这些设备与后端 ...