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;
|
||||
|
||||
/**
|
||||
@brief Remove Lua function reference
|
||||
@brief Remove Lua function handler
|
||||
*/
|
||||
virtual void removeLuaHandler(int nHandler) = 0;
|
||||
|
||||
|
@ -158,15 +158,20 @@ public:
|
|||
virtual int executeGlobalFunction(const char* functionName) = 0;
|
||||
|
||||
/**
|
||||
@brief Execute a function by ref id
|
||||
@param The function ref id
|
||||
@brief Execute a function by handler
|
||||
@param The function handler
|
||||
@param Number of parameters
|
||||
@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 executeFunctionWithFloatData(int nHandler, float 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
|
||||
virtual int executeTouchEvent(int nHandler, int eventType, CCTouch *pTouch) = 0;
|
||||
|
|
|
@ -24,11 +24,11 @@
|
|||
|
||||
#include "CCLuaEngine.h"
|
||||
#include "tolua++.h"
|
||||
#include "tolua_fix.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
#include "tolua_fix.h"
|
||||
}
|
||||
|
||||
#include "cocos2d.h"
|
||||
|
@ -148,88 +148,105 @@ int CCLuaEngine::executeGlobalFunction(const char* functionName)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int CCLuaEngine::executeFunctionByRefID(int nHandler, int numArgs)
|
||||
int CCLuaEngine::executeFunctionByHandler(int nHandler, int numArgs)
|
||||
{
|
||||
lua_pushstring(m_state, TOLUA_REFID_FUNC_MAPPING);
|
||||
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))
|
||||
if (pushFunctionByHandler(nHandler))
|
||||
{
|
||||
CCLOG("[LUA ERROR] function refid '%d' does not reference a Lua function", nHandler);
|
||||
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++)
|
||||
if (numArgs > 0)
|
||||
{
|
||||
tolua_pushvalue(m_state, lo); /* stack: ... refid_func func (...) */
|
||||
lua_insert(m_state, -(numArgs + 1)); /* stack: ... func arg1 arg2 ... */
|
||||
}
|
||||
}
|
||||
|
||||
int error = 0;
|
||||
try
|
||||
{
|
||||
error = lua_pcall(m_state, numArgs, 1, 0); /* stack: ... refid_func ret */
|
||||
int error = 0;
|
||||
// try
|
||||
// {
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
lua_pushinteger(m_state, data);
|
||||
return executeFunctionByRefID(nHandler, 1);
|
||||
return executeFunctionByHandler(nHandler, 1);
|
||||
}
|
||||
|
||||
int CCLuaEngine::executeFunctionWithFloatData(int nHandler, float data)
|
||||
{
|
||||
lua_pushnumber(m_state, data);
|
||||
return executeFunctionByRefID(nHandler, 1);
|
||||
return executeFunctionByHandler(nHandler, 1);
|
||||
}
|
||||
|
||||
int CCLuaEngine::executeFunctionWithBooleanData(int nHandler, bool 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
|
||||
|
@ -239,7 +256,7 @@ int CCLuaEngine::executeTouchEvent(int nHandler, int eventType, CCTouch *pTouch)
|
|||
lua_pushinteger(m_state, eventType);
|
||||
lua_pushnumber(m_state, pt.x);
|
||||
lua_pushnumber(m_state, pt.y);
|
||||
return executeFunctionByRefID(nHandler, 3);
|
||||
return executeFunctionByHandler(nHandler, 3);
|
||||
}
|
||||
|
||||
int CCLuaEngine::executeTouchesEvent(int nHandler, int eventType, CCSet *pTouches)
|
||||
|
@ -262,7 +279,7 @@ int CCLuaEngine::executeTouchesEvent(int nHandler, int eventType, CCSet *pTouche
|
|||
++it;
|
||||
}
|
||||
|
||||
return executeFunctionByRefID(nHandler, 2);
|
||||
return executeFunctionByHandler(nHandler, 2);
|
||||
}
|
||||
|
||||
int CCLuaEngine::executeSchedule(int nHandler, ccTime dt)
|
||||
|
@ -295,4 +312,16 @@ void CCLuaEngine::addLuaLoader(lua_CFunction func)
|
|||
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
|
||||
|
|
|
@ -97,10 +97,15 @@ public:
|
|||
@param Number of parameters
|
||||
@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 executeFunctionWithFloatData(int nHandler, float 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
|
||||
virtual int executeTouchEvent(int nHandler, int eventType, cocos2d::CCTouch *pTouch);
|
||||
|
@ -121,6 +126,7 @@ private:
|
|||
}
|
||||
|
||||
bool init(void);
|
||||
bool pushFunctionByHandler(int nHandler);
|
||||
|
||||
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_newtable(L);
|
||||
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,
|
||||
|
@ -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)
|
||||
{
|
||||
static int functionRefIDCount = 0;
|
||||
if (lua_gettop(L) < abs(lo) || !lua_isfunction(L, lo)) return 0;
|
||||
|
||||
++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;
|
||||
if (!lua_isfunction(L, lo)) return 0;
|
||||
lua_pushvalue(L, lo); /* stack: ... func */
|
||||
return luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
TOLUA_API void tolua_remove_function_by_refid(lua_State* L, int refid)
|
||||
{
|
||||
lua_pushstring(L, TOLUA_REFID_FUNC_MAPPING);
|
||||
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: - */
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, refid);
|
||||
}
|
||||
|
||||
// check lua value is funciton
|
||||
|
|
|
@ -11,7 +11,6 @@ extern "C"
|
|||
|
||||
#define TOLUA_REFID_PTR_MAPPING "tolua_refid_ptr_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 int tolua_pushusertype_ccobject(lua_State* L,
|
||||
|
|
Loading…
Reference in New Issue