cocos2d-x 2.2.0 如何在lua中注册回调函数给C++

时间:2022-03-07 22:33:20

cocos2d-x内部使用tolua进行lua绑定,但是引擎并没有提供一个通用的接口让我们可以把一个lua函数注册给C++层面的回调事件。
翻看引擎的lua绑定代码,我们可以仿照引擎中的方法来做。
值得吐槽的是,这套流程在开发中几乎是不可避免的,而cocos2d-x竟然不把它作为一个公用接口暴露给开发者,而需要我自己动手,真是无奈。


下面以一个简单的消息分发类为例子,演示如何完成这一工作。

MessageDispatcher.h

class MessageDispather
{
public:
static MessageDispather* sharedDispather(); public:
void invokeLuaCallbackFunction(int msgId, const char* text);
void registerScriptHandler(int nHandler); private:
int mLuaHandlerId;
};

MessageDispatcher.cpp

#include "CCLuaEngine.h"

MessageDispather* sharedDispather()
{
static MessageDispather* instance = NULL;
if(instance == NULL) instance = new MessageDispather();
return instance;
} void MessageDispather::invokeLuaCallbackFunction(int msgId, const char* text)
{
if(mScriptHandler > 0)
{
CCLuaStack* stack = CCLuaEngine::defaultEngine()->getLuaStack();
stack->pushInt(msgId);
stack->pushString(text);
stack->executeFunctionByHandler(mScriptHandler, 2);
stack->clean();
}
} void MessageDispather::registerScriptHandler(int nHandler)
{
mLuaHandlerId = nHandler;
}

说明

#include "CCLuaEngine.h"
这个头文件来自cocos2d-x\scripting\lua\cocos2dx_support
整个文件夹里的内容是cocos2d-x引擎做lua绑定时封装的一些工具类。
你需要在你的项目中添加这个目录的include搜索路径。

void registerScriptHandler(int nHandler)
这个函数需要暴露给lua。
在lua中调用这个函数,参数nHandler的位置传进去一个lua函数,就能够在C++这边得到一个nHandler的整数句柄值。
之后任何时间如果想要在C++中调用刚刚注册的lua回调函数,需要以这个整数值来指代那个函数。

void invokeLuaCallbackFunction(int msgId, const char* text)
在C++用调用此函数,我们期待它会调用到一个在lua中定义的回调函数。
具体这个函数里的实现是什么意思,如果你对lua c api有一定了解的话应该很容易能看懂,我就不再做解释。

用于tolua的pkg文件

class MessageDispather
{
static MessageDispather* sharedDispather();
void registerScriptHandler(LUA_FUNCTION nHandler);
};

在lua中使用MessageDispatcher

local function onMessage(msgId, text)
print(msgId, text)
end
MessageDispatcher:sharedDispatcher():registerScriptHandler(onMessage)

万事大吉。。。。。才怪!

有没有发现我们的pkg文件中有一个类型是LUA_FUNCTION??
对,因为这个参数在lua中应该传入一个函数,而到了C++这边我们拿到的却是一个int。
这并不是tolua的缺省行为,而是cocos2d-x针对这种情况做的一个特殊处理。
翻看cocos2d-x的tolua绑定流程,我们可以发现build.bat中的内容是这样的:
tolua++ -L basic.lua -o "../../scripting/lua/cocos2dx_support/LuaCocos2d.cpp" Cocos2d.pkg
这里basic.lua是一些额外的逻辑,其中处理LUA_FUNCTION类型的逻辑也在里面。

那么我们可以照猫画虎,请创建这样一个lua文件:

_is_functions = _is_functions or {}
_to_functions = _to_functions or {} -- register LUA_FUNCTION, LUA_TABLE, LUA_HANDLE type
_to_functions["LUA_FUNCTION"] = "toluafix_ref_function"
_is_functions["LUA_FUNCTION"] = "toluafix_isfunction"
_to_functions["LUA_TABLE"] = "toluafix_totable"
_is_functions["LUA_TABLE"] = "toluafix_istable" local toWrite = {}
local currentString = ''
local out
local WRITE, OUTPUT = write, output function output(s)
out = _OUTPUT
output = OUTPUT -- restore
output(s)
end function write(a)
if out == _OUTPUT then
currentString = currentString .. a
if string.sub(currentString,-1) == '\n' then
toWrite[#toWrite+1] = currentString
currentString = ''
end
else
WRITE(a)
end
end function post_output_hook(package)
local result = table.concat(toWrite)
local function replace(pattern, replacement)
local k = 0
local nxt, currentString = 1, ''
repeat
local s, e = string.find(result, pattern, nxt, true)
if e then
currentString = currentString .. string.sub(result, nxt, s-1) .. replacement
nxt = e + 1
k = k + 1
end
until not e
result = currentString..string.sub(result, nxt)
if k == 0 then print('Pattern not replaced', pattern) end
end replace([[*((LUA_FUNCTION*)]], [[(]])
replace([[tolua_usertype(tolua_S,"LUA_FUNCTION");]], [[]]) WRITE(result)
end

然后在你执行tolua++的时候把这个文件作为-L参数传进去就可以了。

应该真的万事大吉了。

cocos2d-x 2.2.0 如何在lua中注册回调函数给C++的更多相关文章

  1. cocos2d-x 2.2.0 怎样在lua中注冊回调函数给C++

    cocos2d-x内部使用tolua进行lua绑定.可是引擎并没有提供一个通用的接口让我们能够把一个lua函数注冊给C++层面的回调事件. 翻看引擎的lua绑定代码,我们能够仿照引擎中的方法来做. 值 ...

  2. 【转载】如何在 C#中访问 JavaScript函数?

    如何在 C#中访问 JavaScript函数? 时间:13-10-17 栏目:Unity3D教程 作者:zqcyou 评论:0     如何在 C#中访问 JavaScript函数?答案如下:c#代码 ...

  3. iis如何在dos中注册

    iis如何在dos中注册   2009-09-23 08:13 提问者采纳   cd \cd c:\windows\microsoft.net\framework\v2.0.50727aspnet_r ...

  4. lua中调用C++函数

    lua中调用C++函数 我们产品中提供了很多lua-C API给用户在lua中调用,之前一直没用深究其实现原理,只是根据已有的代码在编码.显然这不是一个好的习惯,没用达到知其所以然的目的. 一.基本原 ...

  5. ASP.NET CORE MVC 2.0 如何在Filter中使用依赖注入来读取AppSettings,及.NET Core控制台项目中读取AppSettings

    问: ASP.NET CORE MVC 如何在Filter中使用依赖注入来读取AppSettings 答: Dependency injection is possible in filters as ...

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

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

  7. Xcode中c++&Object-C混编,详细介绍如何在cocos2dx中访问object函数以及Apple Api

    转自:http://www.himigame.com/iphone-cocos2dx/743.html Cocos2dx系列博文的上一篇详细介绍了如何在Xcode中利用jni调用Android的Jav ...

  8. Lua中调用C函数

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

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

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

随机推荐

  1. Nginx的启动脚本(Centos)

    vim /etc/init.d/nginxservice nginx start #!/bin/sh # chkconfig: 2345 85 15 # description:Nginx Serve ...

  2. 【Android学习】android布局中几个距离单位的区别:px、dp、sp

    一.px 像素,我们经常说的400*800这种的就是像素,这个比较好理解. 二.dp 要理解dp,首先要先引入dpi这个概念,dpi全称是dots per inch,对角线每英寸的像素点的个数,所以, ...

  3. C# 集合与泛型

    一.古典集合方式 在C#2.0的时候集合主要通过两种方式实现: 1.使用ArrayList实现 新建ArrayList,然后将所有对象放入该数组中,简单直接,但缺点是该数组什么类型的元素都能接收,在实 ...

  4. 节点插入--对比jQuery和JavaScript方法(一)

    二.插入元素: 1 <div> 2 <p>面朝大海,春暖花开</p> 3 </div> (一).jQuery方法 1.在节点内部插入: 方法 说明 ap ...

  5. WPF中的三维空间&lpar;2&rpar;

    原文:WPF中的三维空间(2) 2.10.3 三维对象操作 1.在二维平面空间移动.缩放.旋转Viewport3D控件对象         图2-196 选中Viewport3D控件对象      图 ...

  6. 201521123105 第8周Java学习总结

    1.本周学习总结 1.1思维导图 2. 书面作业 本次作业题集集合 1.List中指定元素的删除(题目4-1) 1.1 实验总结 1.删除元素的时候从最后一个元素开始,避免删除元素后位置发生变化而导致 ...

  7. jquery UI autocomplete当输入框焦点聚焦时自动弹出跟随下拉框

    $("#search").autocomplete({ minLength: 0, source: function(request,response){ // request对象 ...

  8. robotframework安装及入门指南

    将很久之前自己在本地记录的一些笔记发表到随笔来,希望能够帮到一些童鞋~ robotframework安装及入门指南 本文主要介绍robotframework在windows环境的安装过程! 安装步骤 ...

  9. C&num;多线程之异步编程

    c#中异步编程,主要有两种方法: 1.委托的异步调用: 2.Task的await,async (c# 4.5) 我们来看例子: /// <summary> /// 异步保存网页,url:网 ...

  10. 单点登录SSO:图示和讲解

    目录 概述 示例运行效果动画 跨域Web SSO时序图 代码截图 几个基本概念 涉及的站点和页面 重点理解:单点登录的核心步骤 敢说最准确的单点登录图示,因为: 我严格对照所画时序图的每个步骤,开发了 ...