加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-14 16:55:37 所属栏目:百科 来源:网络整理
导读:1.MessageCenter.h #ifndef __MESSAGECENTER_H__#define __MESSAGECENTER_H__#include string#include liststruct lua_State;class MessageCenter{public:MessageCenter(void);~MessageCenter(void);static MessageCenter * getInstance();static int lua_bi

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__)
#endif

using 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,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 >= 1
	tolua_Error tolua_err;
	if (!tolua_isusertable(tolua_S,1,&tolua_err))
	{
		  tolua_error(tolua_S,("#ferror in function " + functionString).c_str(),&tolua_err);
		  return 0;
	}

	parentOfFunction = (MessageCenter*)tolua_tousertype(tolua_S,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*)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 >= 1
	tolua_Error tolua_err;
	if (!tolua_isusertype(tolua_S,&tolua_err);
		  return 0;
	}
#endif

    parentOfFunction = (MessageCenter*)tolua_tousertype(tolua_S,0);

#if COCOS2D_DEBUG >= 1
    if (!parentOfFunction) 
    {
		tolua_error(tolua_S,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,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,nullptr);
        return 0;
    }
#endif
	
	argc = 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,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 Quesada
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2011      Zynga Inc.
Copyright (c) 2013-2014 Chukong Technologies Inc.
 
http://www.cocos2d-x.org

Permission is hereby granted,free of charge,to any person obtaining a copy
of this software and associated documentation files (the "Software"),to deal
in the Software without restriction,including without limitation the rights
to use,copy,modify,merge,publish,distribute,sublicense,and/or sell
copies of the Software,and to permit persons to whom the Software is
furnished to do so,subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR
IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER
LIABILITY,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 IN
THE 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() {
			@Override
			public 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() {
			@Override
			public void onClick(DialogInterface dialog,int which) {
				AppActivity.this.finish();
				System.exit(0);
			}
		}).setNegativeButton("否",int which) {
			}
		}).show();
    }
    
    private static native boolean nativeIsLandScape();
    private static native boolean nativeIsDebug();
	private static native void javaSendMessageToCpp(String msg);

    @Override
	public 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.const
end


local getPackageName = function(msgArray)
    cc.showTextTips("getPackageName:" .. msgArray[2])
end
local getIpAddress = function(msgArray)
    cc.showTextTips("getIpAddress:" .. msgArray[2])
end
local 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,pos - 1);
        sub_str_tab[#sub_str_tab + 1] = sub_str;
        str = string.sub(str,pos + 1,#str);
    end

    return sub_str_tab;
end

function 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)
end

function 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")
    end
end

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读