mirror of https://github.com/axmolengine/axmol.git
Merge branch 'develop' of https://github.com/cocos2d/cocos2d-x into developTest
This commit is contained in:
commit
faed7a3d36
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
public class Cocos2dxLuaJavaBridge
|
||||||
|
{
|
||||||
|
public static native int callLuaFunctionWithString(int luaFunctionId, String value);
|
||||||
|
public static native int callLuaGlobalFunctionWithString(String luaFunctionName, String value);
|
||||||
|
public static native int retainLuaFunction(int luaFunctionId);
|
||||||
|
public static native int releaseLuaFunction(int luaFunctionId);
|
||||||
|
}
|
|
@ -13,7 +13,8 @@ namespace ShaderTest2
|
||||||
CL(NoiseSpriteTest),
|
CL(NoiseSpriteTest),
|
||||||
CL(EdgeDetectionSpriteTest),
|
CL(EdgeDetectionSpriteTest),
|
||||||
CL(BloomSpriteTest),
|
CL(BloomSpriteTest),
|
||||||
CL(CelShadingSpriteTest)
|
CL(CelShadingSpriteTest),
|
||||||
|
CL(LensFlareSpriteTest)
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned int TEST_CASE_COUNT = sizeof(ShaderTest2::createFunctions) / sizeof(ShaderTest2::createFunctions[0]);
|
static unsigned int TEST_CASE_COUNT = sizeof(ShaderTest2::createFunctions) / sizeof(ShaderTest2::createFunctions[0]);
|
||||||
|
@ -451,6 +452,44 @@ void CelShadingSprite::setCustomUniforms()
|
||||||
getShaderProgram()->setUniformLocationWith2fv(_resolutionLoc, _resolution, 1);
|
getShaderProgram()->setUniformLocationWith2fv(_resolutionLoc, _resolution, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LensFlareSprite : public ShaderSprite, public ShaderSpriteCreator<LensFlareSprite>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LensFlareSprite();
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLfloat _resolution[2];
|
||||||
|
GLfloat _textureResolution[2];
|
||||||
|
GLuint _resolutionLoc;
|
||||||
|
GLuint _textureResolutionLoc;
|
||||||
|
protected:
|
||||||
|
virtual void buildCustomUniforms();
|
||||||
|
virtual void setCustomUniforms();
|
||||||
|
};
|
||||||
|
|
||||||
|
LensFlareSprite::LensFlareSprite()
|
||||||
|
{
|
||||||
|
_fragSourceFile = "Shaders/example_lensFlare.fsh";
|
||||||
|
}
|
||||||
|
|
||||||
|
void LensFlareSprite::buildCustomUniforms()
|
||||||
|
{
|
||||||
|
_resolutionLoc = glGetUniformLocation( getShaderProgram()->getProgram(), "resolution");
|
||||||
|
_textureResolutionLoc = glGetUniformLocation( getShaderProgram()->getProgram(), "textureResolution");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LensFlareSprite::setCustomUniforms()
|
||||||
|
{
|
||||||
|
_textureResolution[0] = getTexture()->getContentSizeInPixels().width;
|
||||||
|
_textureResolution[1] = getTexture()->getContentSizeInPixels().height;
|
||||||
|
|
||||||
|
_resolution[0] = getContentSize().width;
|
||||||
|
_resolution[1] = getContentSize().height;
|
||||||
|
|
||||||
|
getShaderProgram()->setUniformLocationWith2fv(_resolutionLoc, _resolution, 1);
|
||||||
|
getShaderProgram()->setUniformLocationWith2fv(_textureResolutionLoc, _textureResolution, 1);
|
||||||
|
}
|
||||||
|
|
||||||
NormalSpriteTest::NormalSpriteTest()
|
NormalSpriteTest::NormalSpriteTest()
|
||||||
{
|
{
|
||||||
if (ShaderTestDemo2::init())
|
if (ShaderTestDemo2::init())
|
||||||
|
@ -548,3 +587,16 @@ CelShadingSpriteTest::CelShadingSpriteTest()
|
||||||
addChild(sprite2);
|
addChild(sprite2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LensFlareSpriteTest::LensFlareSpriteTest()
|
||||||
|
{
|
||||||
|
if (ShaderTestDemo2::init())
|
||||||
|
{
|
||||||
|
auto s = Director::getInstance()->getWinSize();
|
||||||
|
LensFlareSprite* sprite = LensFlareSprite::createSprite("Images/noise.png");
|
||||||
|
Rect rect = Rect::ZERO;
|
||||||
|
rect.size = Size(480,320);
|
||||||
|
sprite->setPosition(Point(s.width * 0.5, s.height/2));
|
||||||
|
addChild(sprite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -24,8 +24,6 @@ public:
|
||||||
virtual void runThisTest();
|
virtual void runThisTest();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class NormalSpriteTest : public ShaderTestDemo2
|
class NormalSpriteTest : public ShaderTestDemo2
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -71,6 +69,13 @@ public:
|
||||||
virtual std::string subtitle() {return "BloomSpriteTest";}
|
virtual std::string subtitle() {return "BloomSpriteTest";}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LensFlareSpriteTest : public ShaderTestDemo2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LensFlareSpriteTest();
|
||||||
|
virtual std::string subtitle() {return "LensFlareSpriteTest";}
|
||||||
|
};
|
||||||
|
|
||||||
class CelShadingSpriteTest : public ShaderTestDemo2
|
class CelShadingSpriteTest : public ShaderTestDemo2
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
32a561c7f6847e7c0a668e9a684af5dc969c72fc
|
|
@ -0,0 +1,134 @@
|
||||||
|
local targetPlatform = cc.Application:getInstance():getTargetPlatform()
|
||||||
|
|
||||||
|
local LINE_SPACE = 40
|
||||||
|
local itemTagBasic = 1000
|
||||||
|
local LuaBridgeTestsName =
|
||||||
|
{
|
||||||
|
"LuaJavaBridge",
|
||||||
|
"LuaObjectCBridge",
|
||||||
|
}
|
||||||
|
|
||||||
|
local s = cc.Director:getInstance():getWinSize()
|
||||||
|
|
||||||
|
local function LuaBridgeLayer()
|
||||||
|
local layer = cc.Layer:create()
|
||||||
|
local menu = cc.Menu:create()
|
||||||
|
menu:setPosition(cc.p(0, 0))
|
||||||
|
cc.MenuItemFont:setFontName("Arial")
|
||||||
|
cc.MenuItemFont:setFontSize(24)
|
||||||
|
|
||||||
|
local supportObjectCBridge = false
|
||||||
|
if (cc.PLATFORM_OS_IPHONE == targetPlatform) or (cc.PLATFORM_OS_IPAD == targetPlatform) or (cc.PLATFORM_OS_MAC == targetPlatform) then
|
||||||
|
supportObjectCBridge = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local supportJavaBridge = false
|
||||||
|
if (cc.PLATFORM_OS_ANDROID == targetPlatform) then
|
||||||
|
supportJavaBridge = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function createMenuToBridgeScene()
|
||||||
|
local menuToBridgeScene = cc.Menu:create()
|
||||||
|
local function toBridgeScene()
|
||||||
|
local scene = LuaBridgeMainTest()
|
||||||
|
if scene ~= nil then
|
||||||
|
cc.Director:getInstance():replaceScene(scene)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--Create BackMneu
|
||||||
|
cc.MenuItemFont:setFontName("Arial")
|
||||||
|
cc.MenuItemFont:setFontSize(24)
|
||||||
|
local menuItemFont = cc.MenuItemFont:create("Back")
|
||||||
|
menuItemFont:setPosition(cc.p(VisibleRect:rightBottom().x - 50, VisibleRect:rightBottom().y + 25))
|
||||||
|
menuItemFont:registerScriptTapHandler(toBridgeScene)
|
||||||
|
menuToBridgeScene:addChild(menuItemFont)
|
||||||
|
menuToBridgeScene:setPosition(cc.p(0, 0))
|
||||||
|
return menuToBridgeScene
|
||||||
|
end
|
||||||
|
|
||||||
|
local function newLuaJavaBridge()
|
||||||
|
local newScene = cc.Scene:create()
|
||||||
|
local titleLabel = cc.LabelTTF:create("", "Arial", 28)
|
||||||
|
newScene:addChild(titleLabel, 1)
|
||||||
|
titleLabel:setPosition(s.width / 2, s.height - 50)
|
||||||
|
titleLabel:setString("LuaJavaBridge Test")
|
||||||
|
|
||||||
|
subtitleLabel = cc.LabelTTF:create("", "Thonburi", 16)
|
||||||
|
newScene:addChild(subtitleLabel, 1)
|
||||||
|
subtitleLabel:setPosition(s.width / 2, s.height - 80)
|
||||||
|
subtitleLabel:setString("See the console.")
|
||||||
|
if (cc.PLATFORM_OS_ANDROID == targetPlatform) then
|
||||||
|
local args = { 2 , 3}
|
||||||
|
local sigs = "(II)I"
|
||||||
|
local luaj = require "luaj"
|
||||||
|
local className = "com/cocos2dx/sample/LuaJavaBridgeTest/LuaJavaBridgeTest"
|
||||||
|
local ok,ret = luaj.callStaticMethod(className,"addTwoNumbers",args,sigs)
|
||||||
|
if not ok then
|
||||||
|
print("luaj error:", ret)
|
||||||
|
else
|
||||||
|
print("luaj ret:", ret)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function callbackLua(param)
|
||||||
|
if "success" == param then
|
||||||
|
print("java call back success")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
args = { "callbacklua", callbackLua }
|
||||||
|
sigs = "(Ljava/lang/String;I)V"
|
||||||
|
ok = luaj.callStaticMethod(className,"callbackLua",args,sigs)
|
||||||
|
if not ok then
|
||||||
|
print("call callback error")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return newScene
|
||||||
|
end
|
||||||
|
|
||||||
|
local function newLuaObjectCBridge()
|
||||||
|
local newScene = cc.Scene:create()
|
||||||
|
return newScene
|
||||||
|
end
|
||||||
|
|
||||||
|
local function newLuaBridgeScene(idx)
|
||||||
|
if 1 == idx then
|
||||||
|
return newLuaJavaBridge()
|
||||||
|
elseif 2 == idx then
|
||||||
|
return newLuaObjectCBridge()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function menuCallback(tag, pMenuItem)
|
||||||
|
local scene = nil
|
||||||
|
local nIdx = pMenuItem:getZOrder() - itemTagBasic
|
||||||
|
local newScene = newLuaBridgeScene(nIdx)
|
||||||
|
if nil ~= newScene then
|
||||||
|
newScene:addChild(createMenuToBridgeScene(),10)
|
||||||
|
cc.Director:getInstance():replaceScene(newScene)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, table.getn(LuaBridgeTestsName) do
|
||||||
|
local item = cc.MenuItemFont:create(LuaBridgeTestsName[i])
|
||||||
|
item:registerScriptTapHandler(menuCallback)
|
||||||
|
item:setPosition(s.width / 2, s.height - i * LINE_SPACE)
|
||||||
|
menu:addChild(item, itemTagBasic + i)
|
||||||
|
if ((i == 1) and (false == supportJavaBridge))
|
||||||
|
or ((i == 2) and (false == supportObjectCBridge)) then
|
||||||
|
item:setEnabled(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
layer:addChild(menu)
|
||||||
|
|
||||||
|
return layer
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------
|
||||||
|
-- LuaBridge Test
|
||||||
|
-------------------------------------
|
||||||
|
function LuaBridgeMainTest()
|
||||||
|
local scene = cc.Scene:create()
|
||||||
|
scene:addChild(LuaBridgeLayer())
|
||||||
|
scene:addChild(CreateBackMenuItem())
|
||||||
|
return scene
|
||||||
|
end
|
|
@ -43,6 +43,7 @@ require "luaScript/TouchesTest/TouchesTest"
|
||||||
require "luaScript/TransitionsTest/TransitionsTest"
|
require "luaScript/TransitionsTest/TransitionsTest"
|
||||||
require "luaScript/UserDefaultTest/UserDefaultTest"
|
require "luaScript/UserDefaultTest/UserDefaultTest"
|
||||||
require "luaScript/ZwoptexTest/ZwoptexTest"
|
require "luaScript/ZwoptexTest/ZwoptexTest"
|
||||||
|
require "luaScript/LuaBridgeTest/LuaBridgeTest"
|
||||||
|
|
||||||
|
|
||||||
local LINE_SPACE = 40
|
local LINE_SPACE = 40
|
||||||
|
@ -95,7 +96,8 @@ local _allTests = {
|
||||||
{ isSupported = true, name = "TouchesTest" , create_func = TouchesTest },
|
{ isSupported = true, name = "TouchesTest" , create_func = TouchesTest },
|
||||||
{ isSupported = true, name = "TransitionsTest" , create_func = TransitionsTest },
|
{ isSupported = true, name = "TransitionsTest" , create_func = TransitionsTest },
|
||||||
{ isSupported = true, name = "UserDefaultTest" , create_func= UserDefaultTestMain },
|
{ isSupported = true, name = "UserDefaultTest" , create_func= UserDefaultTestMain },
|
||||||
{ isSupported = true, name = "ZwoptexTest" , create_func = ZwoptexTestMain }
|
{ isSupported = true, name = "ZwoptexTest" , create_func = ZwoptexTestMain },
|
||||||
|
{ isSupported = true, name = "LuaBridgeTest" , create_func = LuaBridgeMainTest }
|
||||||
}
|
}
|
||||||
|
|
||||||
local TESTS_COUNT = table.getn(_allTests)
|
local TESTS_COUNT = table.getn(_allTests)
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2012 cocos2d-x.org
|
||||||
|
|
||||||
|
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 com.cocos2dx.sample.LuaJavaBridgeTest;
|
||||||
|
|
||||||
|
import org.cocos2dx.lib.Cocos2dxLuaJavaBridge;
|
||||||
|
|
||||||
|
public class LuaJavaBridgeTest
|
||||||
|
{
|
||||||
|
public static int addTwoNumbers(final int num1,final int num2){
|
||||||
|
return num1 + num2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void callbackLua(final String tipInfo,final int luaFunc){
|
||||||
|
Cocos2dxLuaJavaBridge.callLuaFunctionWithString(luaFunc, "success");
|
||||||
|
Cocos2dxLuaJavaBridge.releaseLuaFunction(luaFunc);
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,6 +38,10 @@ extern "C" {
|
||||||
#include "platform/ios/CCLuaObjcBridge.h"
|
#include "platform/ios/CCLuaObjcBridge.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||||
|
#include "platform/android/CCLuaJavaBridge.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
|
||||||
#include "Lua_web_socket.h"
|
#include "Lua_web_socket.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -136,6 +140,10 @@ bool LuaStack::init(void)
|
||||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||||
LuaObjcBridge::luaopen_luaoc(_state);
|
LuaObjcBridge::luaopen_luaoc(_state);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||||
|
LuaJavaBridge::luaopen_luaj(_state);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
|
||||||
tolua_web_socket_open(_state);
|
tolua_web_socket_open(_state);
|
||||||
|
|
|
@ -0,0 +1,618 @@
|
||||||
|
|
||||||
|
#include "CCLuaJavaBridge.h"
|
||||||
|
#include "platform/android/jni/JniHelper.h"
|
||||||
|
#include <android/log.h>
|
||||||
|
|
||||||
|
#define LOG_TAG "luajc"
|
||||||
|
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "tolua_fix.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
LuaJavaBridge::CallInfo::~CallInfo(void)
|
||||||
|
{
|
||||||
|
if (m_returnType == TypeString && m_ret.stringValue)
|
||||||
|
{
|
||||||
|
delete m_ret.stringValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LuaJavaBridge::CallInfo::execute(void)
|
||||||
|
{
|
||||||
|
switch (m_returnType)
|
||||||
|
{
|
||||||
|
case TypeVoid:
|
||||||
|
m_env->CallStaticVoidMethod(m_classID, m_methodID);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeInteger:
|
||||||
|
m_ret.intValue = m_env->CallStaticIntMethod(m_classID, m_methodID);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeFloat:
|
||||||
|
m_ret.floatValue = m_env->CallStaticFloatMethod(m_classID, m_methodID);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeBoolean:
|
||||||
|
m_ret.boolValue = m_env->CallStaticBooleanMethod(m_classID, m_methodID);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeString:
|
||||||
|
m_retjs = (jstring)m_env->CallStaticObjectMethod(m_classID, m_methodID);
|
||||||
|
const char *stringBuff = m_env->GetStringUTFChars(m_retjs, 0);
|
||||||
|
m_ret.stringValue = new string(stringBuff);
|
||||||
|
m_env->ReleaseStringUTFChars(m_retjs, stringBuff);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_env->ExceptionCheck() == JNI_TRUE)
|
||||||
|
{
|
||||||
|
m_env->ExceptionDescribe();
|
||||||
|
m_env->ExceptionClear();
|
||||||
|
m_error = LUAJ_ERR_EXCEPTION_OCCURRED;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LuaJavaBridge::CallInfo::executeWithArgs(jvalue *args)
|
||||||
|
{
|
||||||
|
switch (m_returnType)
|
||||||
|
{
|
||||||
|
case TypeVoid:
|
||||||
|
m_env->CallStaticVoidMethodA(m_classID, m_methodID, args);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeInteger:
|
||||||
|
m_ret.intValue = m_env->CallStaticIntMethodA(m_classID, m_methodID, args);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeFloat:
|
||||||
|
m_ret.floatValue = m_env->CallStaticFloatMethodA(m_classID, m_methodID, args);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeBoolean:
|
||||||
|
m_ret.boolValue = m_env->CallStaticBooleanMethodA(m_classID, m_methodID, args);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeString:
|
||||||
|
m_retjs = (jstring)m_env->CallStaticObjectMethodA(m_classID, m_methodID, args);
|
||||||
|
const char *stringBuff = m_env->GetStringUTFChars(m_retjs, 0);
|
||||||
|
m_ret.stringValue = new string(stringBuff);
|
||||||
|
m_env->ReleaseStringUTFChars(m_retjs, stringBuff);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_env->ExceptionCheck() == JNI_TRUE)
|
||||||
|
{
|
||||||
|
m_env->ExceptionDescribe();
|
||||||
|
m_env->ExceptionClear();
|
||||||
|
m_error = LUAJ_ERR_EXCEPTION_OCCURRED;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LuaJavaBridge::CallInfo::pushReturnValue(lua_State *L)
|
||||||
|
{
|
||||||
|
if (m_error != LUAJ_ERR_OK)
|
||||||
|
{
|
||||||
|
lua_pushinteger(L, m_error);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (m_returnType)
|
||||||
|
{
|
||||||
|
case TypeInteger:
|
||||||
|
lua_pushinteger(L, m_ret.intValue);
|
||||||
|
return 1;
|
||||||
|
case TypeFloat:
|
||||||
|
lua_pushnumber(L, m_ret.floatValue);
|
||||||
|
return 1;
|
||||||
|
case TypeBoolean:
|
||||||
|
lua_pushboolean(L, m_ret.boolValue);
|
||||||
|
return 1;
|
||||||
|
case TypeString:
|
||||||
|
lua_pushstring(L, m_ret.stringValue->c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LuaJavaBridge::CallInfo::validateMethodSig(void)
|
||||||
|
{
|
||||||
|
size_t len = m_methodSig.length();
|
||||||
|
if (len < 3 || m_methodSig[0] != '(') // min sig is "()V"
|
||||||
|
{
|
||||||
|
m_error = LUAJ_ERR_INVALID_SIGNATURES;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t pos = 1;
|
||||||
|
while (pos < len && m_methodSig[pos] != ')')
|
||||||
|
{
|
||||||
|
LuaJavaBridge::ValueType type = checkType(m_methodSig, &pos);
|
||||||
|
if (type == TypeInvalid) return false;
|
||||||
|
|
||||||
|
m_argumentsCount++;
|
||||||
|
m_argumentsType.push_back(type);
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos >= len || m_methodSig[pos] != ')')
|
||||||
|
{
|
||||||
|
m_error = LUAJ_ERR_INVALID_SIGNATURES;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos++;
|
||||||
|
m_returnType = checkType(m_methodSig, &pos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LuaJavaBridge::ValueType LuaJavaBridge::CallInfo::checkType(const string& sig, size_t *pos)
|
||||||
|
{
|
||||||
|
switch (sig[*pos])
|
||||||
|
{
|
||||||
|
case 'I':
|
||||||
|
return TypeInteger;
|
||||||
|
case 'F':
|
||||||
|
return TypeFloat;
|
||||||
|
case 'Z':
|
||||||
|
return TypeBoolean;
|
||||||
|
case 'V':
|
||||||
|
return TypeVoid;
|
||||||
|
case 'L':
|
||||||
|
size_t pos2 = sig.find_first_of(';', *pos + 1);
|
||||||
|
if (pos2 == string::npos)
|
||||||
|
{
|
||||||
|
m_error = LUAJ_ERR_INVALID_SIGNATURES;
|
||||||
|
return TypeInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
const string t = sig.substr(*pos, pos2 - *pos + 1);
|
||||||
|
if (t.compare("Ljava/lang/String;") == 0)
|
||||||
|
{
|
||||||
|
*pos = pos2;
|
||||||
|
return TypeString;
|
||||||
|
}
|
||||||
|
else if (t.compare("Ljava/util/Vector;") == 0)
|
||||||
|
{
|
||||||
|
*pos = pos2;
|
||||||
|
return TypeVector;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_error = LUAJ_ERR_TYPE_NOT_SUPPORT;
|
||||||
|
return TypeInvalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_error = LUAJ_ERR_TYPE_NOT_SUPPORT;
|
||||||
|
return TypeInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LuaJavaBridge::CallInfo::getMethodInfo(void)
|
||||||
|
{
|
||||||
|
m_methodID = 0;
|
||||||
|
m_env = 0;
|
||||||
|
|
||||||
|
JavaVM* jvm = cocos2d::JniHelper::getJavaVM();
|
||||||
|
jint ret = jvm->GetEnv((void**)&m_env, JNI_VERSION_1_4);
|
||||||
|
switch (ret) {
|
||||||
|
case JNI_OK:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JNI_EDETACHED :
|
||||||
|
if (jvm->AttachCurrentThread(&m_env, NULL) < 0)
|
||||||
|
{
|
||||||
|
LOGD("%s", "Failed to get the environment using AttachCurrentThread()");
|
||||||
|
m_error = LUAJ_ERR_VM_THREAD_DETACHED;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JNI_EVERSION :
|
||||||
|
default :
|
||||||
|
LOGD("%s", "Failed to get the environment using GetEnv()");
|
||||||
|
m_error = LUAJ_ERR_VM_FAILURE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
jstring _jstrClassName = m_env->NewStringUTF(m_className.c_str());
|
||||||
|
m_classID = (jclass) m_env->CallObjectMethod(cocos2d::JniHelper::classloader,
|
||||||
|
cocos2d::JniHelper::loadclassMethod_methodID,
|
||||||
|
_jstrClassName);
|
||||||
|
|
||||||
|
if (NULL == m_classID) {
|
||||||
|
LOGD("Classloader failed to find class of %s", m_className.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_env->DeleteLocalRef(_jstrClassName);
|
||||||
|
m_methodID = m_env->GetStaticMethodID(m_classID, m_methodName.c_str(), m_methodSig.c_str());
|
||||||
|
if (!m_methodID)
|
||||||
|
{
|
||||||
|
m_env->ExceptionClear();
|
||||||
|
LOGD("Failed to find method id of %s.%s %s",
|
||||||
|
m_className.c_str(),
|
||||||
|
m_methodName.c_str(),
|
||||||
|
m_methodSig.c_str());
|
||||||
|
m_error = LUAJ_ERR_METHOD_NOT_FOUND;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------- */
|
||||||
|
|
||||||
|
lua_State *LuaJavaBridge::s_luaState = NULL;
|
||||||
|
int LuaJavaBridge::s_newFunctionId = 0;
|
||||||
|
|
||||||
|
void LuaJavaBridge::luaopen_luaj(lua_State *L)
|
||||||
|
{
|
||||||
|
s_luaState = L;
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_pushstring(L, "callStaticMethod");
|
||||||
|
lua_pushcfunction(L, LuaJavaBridge::callJavaStaticMethod);
|
||||||
|
lua_rawset(L, -3);
|
||||||
|
lua_setglobal(L, "LuaJavaBridge");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
args:
|
||||||
|
const char *className
|
||||||
|
const char *methodName
|
||||||
|
LUA_TABLE args
|
||||||
|
const char *sig
|
||||||
|
*/
|
||||||
|
int LuaJavaBridge::callJavaStaticMethod(lua_State *L)
|
||||||
|
{
|
||||||
|
if (!lua_isstring(L, -4) || !lua_isstring(L, -3) || !lua_istable(L, -2) || !lua_isstring(L, -1))
|
||||||
|
{
|
||||||
|
lua_pushboolean(L, 0);
|
||||||
|
lua_pushinteger(L, LUAJ_ERR_INVALID_SIGNATURES);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGD("%s", "LuaJavaBridge::callJavaStaticMethod(lua_State *L)");
|
||||||
|
|
||||||
|
const char *className = lua_tostring(L, -4);
|
||||||
|
const char *methodName = lua_tostring(L, -3);
|
||||||
|
const char *methodSig = lua_tostring(L, -1);
|
||||||
|
|
||||||
|
CallInfo call(className, methodName, methodSig);
|
||||||
|
|
||||||
|
// check args
|
||||||
|
lua_pop(L, 1); /* L: args */
|
||||||
|
int count = fetchArrayElements(L, -1); /* L: args e1 e2 e3 e4 ... */
|
||||||
|
jvalue *args = NULL;
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
args = new jvalue[count];
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
int index = -count + i;
|
||||||
|
switch (call.argumentTypeAtIndex(i))
|
||||||
|
{
|
||||||
|
case TypeInteger:
|
||||||
|
if (lua_isfunction(L, index))
|
||||||
|
{
|
||||||
|
args[i].i = retainLuaFunction(L, index, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
args[i].i = (int)lua_tonumber(L, index);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeFloat:
|
||||||
|
args[i].f = lua_tonumber(L, index);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeBoolean:
|
||||||
|
args[i].z = lua_toboolean(L, index) != 0 ? JNI_TRUE : JNI_FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeString:
|
||||||
|
default:
|
||||||
|
args[i].l = call.getEnv()->NewStringUTF(lua_tostring(L, index));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_pop(L, count); /* L: args */
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = args ? call.executeWithArgs(args) : call.execute();
|
||||||
|
if (args) delete []args;
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
LOGD("LuaJavaBridge::callJavaStaticMethod(\"%s\", \"%s\", args, \"%s\") EXECUTE FAILURE, ERROR CODE: %d",
|
||||||
|
className, methodName, methodSig, call.getErrorCode());
|
||||||
|
|
||||||
|
lua_pushboolean(L, 0);
|
||||||
|
lua_pushinteger(L, call.getErrorCode());
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGD("LuaJavaBridge::callJavaStaticMethod(\"%s\", \"%s\", args, \"%s\") SUCCESS",
|
||||||
|
className, methodName, methodSig);
|
||||||
|
|
||||||
|
lua_pushboolean(L, 1);
|
||||||
|
return 1 + call.pushReturnValue(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
// increase lua function refernece counter, return counter
|
||||||
|
int LuaJavaBridge::retainLuaFunctionById(int functionId)
|
||||||
|
{
|
||||||
|
lua_State *L = s_luaState;
|
||||||
|
|
||||||
|
lua_pushstring(L, LUAJ_REGISTRY_RETAIN); /* L: key */
|
||||||
|
lua_rawget(L, LUA_REGISTRYINDEX); /* L: id_r */
|
||||||
|
if (!lua_istable(L, -1))
|
||||||
|
{
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get counter
|
||||||
|
lua_pushinteger(L, functionId); /* L: id_r id */
|
||||||
|
lua_rawget(L, -2); /* L: id_r r */
|
||||||
|
if (lua_type(L, -1) != LUA_TNUMBER)
|
||||||
|
{
|
||||||
|
lua_pop(L, 2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// increase counter
|
||||||
|
int retainCount = lua_tonumber(L, -1);
|
||||||
|
retainCount++;
|
||||||
|
lua_pop(L, 1); /* L: id_r */
|
||||||
|
lua_pushinteger(L, functionId); /* L: id_r id */
|
||||||
|
lua_pushinteger(L, retainCount); /* L: id_r id r */
|
||||||
|
lua_rawset(L, -3); /* id_r[id] = r, L: id_r */
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
LOGD("luajretainLuaFunctionById(%d) - retain count = %d", functionId, retainCount);
|
||||||
|
|
||||||
|
return retainCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// decrease lua function reference counter, return counter
|
||||||
|
int LuaJavaBridge::releaseLuaFunctionById(int functionId)
|
||||||
|
{
|
||||||
|
lua_State *L = s_luaState;
|
||||||
|
/* L: */
|
||||||
|
lua_pushstring(L, LUAJ_REGISTRY_FUNCTION); /* L: key */
|
||||||
|
lua_rawget(L, LUA_REGISTRYINDEX); /* L: f_id */
|
||||||
|
if (!lua_istable(L, -1))
|
||||||
|
{
|
||||||
|
lua_pop(L, 1);
|
||||||
|
LOGD("%s", "luajreleaseLuaFunctionById() - LUAJ_REGISTRY_FUNCTION not exists");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushstring(L, LUAJ_REGISTRY_RETAIN); /* L: f_id key */
|
||||||
|
lua_rawget(L, LUA_REGISTRYINDEX); /* L: f_id id_r */
|
||||||
|
if (!lua_istable(L, -1))
|
||||||
|
{
|
||||||
|
lua_pop(L, 2);
|
||||||
|
LOGD("%s", "luajreleaseLuaFunctionById() - LUAJ_REGISTRY_RETAIN not exists");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushinteger(L, functionId); /* L: f_id id_r id */
|
||||||
|
lua_rawget(L, -2); /* L: f_id id_r r */
|
||||||
|
if (lua_type(L, -1) != LUA_TNUMBER)
|
||||||
|
{
|
||||||
|
lua_pop(L, 3);
|
||||||
|
LOGD("luajreleaseLuaFunctionById() - function id %d not found", functionId);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int retainCount = lua_tonumber(L, -1);
|
||||||
|
retainCount--;
|
||||||
|
|
||||||
|
if (retainCount > 0)
|
||||||
|
{
|
||||||
|
// update counter
|
||||||
|
lua_pop(L, 1); /* L: f_id id_r */
|
||||||
|
lua_pushinteger(L, functionId); /* L: f_id id_r id */
|
||||||
|
lua_pushinteger(L, retainCount); /* L: f_id id_r id r */
|
||||||
|
lua_rawset(L, -3); /* id_r[id] = r, L: f_id id_r */
|
||||||
|
lua_pop(L, 2);
|
||||||
|
LOGD("luajreleaseLuaFunctionById() - function id %d retain count = %d", functionId, retainCount);
|
||||||
|
return retainCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove lua function reference
|
||||||
|
lua_pop(L, 1); /* L: f_id id_r */
|
||||||
|
lua_pushinteger(L, functionId); /* L: f_id id_r id */
|
||||||
|
lua_pushnil(L); /* L: f_id id_r id nil */
|
||||||
|
lua_rawset(L, -3); /* id_r[id] = nil, L: f_id id_r */
|
||||||
|
|
||||||
|
lua_pop(L, 1); /* L: f_id */
|
||||||
|
lua_pushnil(L); /* L: f_id nil */
|
||||||
|
while (lua_next(L, -2) != 0) /* L: f_id f id */
|
||||||
|
{
|
||||||
|
int value = lua_tonumber(L, -1);
|
||||||
|
lua_pop(L, 1); /* L: f_id f */
|
||||||
|
if (value == functionId)
|
||||||
|
{
|
||||||
|
lua_pushnil(L); /* L: f_id f nil */
|
||||||
|
lua_rawset(L, -3); /* f_id[f] = nil, L: f_id */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} /* L: f_id */
|
||||||
|
|
||||||
|
lua_pop(L, 1);
|
||||||
|
LOGD("luajreleaseLuaFunctionById() - function id %d released", functionId);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LuaJavaBridge::callLuaFunctionById(int functionId, const char *arg)
|
||||||
|
{
|
||||||
|
lua_State *L = s_luaState;
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
/* L: */
|
||||||
|
lua_pushstring(L, LUAJ_REGISTRY_FUNCTION); /* L: key */
|
||||||
|
lua_rawget(L, LUA_REGISTRYINDEX); /* L: f_id */
|
||||||
|
if (!lua_istable(L, -1))
|
||||||
|
{
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushnil(L); /* L: f_id nil */
|
||||||
|
while (lua_next(L, -2) != 0) /* L: f_id f id */
|
||||||
|
{
|
||||||
|
int value = lua_tonumber(L, -1);
|
||||||
|
lua_pop(L, 1); /* L: f_id f */
|
||||||
|
if (value == functionId)
|
||||||
|
{
|
||||||
|
lua_pushstring(L, arg); /* L: f_id f arg */
|
||||||
|
int ok = lua_pcall(L, 1, 1, 0); /* L: f_id ret|err */
|
||||||
|
int ret;
|
||||||
|
if (ok == 0)
|
||||||
|
{
|
||||||
|
ret = lua_tonumber(L, -1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = -ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(L, top);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} /* L: f_id */
|
||||||
|
|
||||||
|
lua_settop(L, top);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// call lua global function
|
||||||
|
int LuaJavaBridge::callLuaGlobalFunction(const char *functionName, const char *arg)
|
||||||
|
{
|
||||||
|
lua_State *L = s_luaState;
|
||||||
|
|
||||||
|
int ret = -1;
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
|
||||||
|
lua_getglobal(L, functionName);
|
||||||
|
if (lua_isfunction(L, -1))
|
||||||
|
{
|
||||||
|
lua_pushstring(L, arg);
|
||||||
|
int ok = lua_pcall(L, 1, 1, 0);
|
||||||
|
if (ok == 0)
|
||||||
|
{
|
||||||
|
ret = lua_tonumber(L, -1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = -ok;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(L, top);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------
|
||||||
|
|
||||||
|
// increase lua function reference counter, return functionId
|
||||||
|
int LuaJavaBridge::retainLuaFunction(lua_State *L, int functionIndex, int *retainCountReturn)
|
||||||
|
{
|
||||||
|
/* L: f ... */
|
||||||
|
lua_pushstring(L, LUAJ_REGISTRY_FUNCTION); /* L: f ... key */
|
||||||
|
lua_rawget(L, LUA_REGISTRYINDEX); /* L: f ... f_id */
|
||||||
|
if (!lua_istable(L, -1))
|
||||||
|
{
|
||||||
|
lua_pop(L, 1);
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_pushstring(L, LUAJ_REGISTRY_FUNCTION);
|
||||||
|
lua_pushvalue(L, -2);
|
||||||
|
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushstring(L, LUAJ_REGISTRY_RETAIN); /* L: f ... f_id key */
|
||||||
|
lua_rawget(L, LUA_REGISTRYINDEX); /* L: f ... f_id id_r */
|
||||||
|
if (!lua_istable(L, -1))
|
||||||
|
{
|
||||||
|
lua_pop(L, 1);
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_pushstring(L, LUAJ_REGISTRY_RETAIN);
|
||||||
|
lua_pushvalue(L, -2);
|
||||||
|
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get function id
|
||||||
|
lua_pushvalue(L, functionIndex - 2); /* L: f ... f_id id_r f */
|
||||||
|
lua_rawget(L, -3); /* L: f ... f_id id_r id */
|
||||||
|
|
||||||
|
int functionId;
|
||||||
|
if (lua_type(L, -1) != LUA_TNUMBER)
|
||||||
|
{
|
||||||
|
// first retain, create new id
|
||||||
|
lua_pop(L, 1); /* L: f ... f_id id_r */
|
||||||
|
s_newFunctionId++;
|
||||||
|
functionId = s_newFunctionId;
|
||||||
|
|
||||||
|
lua_pushvalue(L, functionIndex - 2); /* L: f ... f_id id_r f */
|
||||||
|
lua_pushinteger(L, functionId); /* L: f ... f_id id_r f id */
|
||||||
|
lua_rawset(L, -4); /* f_id[f] = id, L: f ... f_id id_r */
|
||||||
|
lua_pushinteger(L, functionId); /* L: f ... f_id id_r id */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
functionId = lua_tonumber(L, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get function retain
|
||||||
|
lua_pushvalue(L, -1); /* L: f ... f_id id_r id id */
|
||||||
|
lua_rawget(L, -3); /* L: f ... f_id id_r id r */
|
||||||
|
int retainCount = 1;
|
||||||
|
if (lua_type(L, -1) != LUA_TNUMBER)
|
||||||
|
{
|
||||||
|
// first retain, set retain count = 1
|
||||||
|
lua_pop(L, 1);
|
||||||
|
lua_pushinteger(L, retainCount);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// add retain count
|
||||||
|
retainCount = lua_tonumber(L, -1);
|
||||||
|
retainCount++;
|
||||||
|
lua_pop(L, 1);
|
||||||
|
lua_pushinteger(L, retainCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_rawset(L, -3); /* id_r[id] = r, L: f ... f_id id_r */
|
||||||
|
lua_pop(L, 2); /* L: f ... */
|
||||||
|
|
||||||
|
if (retainCountReturn) *retainCountReturn = retainCount;
|
||||||
|
return functionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LuaJavaBridge::fetchArrayElements(lua_State *L, int index)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, index - count, count + 1);
|
||||||
|
if (lua_isnil(L, -1))
|
||||||
|
{
|
||||||
|
lua_pop(L, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++count;
|
||||||
|
} while (1);
|
||||||
|
return count;
|
||||||
|
}
|
|
@ -0,0 +1,138 @@
|
||||||
|
#ifndef COCOS2DX_SCRIPT_LUA_COCOS2DX_SUPPORT_PLATFORM_ANDROID_LUA_JAVA_BRIDGE_H
|
||||||
|
#define COCOS2DX_SCRIPT_LUA_COCOS2DX_SUPPORT_PLATFORM_ANDROID_LUA_JAVA_BRIDGE_H
|
||||||
|
|
||||||
|
#include <jni.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "cocos2d.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "lua.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace cocos2d;
|
||||||
|
|
||||||
|
#define LUAJ_ERR_OK 0
|
||||||
|
#define LUAJ_ERR_TYPE_NOT_SUPPORT (-1)
|
||||||
|
#define LUAJ_ERR_INVALID_SIGNATURES (-2)
|
||||||
|
#define LUAJ_ERR_METHOD_NOT_FOUND (-3)
|
||||||
|
#define LUAJ_ERR_EXCEPTION_OCCURRED (-4)
|
||||||
|
#define LUAJ_ERR_VM_THREAD_DETACHED (-5)
|
||||||
|
#define LUAJ_ERR_VM_FAILURE (-6)
|
||||||
|
|
||||||
|
#define LUAJ_REGISTRY_FUNCTION "luaj_function_id" // table[function] = id
|
||||||
|
#define LUAJ_REGISTRY_RETAIN "luaj_function_id_retain" // table[id] = retain count
|
||||||
|
|
||||||
|
|
||||||
|
class LuaJavaBridge
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void luaopen_luaj(lua_State *L);
|
||||||
|
|
||||||
|
static int retainLuaFunctionById(int functionId);
|
||||||
|
static int releaseLuaFunctionById(int functionId);
|
||||||
|
|
||||||
|
static int callLuaFunctionById(int functionId, const char *arg);
|
||||||
|
static int callLuaGlobalFunction(const char *functionName, const char *arg);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TypeInvalid = -1,
|
||||||
|
TypeVoid = 0,
|
||||||
|
TypeInteger = 1,
|
||||||
|
TypeFloat = 2,
|
||||||
|
TypeBoolean = 3,
|
||||||
|
TypeString = 4,
|
||||||
|
TypeVector = 5,
|
||||||
|
TypeFunction= 6,
|
||||||
|
} ValueType;
|
||||||
|
|
||||||
|
typedef vector<ValueType> ValueTypes;
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
int intValue;
|
||||||
|
float floatValue;
|
||||||
|
int boolValue;
|
||||||
|
string *stringValue;
|
||||||
|
} ReturnValue;
|
||||||
|
|
||||||
|
class CallInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CallInfo(const char *className, const char *methodName, const char *methodSig)
|
||||||
|
: m_valid(false)
|
||||||
|
, m_error(LUAJ_ERR_OK)
|
||||||
|
, m_className(className)
|
||||||
|
, m_methodName(methodName)
|
||||||
|
, m_methodSig(methodSig)
|
||||||
|
, m_returnType(TypeVoid)
|
||||||
|
, m_argumentsCount(0)
|
||||||
|
, m_retjs(NULL)
|
||||||
|
, m_env(NULL)
|
||||||
|
, m_classID(NULL)
|
||||||
|
, m_methodID(NULL)
|
||||||
|
{
|
||||||
|
memset(&m_ret, 0, sizeof(m_ret));
|
||||||
|
m_valid = validateMethodSig() && getMethodInfo();
|
||||||
|
}
|
||||||
|
~CallInfo(void);
|
||||||
|
|
||||||
|
bool isValid(void) {
|
||||||
|
return m_valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getErrorCode(void) {
|
||||||
|
return m_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEnv *getEnv(void) {
|
||||||
|
return m_env;
|
||||||
|
}
|
||||||
|
|
||||||
|
int argumentTypeAtIndex(size_t index) {
|
||||||
|
return m_argumentsType.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool execute(void);
|
||||||
|
bool executeWithArgs(jvalue *args);
|
||||||
|
int pushReturnValue(lua_State *L);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_valid;
|
||||||
|
int m_error;
|
||||||
|
|
||||||
|
string m_className;
|
||||||
|
string m_methodName;
|
||||||
|
string m_methodSig;
|
||||||
|
int m_argumentsCount;
|
||||||
|
ValueTypes m_argumentsType;
|
||||||
|
ValueType m_returnType;
|
||||||
|
|
||||||
|
ReturnValue m_ret;
|
||||||
|
jstring m_retjs;
|
||||||
|
|
||||||
|
JNIEnv *m_env;
|
||||||
|
jclass m_classID;
|
||||||
|
jmethodID m_methodID;
|
||||||
|
|
||||||
|
bool validateMethodSig(void);
|
||||||
|
bool getMethodInfo(void);
|
||||||
|
ValueType checkType(const string& sig, size_t *pos);
|
||||||
|
};
|
||||||
|
|
||||||
|
static int callJavaStaticMethod(lua_State *L);
|
||||||
|
static int retainLuaFunction(lua_State *L, int functionIndex, int *retainCountReturn);
|
||||||
|
static int getMethodInfo(CallInfo *call, const char *className, const char *methodName, const char *paramCode);
|
||||||
|
static int fetchArrayElements(lua_State *L, int index);
|
||||||
|
static int callAndPushReturnValue(lua_State *L, CallInfo *call, jvalue *args);
|
||||||
|
|
||||||
|
static lua_State *s_luaState;
|
||||||
|
static int s_newFunctionId;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //COCOS2DX_SCRIPT_LUA_COCOS2DX_SUPPORT_PLATFORM_ANDROID_LUA_JAVA_BRIDGE_H
|
|
@ -0,0 +1,45 @@
|
||||||
|
|
||||||
|
#include "Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge.h"
|
||||||
|
|
||||||
|
#include <android/log.h>
|
||||||
|
|
||||||
|
#include "CCLuaJavaBridge.h"
|
||||||
|
|
||||||
|
#define LOG_TAG "Cocos2dxLuaJavaBridge_java"
|
||||||
|
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge_callLuaFunctionWithString
|
||||||
|
(JNIEnv *env, jclass cls, jint functionId, jstring value)
|
||||||
|
{
|
||||||
|
const char *value_ = env->GetStringUTFChars(value, 0);
|
||||||
|
int ret = LuaJavaBridge::callLuaFunctionById(functionId, value_);
|
||||||
|
env->ReleaseStringUTFChars(value, value_);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge_callLuaGlobalFunctionWithString
|
||||||
|
(JNIEnv *env, jclass cls, jstring luaFunctionName, jstring value)
|
||||||
|
{
|
||||||
|
const char *luaFunctionName_ = env->GetStringUTFChars(luaFunctionName, 0);
|
||||||
|
const char *value_ = env->GetStringUTFChars(value, 0);
|
||||||
|
int ret = LuaJavaBridge::callLuaGlobalFunction(luaFunctionName_, value_);
|
||||||
|
env->ReleaseStringUTFChars(luaFunctionName, luaFunctionName_);
|
||||||
|
env->ReleaseStringUTFChars(value, value_);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge_retainLuaFunction
|
||||||
|
(JNIEnv *env, jclass cls, jint luaFunctionId)
|
||||||
|
{
|
||||||
|
return LuaJavaBridge::retainLuaFunctionById(luaFunctionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge_releaseLuaFunction
|
||||||
|
(JNIEnv *env, jclass cls, jint luaFunctionId)
|
||||||
|
{
|
||||||
|
return LuaJavaBridge::releaseLuaFunctionById(luaFunctionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // extern "C"
|
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef COCOS2DX_SCRIPT_LUA_COCOS2DX_SUPPORT_PLATFORM_ANDROID_JNI_JAVA_ORG_COCOS2DX_LIB_COCOS2DX_LUA_JAVA_BRIDEG_H
|
||||||
|
#define COCOS2DX_SCRIPT_LUA_COCOS2DX_SUPPORT_PLATFORM_ANDROID_JNI_JAVA_ORG_COCOS2DX_LIB_COCOS2DX_LUA_JAVA_BRIDEG_H
|
||||||
|
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge
|
||||||
|
* Method: callLuaFunctionWithString
|
||||||
|
* Signature: (ILjava/lang/String;)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge_callLuaFunctionWithString
|
||||||
|
(JNIEnv *, jclass, jint, jstring);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge
|
||||||
|
* Method: callLuaGlobalFunctionWithString
|
||||||
|
* Signature: (Ljava/lang/String;Ljava/lang/String;)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge_callLuaGlobalFunctionWithString
|
||||||
|
(JNIEnv *env, jclass, jstring, jstring);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge
|
||||||
|
* Method: retainLuaFunction
|
||||||
|
* Signature: (I)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge_retainLuaFunction
|
||||||
|
(JNIEnv *env, jclass, jint);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge
|
||||||
|
* Method: releaseLuaFunction
|
||||||
|
* Signature: (I)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge_releaseLuaFunction
|
||||||
|
(JNIEnv *env, jclass, jint);
|
||||||
|
|
||||||
|
} // extern "C"
|
||||||
|
|
||||||
|
#endif // COCOS2DX_SCRIPT_LUA_COCOS2DX_SUPPORT_PLATFORM_ANDROID_JNI_JAVA_ORG_COCOS2DX_LIB_COCOS2DX_LUA_JAVA_BRIDEG_H
|
|
@ -20,6 +20,8 @@ LOCAL_SRC_FILES := ../cocos2dx_support/CCLuaBridge.cpp \
|
||||||
../cocos2dx_support/lua_cocos2dx_manual.cpp \
|
../cocos2dx_support/lua_cocos2dx_manual.cpp \
|
||||||
../cocos2dx_support/lua_cocos2dx_extension_manual.cpp \
|
../cocos2dx_support/lua_cocos2dx_extension_manual.cpp \
|
||||||
../cocos2dx_support/lua_cocos2dx_deprecated.cpp \
|
../cocos2dx_support/lua_cocos2dx_deprecated.cpp \
|
||||||
|
../cocos2dx_support/platform/android/CCLuaJavaBridge.cpp \
|
||||||
|
../cocos2dx_support/platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge.cpp \
|
||||||
../tolua/tolua_event.c \
|
../tolua/tolua_event.c \
|
||||||
../tolua/tolua_is.c \
|
../tolua/tolua_is.c \
|
||||||
../tolua/tolua_map.c \
|
../tolua/tolua_map.c \
|
||||||
|
@ -30,7 +32,9 @@ LOCAL_SRC_FILES := ../cocos2dx_support/CCLuaBridge.cpp \
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../luajit/include \
|
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../luajit/include \
|
||||||
$(LOCAL_PATH)/../tolua \
|
$(LOCAL_PATH)/../tolua \
|
||||||
$(LOCAL_PATH)/../cocos2dx_support \
|
$(LOCAL_PATH)/../cocos2dx_support \
|
||||||
$(LOCAL_PATH)/../../auto-generated/lua-bindings
|
$(LOCAL_PATH)/../../auto-generated/lua-bindings \
|
||||||
|
$(LOCAL_PATH)/../cocos2dx_support/platform/android \
|
||||||
|
$(LOCAL_PATH)/../cocos2dx_support/platform/android/jni
|
||||||
|
|
||||||
|
|
||||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/ \
|
LOCAL_C_INCLUDES := $(LOCAL_PATH)/ \
|
||||||
|
@ -44,7 +48,9 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/ \
|
||||||
$(LOCAL_PATH)/../../../CocosDenshion/include \
|
$(LOCAL_PATH)/../../../CocosDenshion/include \
|
||||||
$(LOCAL_PATH)/../../../extensions \
|
$(LOCAL_PATH)/../../../extensions \
|
||||||
$(LOCAL_PATH)/../cocos2dx_support \
|
$(LOCAL_PATH)/../cocos2dx_support \
|
||||||
$(LOCAL_PATH)/../../auto-generated/lua-bindings
|
$(LOCAL_PATH)/../../auto-generated/lua-bindings \
|
||||||
|
$(LOCAL_PATH)/../cocos2dx_support/platform/android \
|
||||||
|
$(LOCAL_PATH)/../cocos2dx_support/platform/android/jni
|
||||||
|
|
||||||
|
|
||||||
LOCAL_WHOLE_STATIC_LIBRARIES := luajit_static
|
LOCAL_WHOLE_STATIC_LIBRARIES := luajit_static
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
local luaj = {}
|
||||||
|
|
||||||
|
local callJavaStaticMethod = LuaJavaBridge.callStaticMethod
|
||||||
|
|
||||||
|
local function checkArguments(args, sig)
|
||||||
|
if type(args) ~= "table" then args = {} end
|
||||||
|
if sig then return args, sig end
|
||||||
|
|
||||||
|
sig = {"("}
|
||||||
|
for i, v in ipairs(args) do
|
||||||
|
local t = type(v)
|
||||||
|
if t == "number" then
|
||||||
|
sig[#sig + 1] = "F"
|
||||||
|
elseif t == "boolean" then
|
||||||
|
sig[#sig + 1] = "Z"
|
||||||
|
elseif t == "function" then
|
||||||
|
sig[#sig + 1] = "I"
|
||||||
|
else
|
||||||
|
sig[#sig + 1] = "Ljava/lang/String;"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sig[#sig + 1] = ")V"
|
||||||
|
|
||||||
|
return args, table.concat(sig)
|
||||||
|
end
|
||||||
|
|
||||||
|
function luaj.callStaticMethod(className, methodName, args, sig)
|
||||||
|
local args, sig = checkArguments(args, sig)
|
||||||
|
--echoInfo("luaj.callStaticMethod(\"%s\",\n\t\"%s\",\n\targs,\n\t\"%s\"", className, methodName, sig)
|
||||||
|
return callJavaStaticMethod(className, methodName, args, sig)
|
||||||
|
end
|
||||||
|
|
||||||
|
return luaj
|
Loading…
Reference in New Issue