Cocos2d-x Tutorial 之 Socket的使用(2)

来源:互联网 发布:淘宝情趣用品买家秀 编辑:程序博客网 时间:2024/06/06 07:03

本节记录下将 C++ 版本的接口,倒出到 Lua ,并在 Lua 中发送和接收消息

一、编写 cocos2dx_socket_util.ini 文件

参考Cocos2d-x Tutorial 之 如何绑定 C++ 类到 Lua

此处贴出改写完成以后的内容

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
[cocos2dx_socket_util]# the prefix to be added to the generated functions. You might or might not use this in your own# templatesprefix = cocos2dx_socket_util# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)# all classes will be embedded in that namespacetarget_namespace = android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/includeandroid_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/platform/android -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/externalcocos_flags = -DANDROIDcxxgenerator_headers = # extra arguments for clangextra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s # what headers to parseheaders = %(cocosdir)s/../runtime-src/Classes/SocketUtil.h# what classes to produce code for. You can use regular expressions here. When testing the regular# expression, it will be enclosed in "^$", like this: "^Menu*$".classes = SocketUtil# what should we skip? in the format ClassName::[function function]# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just# add a single "*" as functions. See bellow for several examples. A special class name is "*", which# will apply to all class names. This is a convenience wildcard to be able to skip similar named# functions from all classes.skip = SocketUtil::[addMsgHandler addStateHandler addMsgHandlerLua addStateHandlerLua receiveMsg socketStateChange]rename_functions = rename_classes = # for all class names, should we remove something when registering in the target VM?remove_prefix = # classes for which there will be no "parent" lookupclasses_have_no_parents = # base classes which will be skipped when their sub-classes found them.base_classes_to_skip = # classes that create no constructor# Set is special and we will use a hand-written constructorabstract_classes = # Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.script_control_cpp = no

二、编写 genbindings_socket_util.py 文件并生成绑定代码

参考Cocos2d-x Tutorial 之 如何绑定 C++ 类到 Lua

此处贴出改写完成以后的内容

1234567
...        output_dir = '%s/../runtime-src/Classes/auto' % project_root        cmd_args = {                    'cocos2dx_socket_util.ini' : ('cocos2dx_socket_util', 'lua_cocos2dx_socket_util_auto'), \                    }...

打开终端,进入到 genbindings_socket_util.py 所在目录,执行如下命令生成代码

1
./genbindings_socket_util.py

检查是否有报错,没有报错说明代码生成成功。

三、编写特殊函数的绑定代码

SocketUtil 中包含了两个特殊一点的函数,需要从 Lua 中传递一个函数的引用,到 C++ 中,需要手动绑定一下。

在 auto 文件夹所在目录 创建一个新的文件夹 manual,拷贝如下代码。

lua_cocos2dx_socket_util_manual.hpp

12345678910111213141516171819202122232425
#include "base/ccConfig.h"#ifndef __cocos2dx_socket_util_manual_h__#define __cocos2dx_socket_util_manual_h__#ifdef __cplusplusextern "C" {#endif#include "tolua++.h"#ifdef __cplusplus}#endifint register_all_cocos2dx_socket_util_manual(lua_State* tolua_S);#endif // __cocos2dx_socket_util_manual_h__

lua_cocos2dx_socket_util_manual.cpp

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
#include "lua_cocos2dx_socket_util_manual.hpp"#include "SocketUtil.h"#include "tolua_fix.h"#include "LuaBasicConversions.h"#include "CCLuaValue.h"int lua_cocos2dx_socket_util_SocketUtil_addStateHandlerLua(lua_State* tolua_S){    int argc = 0;    SocketUtil* cobj = nullptr;    bool ok  = true;#if COCOS2D_DEBUG >= 1    tolua_Error tolua_err;#endif#if COCOS2D_DEBUG >= 1    if (!tolua_isusertype(tolua_S,1,"SocketUtil",0,&tolua_err)) goto tolua_lerror;#endif    cobj = (SocketUtil*)tolua_tousertype(tolua_S,1,0);#if COCOS2D_DEBUG >= 1    if (!cobj)    {        tolua_error(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_socket_util_SocketUtil_addStateHandlerLua'", nullptr);        return 0;    }#endif    argc = lua_gettop(tolua_S)-1;    if (argc == 1)    {        LUA_FUNCTION arg0;        do {            arg0 = toluafix_ref_function(tolua_S,2,0);        } while(0)        ;        if(!ok)        {            tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_socket_util_SocketUtil_addStateHandlerLua'", nullptr);            return 0;        }        cobj->addStateHandlerLua(arg0);        return 0;    }    luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "SocketUtil:addStateHandlerLua",argc, 1);    return 0;#if COCOS2D_DEBUG >= 1    tolua_lerror:    tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_socket_util_SocketUtil_addStateHandlerLua'.",&tolua_err);#endif    return 0;}int lua_cocos2dx_socket_util_SocketUtil_addMsgHandlerLua(lua_State* tolua_S){    int argc = 0;    SocketUtil* cobj = nullptr;    bool ok  = true;#if COCOS2D_DEBUG >= 1    tolua_Error tolua_err;#endif#if COCOS2D_DEBUG >= 1    if (!tolua_isusertype(tolua_S,1,"SocketUtil",0,&tolua_err)) goto tolua_lerror;#endif    cobj = (SocketUtil*)tolua_tousertype(tolua_S,1,0);#if COCOS2D_DEBUG >= 1    if (!cobj)    {        tolua_error(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_socket_util_SocketUtil_addMsgHandlerLua'", nullptr);        return 0;    }#endif    argc = lua_gettop(tolua_S)-1;    if (argc == 1)    {        LUA_FUNCTION arg0;        do {            arg0 = toluafix_ref_function(tolua_S,2,0);        } while(0)        ;        if(!ok)        {            tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_socket_util_SocketUtil_addMsgHandlerLua'", nullptr);            return 0;        }        cobj->addMsgHandlerLua(arg0);        return 0;    }    luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "SocketUtil:addMsgHandlerLua",argc, 1);    return 0;#if COCOS2D_DEBUG >= 1    tolua_lerror:    tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_socket_util_SocketUtil_addMsgHandlerLua'.",&tolua_err);#endif    return 0;}int lua_register_cocos2dx_socket_util_SocketUtil_Manual(lua_State* tolua_S){    tolua_usertype(tolua_S,"SocketUtil");    tolua_cclass(tolua_S,"SocketUtil","SocketUtil","cc.Ref",nullptr);    tolua_beginmodule(tolua_S,"SocketUtil");        tolua_function(tolua_S,"addStateHandlerLua",lua_cocos2dx_socket_util_SocketUtil_addStateHandlerLua);        tolua_function(tolua_S,"addMsgHandlerLua",lua_cocos2dx_socket_util_SocketUtil_addMsgHandlerLua);    tolua_endmodule(tolua_S);    std::string typeName = typeid(SocketUtil).name();    g_luaType[typeName] = "SocketUtil";    g_typeCast["SocketUtil"] = "SocketUtil";    return 1;}TOLUA_API int register_all_cocos2dx_socket_util_manual(lua_State* tolua_S){    tolua_open(tolua_S);    tolua_module(tolua_S,nullptr,0);    tolua_beginmodule(tolua_S,nullptr);    lua_register_cocos2dx_socket_util_SocketUtil_Manual(tolua_S);    tolua_endmodule(tolua_S);    return 1;}

四、注册绑定函数

将 Class 目录下的 auto 和 manual 文件夹 添加到项目中,修改 AppDelegate.cpp 文件。

123456789101112
...#include "lua_cocos2dx_socket_util_auto.hpp"#include "lua_cocos2dx_socket_util_manual.hpp"...bool AppDelegate::applicationDidFinishLaunching(){    ...    register_all_cocos2dx_socket_util(stack->getLuaState());    register_all_cocos2dx_socket_util_manual(stack->getLuaState());    ...}...

五、测试

打开 src/app/scenes 下面的 MainScene.lua

添加测试代码

MainScene.lua

12345678910111213141516171819202122
function MainScene:ctor()    ...    local instance = SocketUtil:getInstance()    instance:addMsgHandlerLua(handler(self, MainScene.msgHandler))    instance:addStateHandlerLua(handler(self, MainScene.stateHandler))    instance:connectServer("127.0.0.1", 3000)    scheduler.performWithDelayGlobal(function(dt)            local str = "hello world"            instance:sendMsg({string.byte(str,1,#str)})        end, 2)    scheduler.performWithDelayGlobal(function(dt)            instance:close()        end, 4)endfunction MainScene:msgHandler(bytes)    print("msg")endfunction MainScene:stateHandler(connected)    print("state: "..tostring(connected))end

启动好服务端程序,运行,检查控制台输出

123
[LUA-print] state: true[LUA-print] msg[LUA-print] state: false

至此,SocketUtil 绑定到 Lua 完成。

–EOF–

原创粉丝点击