zoukankan      html  css  js  c++  java
  • cocos2d-x 3.1 集成 云风pbc

    cocos2d-x 3.x版本号变动比較大,从改用cmake管理整个项目,到使用python集成一体化的项目工具。

    这些都是我喜欢的。我能够非常easy的在我的ubuntu上面搭建好开发环境,并且根本就不用考虑IDE的事情,sublime-text or emacs足矣。唯一须要自己动手的就是制作一个比較好的调试工具。我是使用lua+cplusplus开发,所以调试就比較的难受,临时仅仅能这样,后面考虑自己实现一个远程lua调试工具。

    触控有公布一款IDE,但是眼下没有linux平台的版本号。我想以后也不会做的,所以就干脆胡忽略了吧。以下就说一下怎样在cocos2d-x 3.1里面集成pbc吧。

    网上有关于怎样在quick-cocos2dx里面集成pbc的,只是quick和cocos2d-x的lua集成方式不一样,并且3.x的版本号在安卓平台使用的是luajit,只是在开发人员方面还是和lua一样。这仅仅是为了提高效率。

    能够简单的看一下pbc中的lua binding以下的makefile,也是能够使用luajit的。假设对luajit感兴趣,那么就自己去搜罗吧。网上的这些关于集成pbc的文章,我有粗略的看过一些,结合cocos2d-x 3.x的情况,參考意义并不大,以下我也会给出我自己的做法。

    我大三的时候写过一篇关于怎样在cocos2d-x中集成luasocket的文章,应该也算是比較早的了。只是。那篇文章的做法。在如今看来的确不是什么好方法,不值得推荐。

    cocos2dx从2.x的某个版本号就加入了自己的lua loader,用来载入lua engine执行的脚本,详细可參考Cocos2dxLuaLoader.cpp/.h文件里的函数。

    复制代码
     1  int cocos2dx_lua_loader(lua_State *L)
     2     {
     3         std::string filename(luaL_checkstring(L, 1));
     4         size_t pos = filename.rfind(".lua");
     5         if (pos != std::string::npos)
     6         {
     7             filename = filename.substr(0, pos);
     8         }
     9         
    10         pos = filename.find_first_of(".");
    11         while (pos != std::string::npos)
    12         {
    13             filename.replace(pos, 1, "/");
    14             pos = filename.find_first_of(".");
    15         }
    16         filename.append(".lua");
    17         
    18         Data data = FileUtils::getInstance()->getDataFromFile(filename);
    19         
    20         if (!data.isNull())
    21         {
    22             if (luaL_loadbuffer(L, (char*)data.getBytes(), data.getSize(), filename.c_str()) != 0)
    23             {
    24                 luaL_error(L, "error loading module %s from file %s :
    	%s",
    25                     lua_tostring(L, 1), filename.c_str(), lua_tostring(L, -1));
    26             }
    27         }
    28         else
    29         {
    30             log("can not get file data of %s", filename.c_str());
    31         }
    32         
    33         return 1;
    34     }
    复制代码

    假设想要实现对自己项目的lua脚本进行解密或者是解压缩处理,都能够在这里下一点功夫。会有不错的收获,这部分我在后面也会做。只是还在写加密算法中,还要再等等。 - -

    或许我这里给出的函数仅仅是个開始。准确的说应该是个错误的開始。不要尝试从这里思考。

    为什么? 由于cocos2d-x改动了lua的文件载入器。

    详细的原因是lua在5.1版本号以后完好了管理机制。

    採用统一的require载入,这也不难在cocos2d-x里面看出来。能够随便看看Lua引擎入口载入运行的函数,例如以下:(CCLuaStack.cpp)

    复制代码
     1 int LuaStack::executeScriptFile(const char* filename)
     2 {
     3 #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
     4     std::string code("require "");
     5     code.append(filename);
     6     code.append(""");
     7     return executeString(code.c_str());
     8 #else
     9     std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename);
    10     ++_callFromLua;
    11     int nRet = luaL_dofile(_state, fullPath.c_str());
    12     --_callFromLua;
    13     CC_ASSERT(_callFromLua >= 0);
    14     // lua_gc(_state, LUA_GCCOLLECT, 0);
    15     
    16     if (nRet != 0)
    17     {
    18         CCLOG("[LUA ERROR] %s", lua_tostring(_state, -1));
    19         lua_pop(_state, 1);
    20         return nRet;
    21     }
    22     return 0;
    23 #endif
    24 }
    复制代码

    假设你须要写自己的脚本资源管理模块,那么这里就须要注意了。在android和其它平台处理的时候有明显的不同。不过不过在入口的不同,在兴许的require载入中都是一样的。由于在注冊

    lua loader(也就是上面的cocos2dx_lua_loader)是一样的。

    - - 当作一个友善的提示吧。然而lua本身提供的lua loader有四个,用于载入,在Lua源代码下的loadlib.c中能够找到:

    1 static const lua_CFunction loaders[] =
    2   {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};

    相应luajit中也是能够找到的.源代码在luajit源代码文件夹下的lib_package.c中:

    复制代码
    1 static const lua_CFunction package_loaders[] =
    2 {
    3   lj_cf_package_loader_preload,
    4   lj_cf_package_loader_lua,
    5   lj_cf_package_loader_c,
    6   lj_cf_package_loader_croot,
    7   NULL
    8 };
    复制代码

    经过cocos2d-x改动loader之后,lua在载入c lib的时候就有问题了,载入不到。

    只是。还是能够通过改动lua的环境表来做到载入pbc。详细做法例如以下,改动lua_extension.c:

    复制代码
     1 #include "pbc-master/src/pbc-lua.h" //add
     2 
     3 static luaL_Reg luax_exts[] = {
     4     {"socket.core", luaopen_socket_core},
     5     {"mime.core", luaopen_mime_core},
     6     {"protobuf.c", luaopen_protobuf_c}, // add
     7     {NULL, NULL}
     8 };
     9 
    10 void luaopen_lua_extensions(lua_State *L)
    11 {
    12     // load extensions
    13     luaL_Reg* lib = luax_exts;
    14     lua_getglobal(L, "package");
    15     lua_getfield(L, -1, "preload");
    16     for (; lib->func; lib++)
    17     {
    18         lua_pushcfunction(L, lib->func);
    19         lua_setfield(L, -2, lib->name);
    20     }
    21     lua_pop(L, 2);
    22 }
    复制代码

    将下载的pbc源代码(假设是http下载的话那应该是pbc-master,假设是git clone的话那就是pbc)放到coco/lua文件夹以下去,将binding以下的pbc-lua.c复制到src文件夹以下。将pbc.h也相同拷贝过去,

    然后在创建一个pbc-lua.h文件,内容就是luaopen_protobuf_c的函数声明,例如以下:

    复制代码
     1 #ifndef PBC_LUA_H
     2 #define PBC_LUA_H
     3 
     4 #ifdef __cplusplus
     5 extern "C" {
     6 #endif
     7 
     8 extern int luaopen_protobuf_c(lua_State *L);    
     9 
    10 #ifdef __cplusplus    
    11 }
    12 #endif
    13 
    14 #endif/* PBC_LUA_H */
    复制代码

    因为目标平台是安卓,所以以下就去改动ndk的Android.mk文件。目标就是coco/scripting/lua-bindings以下的Android.mk文件: 改动的部分例如以下:

    复制代码
     1 LOCAL_SRC_FILES := manual/CCLuaBridge.cpp 
     2           manual/CCLuaEngine.cpp 
     3           manual/CCLuaStack.cpp 
     4           manual/lua_debugger.c 
     5           manual/CCLuaValue.cpp 
     6           manual/Cocos2dxLuaLoader.cpp 
     7           manual/CCBProxy.cpp 
     8           manual/Lua_web_socket.cpp 
     9           manual/LuaOpengl.cpp 
    10           manual/LuaScriptHandlerMgr.cpp 
    11           manual/LuaBasicConversions.cpp 
    12           manual/LuaSkeletonAnimation.cpp 
    13           manual/lua_cocos2dx_manual.cpp 
    14           manual/lua_cocos2dx_extension_manual.cpp 
    15           manual/lua_cocos2dx_coco_studio_manual.cpp 
    16           manual/lua_cocos2dx_ui_manual.cpp 
    17           manual/lua_cocos2dx_spine_manual.cpp 
    18           manual/lua_cocos2dx_physics_manual.cpp 
    19           manual/lua_cocos2dx_deprecated.cpp 
    20           manual/lua_xml_http_request.cpp 
    21           manual/platform/android/CCLuaJavaBridge.cpp 
    22           manual/platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge.cpp 
    23           manual/tolua_fix.cpp 
    24           manual/lua_extensions.c 
    25           auto/lua_cocos2dx_auto.cpp 
    26           auto/lua_cocos2dx_extension_auto.cpp 
    27           auto/lua_cocos2dx_studio_auto.cpp 
    28           auto/lua_cocos2dx_ui_auto.cpp 
    29           auto/lua_cocos2dx_spine_auto.cpp 
    30           auto/lua_cocos2dx_physics_auto.cpp 
    31           ../../../external/lua/tolua/tolua_event.c 
    32           ../../../external/lua/tolua/tolua_is.c 
    33           ../../../external/lua/tolua/tolua_map.c 
    34           ../../../external/lua/tolua/tolua_push.c 
    35           ../../../external/lua/tolua/tolua_to.c 
    36           ../../../external/lua/luasocket/auxiliar.c 
    37           ../../../external/lua/luasocket/buffer.c 
    38           ../../../external/lua/luasocket/except.c 
    39           ../../../external/lua/luasocket/inet.c 
    40           ../../../external/lua/luasocket/io.c 
    41           ../../../external/lua/luasocket/luasocket.c 
    42           ../../../external/lua/luasocket/mime.c 
    43           ../../../external/lua/luasocket/options.c 
    44           ../../../external/lua/luasocket/select.c 
    45           ../../../external/lua/luasocket/serial.c 
    46           ../../../external/lua/luasocket/tcp.c 
    47           ../../../external/lua/luasocket/timeout.c 
    48           ../../../external/lua/luasocket/udp.c 
    49           ../../../external/lua/luasocket/unix.c 
    50           ../../../external/lua/luasocket/usocket.c 
    51           ../../../external/lua/pbc-master/src/alloc.c     -- begin
    52           ../../../external/lua/pbc-master/src/array.c 
    53           ../../../external/lua/pbc-master/src/bootstrap.c 
    54           ../../../external/lua/pbc-master/src/context.c 
    55           ../../../external/lua/pbc-master/src/decode.c 
    56           ../../../external/lua/pbc-master/src/map.c 
    57           ../../../external/lua/pbc-master/src/pattern.c 
    58           ../../../external/lua/pbc-master/src/proto.c 
    59           ../../../external/lua/pbc-master/src/register.c 
    60           ../../../external/lua/pbc-master/src/rmessage.c 
    61           ../../../external/lua/pbc-master/src/stringpool.c 
    62           ../../../external/lua/pbc-master/src/varint.c 
    63           ../../../external/lua/pbc-master/src/wmessage.c 
    64           ../../../external/lua/pbc-master/src/pbc-lua.c   -- end
    复制代码

    之后就不须要不论什么的改动了。也不须要在c++代码部分手动去载入pbc的库,由于一切都已经昨晚了。能够非常easy的看出来,这样的做法的优点。PS:最后别忘记将protobuf.lua复制到你的src或者是res以下,都是能够的,这个就不须要解释了。

    測试是我将addressbook.pb复制到src文件夹以下,在AppDelegate.cpp中加入了比較简单的拷贝代码,将addressbook.pb复制到writablepath,原因就是后面我使用了lua io库去读pb文件。这也是直接參考pbc中的小样例写的,假设有更好的做法请告诉我。谢谢。

    复制代码
    1  ssize_t __len = 0;
    2     auto writablepath = FileUtils::getInstance()->getWritablePath()+"addressbook.pb";
    3     unsigned char *data = FileUtils::getInstance()->getFileData("assets/src/addressbook.pb","r",&__len);
    4 
    5     FILE *fp = fopen(writablepath.c_str(),"w");
    6     fwrite(data,sizeof(char),__len,fp);
    7     fclose(fp);
    8     delete[] data;
    9     data = NULL;
    复制代码

    以下我给出lua部分的測试代码,实际执行是通过的,我的环境是ubuntu 14.04 x64 + ndk r9 + android

    复制代码
     1     local tf = cc.Label:create()
     2         tf:setString(package.loaded)
     3 
     4         local writablepath = cc.FileUtils:getInstance():getWritablePath()
     5 
     6         local addr = io.open(writablepath .. "addressbook.pb", "rb")
     7         local buffer = addr:read "*a"
     8         addr:close()
     9         protobuf.register(buffer)
    10 
    11         local t = protobuf.decode("google.protobuf.FileDescriptorSet", buffer)
    12         local proto = t.file[1]
    13 
    14         tf:setString(proto.name .. " " .. proto.package)
    15 
    16 
    17         local addressbook = {
    18                 name = "Alice",
    19                 id = 12345,
    20                 phone = {
    21                 { number = "1301234567" },
    22                 { number = "87654321", type = "WORK" },
    23             }
    24         }
    25 
    26         local code = protobuf.encode("tutorial.Person", addressbook)
    27 
    28         local decode = protobuf.decode("tutorial.Person" , code)
    29 
    30         tf:setString(decode.name .. " | " .. decode.id)
    复制代码

    我使用FileUtils:getInstance():getFileData无法获取数据,所以也就改为在C++那边拷贝,知道这部分怎样使用的能够告诉我。先谢过。

    pbc lua binding 文摘:http://blog.csdn.net/kaitiren/article/details/28865725


  • 相关阅读:
    Android 11 的5个新安全和隐私功能,不更新会面临被黑客入侵风险
    SSL / TLS新加密漏洞,黑客是这样读取敏感数据,看看修复方法!
    蓝牙新漏洞,黑客可以轻松控制你的手机,全球数亿台设备受影响
    Visa信用卡漏洞,新的PIN验证黑客可绕过,并进行非接触式付款
    思科是如何遭黑客入侵?原因:XSS缺陷到RCE缺陷
    WhatsApp现神秘漏洞,黑客可远程查看聊天记录
    郭盛华:免受网络黑客攻击的5个技巧
    Apache服务器现3个致命漏洞,黑客可远程监听
    centos 下安装python3 的MySQLdb
    MySQL创建用户与授权及删除
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5184056.html
Copyright © 2011-2022 走看看