事情的经过

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

    一.引言 最近做一个智慧城市项目,项目中需要图表和报表进行数据分析,从网上找了很多,最后找到了百度开放的echarts,一个很强大的插件. 二.介绍 ECharts,缩写来自Enterprise Ch ...

  2. Android 几种消息推送方案总结

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6241354.html 首先看一张国内Top500 Android应用中它们用到的第三方推送以及所占数量: 现 ...

  3. Java 为值传递而不是引用传递

    ——reference Java is Pass by Value and Not Pass by Reference 其实这个问题是一个非常初级的问题,相关的概念初学者早已掌握,但是时间长了还是容易 ...

  4. 【转】java通用URL接口地址调用方式GET和POST方式

    java通用URL接口地址调用方式GET和POST方式,包括建立请求和设置请求头部信息等等......... import java.io.ByteArrayOutputStream; import ...

  5. TCP三次握手图解

  6. spring boot1

    spring boot 玩转spring boot--快速开始   开发环境: IED环境:Eclipse JDK版本:1.8 maven版本:3.3.9 一.创建一个spring boot的mcv ...

  7. sublime text 3 + python配置,完整搭建及常用插件安装

    四年的时间,一直使用EmEditor编辑器进行Python开发,之前是做面向过程,只需要将一个单独的py文件维护好即可,用着也挺顺手,但是最近在做面向对象的开发,不同的py文件中相互关联较多,感觉单纯 ...

  8. ENode 2.8 最新架构图简介

    ENode架构图 什么是ENode ENode是一个.NET平台下,纯C#开发的,基于DDD,CQRS,ES,EDA,In-Memory架构风格的,可以帮助开发者开发高并发.高吞吐.可伸缩.可扩展的应 ...

  9. nfs 笔记 2

    http://woxihuanpes.blog.163.com/blog/static/12423219820097139145238/ http://blog.csdn.net/willvc123/ ...

  10. HTML中的拖拉框----在路上(29)

    拖拽框---当鼠标按在指定的区域才可进行拖拽 思想:只有当鼠标是按在一个大div里的小div才可拖拽,其他不可:拖拽框有多种方法,这里以其中一种分享:下面使我自己写的demo,简单有效. <!D ...