事情的经过

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

    开源地址:https://github.com/yuezhongxin/paste-upload-image.js 支持 Ctrl+C/Ctrl+V 上传,支持拖拽上传,也支持 QQ/微信截图上传. ...

  2. 快速了解微信小程序的使用,一个根据小程序的框架开发的todos app

    微信官方已经开放微信小程序的官方文档和开发者工具.前两天都是在看相关的新闻来了解小程序该如何开发,这两天官方的文档出来之后,赶紧翻看了几眼,重点了解了一下文档中框架与组件这两个部分,然后根据简易教程, ...

  3. VS2015常用快捷键总结

    生成解决方案 F6,生成项目Shift+F6 调试执行F5,终止调试执行Shift+F5 执行调试Ctrl+F5 查找下一个F3,查找上一个Shift+F3 附加到进程Ctrl+Alt+P,逐过程F1 ...

  4. Autofac - 属性注入

    属性注入不同于通过构造函数方式传入参数. 这里是通过注入的方式, 在类创建完毕之后, 资源释放之前, 给属性赋值. 这里, 我重新弄一些类来演示这一篇吧. public class ClassA { ...

  5. JavaScript对象和数组

    1.JavaScript中有两个非常重要的数据类型是对象和数组. 通过"."或者"[]"来访问对象属性 举例:var book = { topic:" ...

  6. 5.0 JS中引用类型介绍

    其实,在前面的"js的六大数据类型"文章中稍微说了一下引用类型.前面我们说到js中有六大数据类型(五种基本数据类型 + 一种引用类型).下面的章节中,我们将详细讲解引用类型. 1. ...

  7. 【干货分享】流程DEMO-加班与调休

    流程名: 加班.调休  业务描述: 加班: 工作日加班可以申请调休,也可以申请支付加班费.原则上都应申请调休:周末加班原则上申请调休:法定节假日加班支付加班费. 加班申请以半小时为单位. 当月加班不能 ...

  8. i++、++i 、i--、--i

    总结: i++ 先用后加, ++i先加后用: i--先用后减, --i先减后用: //int i = 1; //Console.WriteLine(i);//1 //Console.WriteLine ...

  9. SymmetricDS 快速和灵活的数据库复制

    开始谈谈开源的SymmetricDS,谈谈实际使用中,遇到的一些问题和解决办法.持续更新: SymmetricDS 快速和灵活的数据库复制 实际使用 和 埋过的坑 (一)知识篇 SymmetricDS ...

  10. [BOT]自己动手实现android 饼状图,PieGraphView,附源码解析

    本文要介绍的是一个参照手机支付宝app里面记账本功能里的"饼状图"实现的控件.通常app中可能的数据展示控件有柱状图,折线图,饼状图等,如果需要一个包含多种View控件的库,那么 ...