cocos2dx-lua编程之c++与lua通信,c++与java通信

来源:互联网 发布:最帅程序员 编辑:程序博客网 时间:2024/05/16 07:17

1. MessageCenter.h


#ifndef __MESSAGECENTER_H__#define __MESSAGECENTER_H__#include <string>#include <list>struct lua_State;class MessageCenter{public:MessageCenter(void);~MessageCenter(void);static MessageCenter * getInstance();static int  lua_bind_AllFunction(lua_State* tolua_S);void cppSendMessageToJava(const std::string & message);void addMessageToList(const std::string &message);const std::string luaGetMessageFromCpp();static const std::string classPrefix;static const std::string fullName;static const std::string className;private:static MessageCenter *m_instance;std::list<std::string> m_messageList;};int lua_cocos2dx_MessageCenter_getInstance(lua_State* tolua_S);int lua_cocos2dx_MessageCenter_luaGetMessageFromCpp(lua_State* tolua_S);int lua_cocos2dx_MessageCenter_cppSendMessageToJava(lua_State* tolua_S);//void Java_org_cocos2dx_lua_AppActivity_javaSendMessageToCpp(JNIEnv env, jobject thiz, jstring msg)#endif



2. MessageCenter.cpp

#include "MessageCenter.h"#include "tolua_fix.h"#include "LuaBasicConversions.h"#include <stdlib.h>#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)#include <jni.h>#include <android/log.h>#include "platform/android/jni/JniHelper.h"#define  LOG_TAG    "MessageCenter"#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)#endifusing namespace cocos2d;const std::string MessageCenter::classPrefix = "cp";const std::string MessageCenter::className = "MessageCenter";const std::string MessageCenter::fullName = classPrefix + "." + className;MessageCenter *MessageCenter::m_instance = NULL;MessageCenter::MessageCenter(void){m_messageList.clear();}MessageCenter::~MessageCenter(void){}MessageCenter * MessageCenter::getInstance(){if (!m_instance){m_instance = new MessageCenter();}return m_instance;}const std::string  MessageCenter::luaGetMessageFromCpp(){if(!m_messageList.empty()){const std::string message = m_messageList.front();m_messageList.pop_front();return message;}return "0";}void MessageCenter::addMessageToList(const std::string &message){m_messageList.push_back(message);}void MessageCenter::cppSendMessageToJava(const std::string & message){CCLOG("sendMessageToJava:%s", message.c_str());#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)JniMethodInfo jmi;JniHelper::getStaticMethodInfo(jmi, "org/cocos2dx/lua/AppActivity", "SendMessage", "(Ljava/lang/String;)V");jstring str = (jmi.env->NewStringUTF(message.c_str()));jmi.env->CallStaticVoidMethod(jmi.classID, jmi.methodID, str);#endif}#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)extern "C"{void Java_org_cocos2dx_lua_AppActivity_javaSendMessageToCpp(JNIEnv env, jobject thiz, jstring msg){std::string str = JniHelper::jstring2string(msg);LOGD("javaSendMessageToCpp");MessageCenter::getInstance()->addMessageToList(str);}}#endif//==============lua bind================int MessageCenter::lua_bind_AllFunction(lua_State* tolua_S){lua_getglobal(tolua_S, "_G");if (lua_istable(tolua_S,-1))//stack:...,_G,{tolua_open(tolua_S);tolua_module(tolua_S, classPrefix.c_str(), 0);tolua_beginmodule(tolua_S, classPrefix.c_str());tolua_usertype(tolua_S, MessageCenter::fullName.c_str());tolua_cclass(tolua_S, className.c_str(), MessageCenter::fullName.c_str(),"",nullptr);tolua_beginmodule(tolua_S, className.c_str());tolua_function(tolua_S, "getInstance", lua_cocos2dx_MessageCenter_getInstance);tolua_function(tolua_S, "cppSendMessageToJava", lua_cocos2dx_MessageCenter_cppSendMessageToJava);tolua_function(tolua_S, "luaGetMessageFromCpp", lua_cocos2dx_MessageCenter_luaGetMessageFromCpp);tolua_endmodule(tolua_S);g_luaType[typeid(MessageCenter).name()] = MessageCenter::fullName;g_typeCast[className] = MessageCenter::fullName;tolua_endmodule(tolua_S);}lua_pop(tolua_S, 1);return 1;}int lua_cocos2dx_MessageCenter_getInstance(lua_State* tolua_S){    int argc = 0;MessageCenter* parentOfFunction = nullptr;const std::string &functionString = "'lua_cocos2dx_MessageCenter_getInstance'";const std::string &luaFunctionString = MessageCenter::fullName + ":getInstance";#if COCOS2D_DEBUG >= 1tolua_Error tolua_err;if (!tolua_isusertable(tolua_S,1, MessageCenter::fullName.c_str(),0,&tolua_err)){  tolua_error(tolua_S, ("#ferror in function " + functionString).c_str(),&tolua_err);  return 0;}parentOfFunction = (MessageCenter*)tolua_tousertype(tolua_S,1,0); if (!parentOfFunction)     {//tolua_error(tolua_S, ("invalid 'cobj' in function " + functionString).c_str(), nullptr);        //return 0;    }#endif    argc = lua_gettop(tolua_S) - 1;    if (argc == 0)    {MessageCenter* ret = MessageCenter::getInstance();        object_to_luaval<MessageCenter>(tolua_S, MessageCenter::fullName.c_str(),(MessageCenter*)ret);        return 1;    }    else {luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n",  luaFunctionString.c_str(),argc, 1);}    return 0;}int lua_cocos2dx_MessageCenter_cppSendMessageToJava(lua_State* tolua_S){    int argc = 0;MessageCenter* parentOfFunction = nullptr;    bool ok  = true;const std::string &functionString = "'lua_cocos2dx_MessageCenter_cppSendMessageToJava'";const std::string &luaFunctionString = MessageCenter::fullName + ":cppSendMessageToJava";#if COCOS2D_DEBUG >= 1tolua_Error tolua_err;if (!tolua_isusertype(tolua_S, 1, MessageCenter::fullName.c_str(), 0, &tolua_err)){  tolua_error(tolua_S, ("#ferror in function " + functionString).c_str(),&tolua_err);  return 0;}#endif    parentOfFunction = (MessageCenter*)tolua_tousertype(tolua_S,1,0);#if COCOS2D_DEBUG >= 1    if (!parentOfFunction)     {tolua_error(tolua_S, ("invalid 'cobj' in function " + functionString).c_str(), nullptr);        return 0;    }#endif    argc = lua_gettop(tolua_S)-1;    if (argc == 1)     {        std::string arg0;ok &= luaval_to_std_string(tolua_S, 2,&arg0, luaFunctionString.c_str());        if(!ok)        {tolua_error(tolua_S,("invalid arguments in function " + functionString).c_str(), nullptr);            return 0;        }parentOfFunction->cppSendMessageToJava(arg0);        lua_settop(tolua_S, 1);        return 1;    }else{luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n",  luaFunctionString.c_str(),argc, 1);}    return 0;}int lua_cocos2dx_MessageCenter_luaGetMessageFromCpp(lua_State* tolua_S){    int argc = 0;MessageCenter* parentOfFunction = nullptr;    bool ok  = true;const std::string &functionString = "'lua_cocos2dx_MessageCenter_luaGetMessageFromCpp'";const std::string &luaFunctionString = MessageCenter::fullName + ":luaGetMessageFromCpp";#if COCOS2D_DEBUG >= 1 tolua_Error tolua_err;if (!tolua_isusertype(tolua_S, 1, MessageCenter::fullName.c_str(), 0, &tolua_err)){  tolua_error(tolua_S, ("#ferror in function " + functionString).c_str(),&tolua_err);  return 0;}#endif    parentOfFunction = (MessageCenter*)tolua_tousertype(tolua_S,1,0);#if COCOS2D_DEBUG >= 1    if (!parentOfFunction)     {tolua_error(tolua_S, ("invalid 'cobj' in function " + functionString).c_str(), nullptr);        return 0;    }#endifargc = lua_gettop(tolua_S) - 1;    if (argc == 0)     {const std::string &ret = parentOfFunction->luaGetMessageFromCpp();tolua_pushcppstring(tolua_S, ret);        return 1;    }else{luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n",  luaFunctionString.c_str(),argc, 1);}return 0;}



3. 在AppDelegate.cpp中注册MessageCenter函数

bool AppDelegate::applicationDidFinishLaunching(){    // set default FPS    Director::getInstance()->setAnimationInterval(1.0 / 60.0f);       // register lua module    auto engine = LuaEngine::getInstance();    ScriptEngineManager::getInstance()->setScriptEngine(engine);    lua_State* L = engine->getLuaStack()->getLuaState();    lua_module_register(L);register_TestLayer(L);TestClass::lua_bind_AllFunction(L);MessageCenter::lua_bind_AllFunction(L);ScreenMatchLayer::lua_bind_AllFunction(L);    // If you want to use Quick-Cocos2d-X, please uncomment below code    // register_all_quick_manual(L);    LuaStack* stack = engine->getLuaStack();    stack->setXXTEAKeyAndSign("2dxLua", strlen("2dxLua"), "XXTEA", strlen("XXTEA"));        //register custom function    //LuaStack* stack = engine->getLuaStack();    //register_custom_function(stack->getLuaState());    #if (COCOS2D_DEBUG > 0) && (CC_CODE_IDE_DEBUG_SUPPORT > 0)    // NOTE:Please don't remove this call if you want to debug with Cocos Code IDE    RuntimeEngine::getInstance()->start();    cocos2d::log("iShow!");#else    if (engine->executeScriptFile("src/main.lua"))    {        return false;    }#endif        return true;}



4. org.cocos2dx.lua.AppActivity的java文件(AppActivity.java)

/****************************************************************************Copyright (c) 2008-2010 Ricardo QuesadaCopyright (c) 2010-2012 cocos2d-x.orgCopyright (c) 2011      Zynga Inc.Copyright (c) 2013-2014 Chukong Technologies Inc. http://www.cocos2d-x.orgPermission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included inall copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS INTHE SOFTWARE.****************************************************************************/package org.cocos2dx.lua;import java.net.InetAddress;import java.net.NetworkInterface;import java.net.SocketException;import java.util.Enumeration;import java.util.ArrayList;import org.cocos2dx.lib.Cocos2dxActivity;import android.app.AlertDialog;import android.content.Context;import android.content.DialogInterface;import android.content.DialogInterface.OnClickListener;import android.content.Intent;import android.content.pm.ApplicationInfo;import android.content.pm.ActivityInfo;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.net.wifi.WifiInfo;import android.net.wifi.WifiManager;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.provider.Settings;import android.text.format.Formatter;import android.util.Log;import android.view.KeyEvent;import android.view.WindowManager;import android.widget.Toast;public class AppActivity extends Cocos2dxActivity{private static Handler handler;    static String hostIPAdress = "0.0.0.0";        @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);                if(nativeIsLandScape()) {            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);        } else {            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);        }                        final String packageName = this.getPackageName();        final String ipAddress = this.getHostIpAddress();        final String macAddress = this.getMacAddress();        handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);String message = (String) msg.obj;if(message.equals("love")){Log.i("wc", "isLove");AppActivity.javaSendMessageToCpp("2001|" + packageName);AppActivity.javaSendMessageToCpp("2002|" + ipAddress);AppActivity.javaSendMessageToCpp("2003|" + macAddress);}Log.i("wc", message);}};        //2.Set the format of window                // Check the wifi is opened when the native is debug.        if(nativeIsDebug())        {            getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);            if(!isNetworkConnected())            {                AlertDialog.Builder builder=new AlertDialog.Builder(this);                builder.setTitle("Warning");                builder.setMessage("Please open WIFI for debuging...");                builder.setPositiveButton("OK",new DialogInterface.OnClickListener() {                                        @Override                    public void onClick(DialogInterface dialog, int which) {                        startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));                        finish();                        System.exit(0);                    }                });                builder.setNegativeButton("Cancel", null);                builder.setCancelable(true);                builder.show();            }            hostIPAdress = getHostIpAddress();        }    }    private boolean isNetworkConnected() {            ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);              if (cm != null) {                  NetworkInfo networkInfo = cm.getActiveNetworkInfo();              ArrayList networkTypes = new ArrayList();            networkTypes.add(ConnectivityManager.TYPE_WIFI);            try {                networkTypes.add(ConnectivityManager.class.getDeclaredField("TYPE_ETHERNET").getInt(null));            } catch (NoSuchFieldException nsfe) {            }            catch (IllegalAccessException iae) {                throw new RuntimeException(iae);            }            if (networkInfo != null && networkTypes.contains(networkInfo.getType())) {                    return true;                  }              }              return false;          }          public String getHostIpAddress() {        WifiManager wifiMgr = (WifiManager) getSystemService(WIFI_SERVICE);        WifiInfo wifiInfo = wifiMgr.getConnectionInfo();        int ip = wifiInfo.getIpAddress();        return ((ip & 0xFF) + "." + ((ip >>>= 8) & 0xFF) + "." + ((ip >>>= 8) & 0xFF) + "." + ((ip >>>= 8) & 0xFF));    }        public static String getLocalIpAddress() {        return hostIPAdress;    }        private void exitApp(){    new AlertDialog.Builder(this).setTitle("退出").setMessage("是否退出游戏").setPositiveButton("是", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {AppActivity.this.finish();System.exit(0);}}).setNegativeButton("否", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {}}).show();    }        private static native boolean nativeIsLandScape();    private static native boolean nativeIsDebug();private static native void javaSendMessageToCpp(String msg);    @Overridepublic boolean onKeyUp(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK) {exitApp();return true;}return super.onKeyUp(keyCode, event);}            public String getMacAddress()    {    WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);         WifiInfo info = wifi.getConnectionInfo();         return info.getMacAddress();    }    public static void SendMessage(String msg) {        Message message = Message.obtain();        message.obj = msg;        AppActivity.handler.sendMessage(message);    }}

5. lua中的调用方法

Utility.lua

cc.const = function()    if cc.const == nil then        cc.const = {}        cc._const = {}        local function newIndex(t,k,v)            if not cc._const[k] then                cc._const[k] = v            else                error("尝试给 const."..k.." 赋值")            end        end        local mt = {        __newindex = newIndex,        __index = cc._const        }        setmetatable(cc.const,mt)    end    return cc.constendlocal getPackageName = function(msgArray)    cc.showTextTips("getPackageName:" .. msgArray[2])endlocal getIpAddress = function(msgArray)    cc.showTextTips("getIpAddress:" .. msgArray[2])endlocal getMacAddress = function(msgArray)    cc.showTextTips("getMacAddress:" .. msgArray[2])end cc.android = {    packageName = "",    ip = "",        mac = "",    eventList = {        ["2001"] = getPackageName,        ["2002"] = getIpAddress,        ["2003"] = getMacAddress    },}cc.zOrder = {    showTextTips = 100}function cc.splitStringWithSeparator(str, split_char)    local sub_str_tab = {};    while (true) do        local pos = string.find(str, split_char);        if (not pos) then            sub_str_tab[#sub_str_tab + 1] = str;            break;        end        local sub_str = string.sub(str, 1, pos - 1);        sub_str_tab[#sub_str_tab + 1] = sub_str;        str = string.sub(str, pos + 1, #str);    end    return sub_str_tab;endfunction cc.startListenCppMessage()     local function event_loop(dtime)         local msg = cp.MessageCenter : getInstance() : luaGetMessageFromCpp()        if msg ~= nil and msg ~= "0" then            local msgArray = cc.splitStringWithSeparator(msg, "|")            local code = msgArray[1]            if #msgArray > 0 and cc.android.eventList[code] ~= nil then                cc.android.eventList[code](msgArray)            end        end    end    cc.Director : getInstance() : getScheduler() : scheduleScriptFunc(event_loop, 0.1, false)endfunction cc.showTextTips(text)    local scene = cc.Director:getInstance() : getRunningScene()    if scene ~= nil and text ~= "" then        local function createTextBackgroundWithSize(bgSize)            local bgSprite = ccui.Scale9Sprite:create("tips/ui_bg_small.png")            bgSprite : setScale9Enabled(true)            bgSprite : setContentSize(bgSize)            bgSprite : setLocalZOrder(cc.zOrder.showTextTips)            bgSprite : setPosition(480, 320)            return bgSprite        end        local label = cc.LabelTTF:create(text, "heiti", 24)        local bgSize = cc.size(label : getContentSize().width + 40, 50)        local bgSprite = createTextBackgroundWithSize(bgSize)        scene : addChild(bgSprite)                bgSprite : addChild(label)        label : setPosition(bgSize.width / 2, bgSize.height / 2)        local actionMove = cc.Sequence:create(              cc.MoveBy:create(1.0, cc.p(0,100)),            cc.DelayTime:create(0.5),            cc.CallFunc:create(                 function ()                     bgSprite : removeFromParent()                end)        )        bgSprite : runAction(actionMove)    else        print("showTextTips error")    endend

0 0
原创粉丝点击