#ifndef __MESSAGECENTER_H__
#define __MESSAGECENTER_H__
#include
#include
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 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
#include "MessageCenter.h"
#include "tolua_fix.h"
#include "LuaBasicConversions.h"
#include
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include
#include
#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, 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 >= 1
tolua_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(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 >= 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;
}
#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;
}
#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, "%s has wrong number of arguments: %d, was expecting %d \n", luaFunctionString.c_str(),argc, 1);}
return 0;
}
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;
}
/****************************************************************************
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("否", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, 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);
}
}
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, 1, 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