cocos2d-x 2.2.0 怎样在lua中注冊回调函数给C++
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有一定了解的话应该非常easy能看懂,我就不再做解释。
用于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++的更多相关文章
- cocos2d-x 2.2.0 如何在lua中注册回调函数给C++
cocos2d-x内部使用tolua进行lua绑定,但是引擎并没有提供一个通用的接口让我们可以把一个lua函数注册给C++层面的回调事件.翻看引擎的lua绑定代码,我们可以仿照引擎中的方法来做.值得吐 ...
- 【Cocos2d-x 3.0 基础系列一】 各类回调函数写法汇总
一.button回调 1. Lambda 表达式,C++11 Lambda 赋予了Cocos2d-x 3.0创建回调函数的灵活性. auto itemNor = Sprite::create(&quo ...
- EXTJS4.0 form 表单提交 后 回调函数 不响应的问题
在提交表单后,应返回一个 JSON 至少要包含{success:true} 否则,EXT 不知道是否成功,没有响应. {success:true,msg:'成功',Url:'http://www.ba ...
- Cocos2d-x3.0下一个 Lua与C++打电话给对方
这里谈下Lua与C++如何实现相互通话 原来的连接:http://blog.csdn.net/qqmcy/article/details/26052771 DJLCData.h 实现类 // // D ...
- php7.0支持调用lua脚本
需求前瞻: 最近因需求,需要支持php调用现有的Lua代码,可以减少php的代码量,同时在维护上也比较方便,不会照成需求变更,需要同时修改两份代码 第一步:安装php7.0及以上版本,此处安装方法就略 ...
- Lua中调用C函数
Lua利用一个虚拟的堆栈来给C传递值或从C获取值.每当Lua调用C函数,都会获得一个新的堆栈,该堆栈初始包含所有的调用C函数所需要的参数值(Lua传给C函数的调用实参),并且C函数执行完毕后,会把返回 ...
- lua堆栈操作常用函数学习二
/* ** basic stack manipulation */ LUA_API int <strong> (lua_gettop) (lua_State *L); </str ...
- Lua中调用C函数(lua-5.2.3)
Lua能够调用C函数的能力将极大的提高Lua的可扩展性和可用性. 对于有些和操作系统相关的功能,或者是对效率要求较高的模块,我们全然能够通过C函数来实现,之后再通过Lua调用指定的C函数. 对于那些可 ...
- Lua调用C,C++函数案例
该程序主要是C++与Lua之间的相互调用示例.执行内容:(1)新建一个lua_State(2)打开常用库,如io,os,table,string等(3)注册C函数(4)导入程序所在目录下所有*.lua ...
随机推荐
- crontab执行脚本和手动执行脚本输出结果不一致的问题处理
背景:huskiesir最近用公司给分配的账户写了脚本去检测某应用状态并发送到企业邮箱,写完脚本之后去执行了一下,发现效果还不错,在邮箱显示效果如下: 10.11.116.6 检查结果OK,检查时间 ...
- (转)RestFul 无状态的一点认识
今天早上在Yahoo的邮件列表里看到一篇颇有意思的讨论,标题为RESTful vs. unRESTful: Session IDs and Authentication(51CTO编者注:意为REST ...
- POJ 2175 Evacuation Plan
Evacuation Plan Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Origina ...
- Linux修改Linux默认打开方式
从总体上讲 /etc/gnome/defaults.list 保存了全局的打开方式 /.local/share/applications/mimeapps.list 保存了个人的打开方式当两着不一致是 ...
- 洛谷 P2049 魔术棋子
P2049 魔术棋子 题目描述 在一个M*N的魔术棋盘中,每个格子中均有一个整数,当棋子走进这个格子中,则此棋子上的数会被乘以此格子中的数.一个棋子从左上角走到右下角,只能向右或向下行动,请问此棋子走 ...
- 对于树的序列化,用了stream,很好
https://leetcode.com/problems/serialize-and-deserialize-binary-tree/?tab=Description 下面这个解法里面的C++部分很 ...
- 为什么不能往Android的Application对象里存储数据
在一个App里面总有一些数据需要在多个地方用到.这些数据可能是一个 session token,一次费时计算的结果等.通常为了避免activity之间传递对象的开销 ,这些数据一般都会保存到持久化存储 ...
- iOS RegexKitLite 提取匹配的内容
使用RegexKitLite正则表达式需要以下工作: 1.RegexKitLite官方网址(内含使用教程):http://regexkit.sourceforge.net/RegexK ...
- 【数据压缩】JPEG标准与原理解析
转载请注明出处:http://blog.csdn.net/luoshixian099/article/details/50392230 CSDN-勿在浮沙筑高台 为了满足不同应用的需求,JPEG标准包 ...
- [JZOJ4272] [NOIP2015模拟10.28B组] 序章-弗兰德的秘密 解题报告(树形DP)
Description 背景介绍弗兰德,我不知道这个地方对我意味着什么.这里是一切开始的地方.3年前,还是个什么都没见过的少年,来到弗兰德的树下,走进了封闭的密室,扭动的封尘已久机关,在石板上知道了这 ...