mirror of https://github.com/axmolengine/axmol.git
Merge pull request #756 from dualface/fix-lua-engine-bugs
fixed #1030: Improve Lua engine
This commit is contained in:
commit
7dfe4224e1
|
@ -125,7 +125,7 @@ public:
|
||||||
virtual void removeCCObjectByID(int nLuaID) = 0;
|
virtual void removeCCObjectByID(int nLuaID) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Remove Lua function reference
|
@brief Remove Lua function handler
|
||||||
*/
|
*/
|
||||||
virtual void removeLuaHandler(int nHandler) = 0;
|
virtual void removeLuaHandler(int nHandler) = 0;
|
||||||
|
|
||||||
|
@ -158,15 +158,20 @@ public:
|
||||||
virtual int executeGlobalFunction(const char* functionName) = 0;
|
virtual int executeGlobalFunction(const char* functionName) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Execute a function by ref id
|
@brief Execute a function by handler
|
||||||
@param The function ref id
|
@param The function handler
|
||||||
@param Number of parameters
|
@param Number of parameters
|
||||||
@return The integer value returned from the script function.
|
@return The integer value returned from the script function.
|
||||||
*/
|
*/
|
||||||
virtual int executeFunctionByRefID(int nHandler, int numArgs = 0) = 0;
|
virtual int executeFunctionByHandler(int nHandler, int numArgs = 0) = 0;
|
||||||
virtual int executeFunctionWithIntegerData(int nHandler, int data) = 0;
|
virtual int executeFunctionWithIntegerData(int nHandler, int data) = 0;
|
||||||
virtual int executeFunctionWithFloatData(int nHandler, float data) = 0;
|
virtual int executeFunctionWithFloatData(int nHandler, float data) = 0;
|
||||||
virtual int executeFunctionWithBooleanData(int nHandler, bool data) = 0;
|
virtual int executeFunctionWithBooleanData(int nHandler, bool data) = 0;
|
||||||
|
virtual int executeFunctionWithCCObject(int nHandler, CCObject* pObject, const char* typeName) = 0;
|
||||||
|
virtual int pushIntegerToLuaStack(int data) = 0;
|
||||||
|
virtual int pushFloatToLuaStack(int data) = 0;
|
||||||
|
virtual int pushBooleanToLuaStack(int data) = 0;
|
||||||
|
virtual int pushCCObjectToLuaStack(CCObject* pObject, const char* typeName) = 0;
|
||||||
|
|
||||||
// functions for excute touch event
|
// functions for excute touch event
|
||||||
virtual int executeTouchEvent(int nHandler, int eventType, CCTouch *pTouch) = 0;
|
virtual int executeTouchEvent(int nHandler, int eventType, CCTouch *pTouch) = 0;
|
||||||
|
|
|
@ -24,11 +24,11 @@
|
||||||
|
|
||||||
#include "CCLuaEngine.h"
|
#include "CCLuaEngine.h"
|
||||||
#include "tolua++.h"
|
#include "tolua++.h"
|
||||||
#include "tolua_fix.h"
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "lualib.h"
|
#include "lualib.h"
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
|
#include "tolua_fix.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "cocos2d.h"
|
#include "cocos2d.h"
|
||||||
|
@ -148,88 +148,105 @@ int CCLuaEngine::executeGlobalFunction(const char* functionName)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CCLuaEngine::executeFunctionByRefID(int nHandler, int numArgs)
|
int CCLuaEngine::executeFunctionByHandler(int nHandler, int numArgs)
|
||||||
{
|
{
|
||||||
lua_pushstring(m_state, TOLUA_REFID_FUNC_MAPPING);
|
if (pushFunctionByHandler(nHandler))
|
||||||
lua_rawget(m_state, LUA_REGISTRYINDEX); /* stack: ... refid_func */
|
|
||||||
lua_pushinteger(m_state, nHandler); /* stack: ... refid_func refid */
|
|
||||||
lua_rawget(m_state, -2); /* stack: ... refid_func func */
|
|
||||||
|
|
||||||
if (!lua_isfunction(m_state, -1))
|
|
||||||
{
|
{
|
||||||
CCLOG("[LUA ERROR] function refid '%d' does not reference a Lua function", nHandler);
|
if (numArgs > 0)
|
||||||
lua_pop(m_state, 2 + numArgs);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numArgs > 0)
|
|
||||||
{
|
|
||||||
// [a1] [a2] refid_func func
|
|
||||||
// -4 -3 -2 -1
|
|
||||||
// [a1] [a2] refid_func func [a1]
|
|
||||||
// -5 -4 -3 -2 -1
|
|
||||||
int lo = -2 - numArgs;
|
|
||||||
for (int i = 0; i < numArgs; i++)
|
|
||||||
{
|
{
|
||||||
tolua_pushvalue(m_state, lo); /* stack: ... refid_func func (...) */
|
lua_insert(m_state, -(numArgs + 1)); /* stack: ... func arg1 arg2 ... */
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int error = 0;
|
int error = 0;
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
error = lua_pcall(m_state, numArgs, 1, 0); /* stack: ... refid_func ret */
|
error = lua_pcall(m_state, numArgs, 1, 0); /* stack: ... ret */
|
||||||
|
// }
|
||||||
|
// catch (exception& e)
|
||||||
|
// {
|
||||||
|
// CCLOG("[LUA ERROR] lua_pcall(%d) catch C++ exception: %s", nHandler, e.what());
|
||||||
|
// lua_settop(m_state, 0);
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
// catch (...)
|
||||||
|
// {
|
||||||
|
// CCLOG("[LUA ERROR] lua_pcall(%d) catch C++ unknown exception.", nHandler);
|
||||||
|
// lua_settop(m_state, 0);
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
CCLOG("[LUA ERROR] %s", lua_tostring(m_state, - 1));
|
||||||
|
lua_settop(m_state, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get return value
|
||||||
|
int ret = 0;
|
||||||
|
if (lua_isnumber(m_state, -1))
|
||||||
|
{
|
||||||
|
ret = lua_tointeger(m_state, -1);
|
||||||
|
}
|
||||||
|
else if (lua_isboolean(m_state, -1))
|
||||||
|
{
|
||||||
|
ret = lua_toboolean(m_state, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(m_state, 1);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
catch (exception& e)
|
else
|
||||||
{
|
{
|
||||||
CCLOG("[LUA ERROR] lua_pcall(%d) catch C++ exception: %s", nHandler, e.what());
|
|
||||||
lua_settop(m_state, 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
CCLOG("[LUA ERROR] lua_pcall(%d) catch C++ unknown exception.", nHandler);
|
|
||||||
lua_settop(m_state, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
CCLOG("[LUA ERROR] %s", lua_tostring(m_state, - 1));
|
|
||||||
lua_pop(m_state, 2 + numArgs); // clean error message
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get return value
|
|
||||||
int ret = 0;
|
|
||||||
if (lua_isnumber(m_state, -1))
|
|
||||||
{
|
|
||||||
ret = lua_tointeger(m_state, -1);
|
|
||||||
}
|
|
||||||
else if (lua_isboolean(m_state, -1))
|
|
||||||
{
|
|
||||||
ret = lua_toboolean(m_state, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_pop(m_state, 2 + numArgs);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CCLuaEngine::executeFunctionWithIntegerData(int nHandler, int data)
|
int CCLuaEngine::executeFunctionWithIntegerData(int nHandler, int data)
|
||||||
{
|
{
|
||||||
lua_pushinteger(m_state, data);
|
lua_pushinteger(m_state, data);
|
||||||
return executeFunctionByRefID(nHandler, 1);
|
return executeFunctionByHandler(nHandler, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CCLuaEngine::executeFunctionWithFloatData(int nHandler, float data)
|
int CCLuaEngine::executeFunctionWithFloatData(int nHandler, float data)
|
||||||
{
|
{
|
||||||
lua_pushnumber(m_state, data);
|
lua_pushnumber(m_state, data);
|
||||||
return executeFunctionByRefID(nHandler, 1);
|
return executeFunctionByHandler(nHandler, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CCLuaEngine::executeFunctionWithBooleanData(int nHandler, bool data)
|
int CCLuaEngine::executeFunctionWithBooleanData(int nHandler, bool data)
|
||||||
{
|
{
|
||||||
lua_pushboolean(m_state, data);
|
lua_pushboolean(m_state, data);
|
||||||
return executeFunctionByRefID(nHandler, 1);
|
return executeFunctionByHandler(nHandler, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CCLuaEngine::executeFunctionWithCCObject(int nHandler, CCObject* pObject, const char* typeName)
|
||||||
|
{
|
||||||
|
tolua_pushusertype_ccobject(m_state, pObject->m_uID, &pObject->m_nLuaID, pObject, typeName);
|
||||||
|
return executeFunctionByHandler(nHandler, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CCLuaEngine::pushIntegerToLuaStack(int data)
|
||||||
|
{
|
||||||
|
lua_pushinteger(m_state, data);
|
||||||
|
return lua_gettop(m_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CCLuaEngine::pushFloatToLuaStack(int data)
|
||||||
|
{
|
||||||
|
lua_pushnumber(m_state, data);
|
||||||
|
return lua_gettop(m_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CCLuaEngine::pushBooleanToLuaStack(int data)
|
||||||
|
{
|
||||||
|
lua_pushboolean(m_state, data);
|
||||||
|
return lua_gettop(m_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CCLuaEngine::pushCCObjectToLuaStack(CCObject* pObject, const char* typeName)
|
||||||
|
{
|
||||||
|
tolua_pushusertype_ccobject(m_state, pObject->m_uID, &pObject->m_nLuaID, pObject, typeName);
|
||||||
|
return lua_gettop(m_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// functions for excute touch event
|
// functions for excute touch event
|
||||||
|
@ -239,7 +256,7 @@ int CCLuaEngine::executeTouchEvent(int nHandler, int eventType, CCTouch *pTouch)
|
||||||
lua_pushinteger(m_state, eventType);
|
lua_pushinteger(m_state, eventType);
|
||||||
lua_pushnumber(m_state, pt.x);
|
lua_pushnumber(m_state, pt.x);
|
||||||
lua_pushnumber(m_state, pt.y);
|
lua_pushnumber(m_state, pt.y);
|
||||||
return executeFunctionByRefID(nHandler, 3);
|
return executeFunctionByHandler(nHandler, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CCLuaEngine::executeTouchesEvent(int nHandler, int eventType, CCSet *pTouches)
|
int CCLuaEngine::executeTouchesEvent(int nHandler, int eventType, CCSet *pTouches)
|
||||||
|
@ -262,7 +279,7 @@ int CCLuaEngine::executeTouchesEvent(int nHandler, int eventType, CCSet *pTouche
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
return executeFunctionByRefID(nHandler, 2);
|
return executeFunctionByHandler(nHandler, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CCLuaEngine::executeSchedule(int nHandler, ccTime dt)
|
int CCLuaEngine::executeSchedule(int nHandler, ccTime dt)
|
||||||
|
@ -295,4 +312,16 @@ void CCLuaEngine::addLuaLoader(lua_CFunction func)
|
||||||
lua_pop(m_state, 1);
|
lua_pop(m_state, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CCLuaEngine::pushFunctionByHandler(int nHandler)
|
||||||
|
{
|
||||||
|
lua_rawgeti(m_state, LUA_REGISTRYINDEX, nHandler); /* stack: ... func */
|
||||||
|
if (!lua_isfunction(m_state, -1))
|
||||||
|
{
|
||||||
|
CCLOG("[LUA ERROR] function refid '%d' does not reference a Lua function", nHandler);
|
||||||
|
lua_pop(m_state, 1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
NS_CC_END
|
NS_CC_END
|
||||||
|
|
|
@ -97,10 +97,15 @@ public:
|
||||||
@param Number of parameters
|
@param Number of parameters
|
||||||
@return The integer value returned from the script function.
|
@return The integer value returned from the script function.
|
||||||
*/
|
*/
|
||||||
virtual int executeFunctionByRefID(int nHandler, int numArgs = 0);
|
virtual int executeFunctionByHandler(int nHandler, int numArgs = 0);
|
||||||
virtual int executeFunctionWithIntegerData(int nHandler, int data);
|
virtual int executeFunctionWithIntegerData(int nHandler, int data);
|
||||||
virtual int executeFunctionWithFloatData(int nHandler, float data);
|
virtual int executeFunctionWithFloatData(int nHandler, float data);
|
||||||
virtual int executeFunctionWithBooleanData(int nHandler, bool data);
|
virtual int executeFunctionWithBooleanData(int nHandler, bool data);
|
||||||
|
virtual int executeFunctionWithCCObject(int nHandler, CCObject* pObject, const char* typeName);
|
||||||
|
virtual int pushIntegerToLuaStack(int data);
|
||||||
|
virtual int pushFloatToLuaStack(int data);
|
||||||
|
virtual int pushBooleanToLuaStack(int data);
|
||||||
|
virtual int pushCCObjectToLuaStack(CCObject* pObject, const char* typeName);
|
||||||
|
|
||||||
// functions for excute touch event
|
// functions for excute touch event
|
||||||
virtual int executeTouchEvent(int nHandler, int eventType, cocos2d::CCTouch *pTouch);
|
virtual int executeTouchEvent(int nHandler, int eventType, cocos2d::CCTouch *pTouch);
|
||||||
|
@ -121,6 +126,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init(void);
|
bool init(void);
|
||||||
|
bool pushFunctionByHandler(int nHandler);
|
||||||
|
|
||||||
lua_State* m_state;
|
lua_State* m_state;
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,10 +11,6 @@ TOLUA_API void tolua_prepare_ccobject_table(lua_State* L)
|
||||||
lua_pushstring(L, TOLUA_REFID_TYPE_MAPPING);
|
lua_pushstring(L, TOLUA_REFID_TYPE_MAPPING);
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||||
|
|
||||||
lua_pushstring(L, TOLUA_REFID_FUNC_MAPPING);
|
|
||||||
lua_newtable(L);
|
|
||||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TOLUA_API int tolua_pushusertype_ccobject(lua_State* L,
|
TOLUA_API int tolua_pushusertype_ccobject(lua_State* L,
|
||||||
|
@ -150,29 +146,14 @@ TOLUA_API int tolua_remove_ccobject_by_refid(lua_State* L, int refid)
|
||||||
|
|
||||||
TOLUA_API int tolua_ref_function(lua_State* L, int lo, int def)
|
TOLUA_API int tolua_ref_function(lua_State* L, int lo, int def)
|
||||||
{
|
{
|
||||||
static int functionRefIDCount = 0;
|
if (!lua_isfunction(L, lo)) return 0;
|
||||||
if (lua_gettop(L) < abs(lo) || !lua_isfunction(L, lo)) return 0;
|
lua_pushvalue(L, lo); /* stack: ... func */
|
||||||
|
return luaL_ref(L, LUA_REGISTRYINDEX);
|
||||||
++functionRefIDCount;
|
|
||||||
/* stack: ... func ... */
|
|
||||||
lua_pushstring(L, TOLUA_REFID_FUNC_MAPPING);
|
|
||||||
lua_rawget(L, LUA_REGISTRYINDEX); /* stack: ... func ... refid_func */
|
|
||||||
lua_pushinteger(L, functionRefIDCount); /* stack: ... func ... refid_func refid */
|
|
||||||
lua_pushvalue(L, lo); /* stack: ... func ... refid_func refid func */
|
|
||||||
lua_rawset(L, -3); /* refid_func[refid] = func, stack: ... func ... refid_func */
|
|
||||||
lua_pop(L, 1); /* stack: ... func ... */
|
|
||||||
|
|
||||||
return functionRefIDCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TOLUA_API void tolua_remove_function_by_refid(lua_State* L, int refid)
|
TOLUA_API void tolua_remove_function_by_refid(lua_State* L, int refid)
|
||||||
{
|
{
|
||||||
lua_pushstring(L, TOLUA_REFID_FUNC_MAPPING);
|
luaL_unref(L, LUA_REGISTRYINDEX, refid);
|
||||||
lua_rawget(L, LUA_REGISTRYINDEX); /* stack: refid_func */
|
|
||||||
lua_pushinteger(L, refid); /* stack: refid_func refid */
|
|
||||||
lua_pushnil(L); /* stack: refid_func refid nil */
|
|
||||||
lua_rawget(L, -2); /* delete refid_func[refid], stack: refid_func */
|
|
||||||
lua_pop(L, 1); /* stack: - */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check lua value is funciton
|
// check lua value is funciton
|
||||||
|
|
|
@ -11,7 +11,6 @@ extern "C"
|
||||||
|
|
||||||
#define TOLUA_REFID_PTR_MAPPING "tolua_refid_ptr_mapping"
|
#define TOLUA_REFID_PTR_MAPPING "tolua_refid_ptr_mapping"
|
||||||
#define TOLUA_REFID_TYPE_MAPPING "tolua_refid_type_mapping"
|
#define TOLUA_REFID_TYPE_MAPPING "tolua_refid_type_mapping"
|
||||||
#define TOLUA_REFID_FUNC_MAPPING "tolua_refid_func_mapping"
|
|
||||||
|
|
||||||
TOLUA_API void tolua_prepare_ccobject_table(lua_State* L);
|
TOLUA_API void tolua_prepare_ccobject_table(lua_State* L);
|
||||||
TOLUA_API int tolua_pushusertype_ccobject(lua_State* L,
|
TOLUA_API int tolua_pushusertype_ccobject(lua_State* L,
|
||||||
|
|
Loading…
Reference in New Issue