2015-06-17 13:59:09 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2015 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.
|
|
|
|
****************************************************************************/
|
|
|
|
|
2016-03-20 21:53:44 +08:00
|
|
|
#include "scripting/lua-bindings/manual/CCComponentLua.h"
|
2015-09-22 01:34:56 +08:00
|
|
|
#include <string>
|
2015-06-17 13:59:09 +08:00
|
|
|
#include "base/CCScriptSupport.h"
|
2016-03-20 21:53:44 +08:00
|
|
|
#include "scripting/lua-bindings/manual/CCLuaEngine.h"
|
|
|
|
#include "scripting/lua-bindings/manual/LuaBasicConversions.h"
|
2015-06-17 13:59:09 +08:00
|
|
|
|
|
|
|
NS_CC_BEGIN
|
|
|
|
|
2015-09-25 22:46:10 +08:00
|
|
|
const std::string ComponentLua::ON_ENTER = "onEnter";
|
|
|
|
const std::string ComponentLua::ON_EXIT = "onExit";
|
|
|
|
const std::string ComponentLua::UPDATE = "update";
|
|
|
|
|
2015-06-24 17:07:56 +08:00
|
|
|
#define KEY_COMPONENT "component"
|
|
|
|
|
|
|
|
int ComponentLua::_index = 0;
|
|
|
|
|
2015-06-19 18:54:01 +08:00
|
|
|
ComponentLua* ComponentLua::create(const std::string& scriptFileName)
|
2015-06-17 13:59:09 +08:00
|
|
|
{
|
2015-06-19 18:54:01 +08:00
|
|
|
CC_ASSERT(!scriptFileName.empty());
|
|
|
|
|
2015-07-08 10:11:17 +08:00
|
|
|
initClass();
|
2015-06-24 17:07:56 +08:00
|
|
|
|
2015-06-19 18:54:01 +08:00
|
|
|
auto componentLua = new(std::nothrow) ComponentLua(scriptFileName);
|
|
|
|
if (componentLua)
|
|
|
|
{
|
|
|
|
componentLua->autorelease();
|
|
|
|
}
|
|
|
|
|
|
|
|
return componentLua;
|
2015-06-17 13:59:09 +08:00
|
|
|
}
|
|
|
|
|
2015-06-19 18:54:01 +08:00
|
|
|
ComponentLua::ComponentLua(const std::string& scriptFileName)
|
2015-09-25 22:46:10 +08:00
|
|
|
: _scriptFileName(scriptFileName)
|
2015-06-24 17:07:56 +08:00
|
|
|
, _table(nullptr)
|
|
|
|
, _strIndex("")
|
|
|
|
{
|
|
|
|
_succeedLoadingScript = loadAndExecuteScript();
|
|
|
|
}
|
|
|
|
|
|
|
|
ComponentLua::~ComponentLua()
|
2015-06-19 18:54:01 +08:00
|
|
|
{
|
2015-06-24 17:07:56 +08:00
|
|
|
removeLuaTable();
|
2015-06-19 18:54:01 +08:00
|
|
|
}
|
|
|
|
|
2015-09-19 00:18:28 +08:00
|
|
|
void ComponentLua::getScriptObjectInternal() const
|
2015-07-08 10:11:17 +08:00
|
|
|
{
|
|
|
|
lua_State *l = LuaEngine::getInstance()->getLuaStack()->getLuaState();
|
|
|
|
lua_pushstring(l, KEY_COMPONENT); // stack: "component"
|
|
|
|
lua_rawget(l, LUA_REGISTRYINDEX); // stack: LUA_REGISTRYINDEX["component"]
|
|
|
|
lua_pushstring(l, _strIndex.c_str()); // stack: LUA_REGISTRYINDEX["component"] strIndex
|
|
|
|
lua_rawget(l, -2); // stack: LUA_REGISTRYINDEX["component"]
|
|
|
|
}
|
|
|
|
|
2015-09-19 00:18:28 +08:00
|
|
|
void* ComponentLua::getScriptObject() const
|
|
|
|
{
|
|
|
|
getScriptObjectInternal();
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2015-06-19 18:54:01 +08:00
|
|
|
void ComponentLua::update(float delta)
|
2015-06-24 17:07:56 +08:00
|
|
|
{
|
2015-09-25 22:46:10 +08:00
|
|
|
if (_succeedLoadingScript && getLuaFunction(ComponentLua::UPDATE))
|
2015-06-24 17:07:56 +08:00
|
|
|
{
|
|
|
|
getUserData();
|
2015-06-25 17:39:59 +08:00
|
|
|
lua_State *l = LuaEngine::getInstance()->getLuaStack()->getLuaState();
|
|
|
|
lua_pushnumber(l, delta);
|
|
|
|
LuaEngine::getInstance()->getLuaStack()->executeFunction(2);
|
2015-06-24 17:07:56 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-07 09:51:18 +08:00
|
|
|
void ComponentLua::onEnter()
|
|
|
|
{
|
2015-09-25 22:46:10 +08:00
|
|
|
if (_succeedLoadingScript && getLuaFunction(ComponentLua::ON_ENTER))
|
2015-07-07 09:51:18 +08:00
|
|
|
{
|
|
|
|
getUserData();
|
|
|
|
LuaEngine::getInstance()->getLuaStack()->executeFunction(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ComponentLua::onExit()
|
|
|
|
{
|
2015-09-25 22:46:10 +08:00
|
|
|
if (_succeedLoadingScript && getLuaFunction(ComponentLua::ON_EXIT))
|
2015-07-07 09:51:18 +08:00
|
|
|
{
|
|
|
|
getUserData();
|
|
|
|
LuaEngine::getInstance()->getLuaStack()->executeFunction(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-24 17:07:56 +08:00
|
|
|
bool ComponentLua::getLuaFunction(const std::string& functionName)
|
2015-06-19 18:54:01 +08:00
|
|
|
{
|
|
|
|
lua_State *l = LuaEngine::getInstance()->getLuaStack()->getLuaState();
|
2015-06-24 09:45:04 +08:00
|
|
|
|
2015-06-24 17:07:56 +08:00
|
|
|
lua_pushstring(l, KEY_COMPONENT); // stack: "component"
|
|
|
|
lua_rawget(l, LUA_REGISTRYINDEX); // stack: table_of_component
|
2015-07-07 09:51:18 +08:00
|
|
|
lua_pushstring(l, _strIndex.c_str()); // stack: table_of_component strIndex
|
2015-06-24 17:07:56 +08:00
|
|
|
lua_rawget(l, -2); // stack: table_of_component table_of_this
|
|
|
|
lua_pushstring(l, functionName.c_str()); // stack: table_of_component table_of_this "update"
|
|
|
|
lua_rawget(l, -2); // stack: table_of_component table_of_this table_of_this["update"]
|
|
|
|
lua_remove(l, -2); // stack: table_of_component table_of_this["update"]
|
|
|
|
lua_remove(l, -2); // stack: table_of_this["update"]
|
|
|
|
|
|
|
|
int type = lua_type(l, -1);
|
2015-07-07 09:51:18 +08:00
|
|
|
// if (type != LUA_TFUNCTION)
|
|
|
|
// {
|
|
|
|
// CCLOG("can not get %s function from %s", functionName.c_str(), _scriptFileName.c_str());
|
|
|
|
// }
|
2015-06-24 17:07:56 +08:00
|
|
|
|
|
|
|
return type == LUA_TFUNCTION;
|
2015-06-19 18:54:01 +08:00
|
|
|
}
|
|
|
|
|
2015-06-24 17:07:56 +08:00
|
|
|
bool ComponentLua::loadAndExecuteScript()
|
2015-06-17 13:59:09 +08:00
|
|
|
{
|
2015-06-19 18:54:01 +08:00
|
|
|
// register native functions
|
2015-06-24 17:07:56 +08:00
|
|
|
auto engine = LuaEngine::getInstance();
|
2015-06-19 18:54:01 +08:00
|
|
|
lua_State *l = engine->getLuaStack()->getLuaState();
|
2015-06-24 17:07:56 +08:00
|
|
|
|
|
|
|
// load script
|
2015-11-03 15:49:46 +08:00
|
|
|
auto fileUtils = FileUtils::getInstance();
|
|
|
|
std::string fullPathOfScript = fileUtils->fullPathForFilename(_scriptFileName);
|
|
|
|
Data data = fileUtils->getDataFromFile(fullPathOfScript);
|
|
|
|
int error = LUA_ERRFILE;
|
|
|
|
if(data.getSize() > 0)
|
|
|
|
error = engine->getLuaStack()->luaLoadBuffer(l, (const char*)data.getBytes(), (int)data.getSize(), fullPathOfScript.c_str());
|
2015-06-24 17:07:56 +08:00
|
|
|
if (error)
|
|
|
|
{
|
2015-07-07 09:51:18 +08:00
|
|
|
CCLOG("ComponentLua::loadAndExecuteScript: %s", lua_tostring(l, -1));
|
|
|
|
lua_pop(l, 1);
|
2015-06-24 17:07:56 +08:00
|
|
|
return false;
|
|
|
|
}
|
2015-06-19 18:54:01 +08:00
|
|
|
|
|
|
|
// execute script
|
2015-06-24 17:07:56 +08:00
|
|
|
error = lua_pcall(l, 0, 1, 0);
|
|
|
|
if (error)
|
|
|
|
{
|
2015-07-07 09:51:18 +08:00
|
|
|
CCLOG("ComponentLua::loadAndExecuteScript: %s", lua_tostring(l, -1));
|
|
|
|
lua_pop(l, 1);
|
2015-06-24 17:07:56 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check the return value from lua script is a table
|
|
|
|
int type = lua_type(l, -1);
|
|
|
|
if (type != LUA_TTABLE)
|
|
|
|
{
|
2015-07-07 09:51:18 +08:00
|
|
|
CCLOG("%s should return a table, or the script component can not work currectly", _scriptFileName.c_str());
|
2015-06-24 17:07:56 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
storeLuaTable();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-07-08 10:11:17 +08:00
|
|
|
void ComponentLua::initClass()
|
2015-06-24 17:07:56 +08:00
|
|
|
{
|
|
|
|
static bool run = true;
|
|
|
|
if (run)
|
|
|
|
{
|
|
|
|
// LUA_REGISTRYINDEX["component"] = new table
|
|
|
|
|
|
|
|
LuaEngine* engine = LuaEngine::getInstance();
|
|
|
|
lua_State* l = engine->getLuaStack()->getLuaState();
|
|
|
|
|
|
|
|
lua_pushstring(l, KEY_COMPONENT); // stack: "component"
|
|
|
|
lua_newtable(l); // stack: "component" table
|
|
|
|
lua_rawset(l, LUA_REGISTRYINDEX); // stack: -
|
|
|
|
|
|
|
|
run = false;
|
|
|
|
}
|
2015-07-07 09:51:18 +08:00
|
|
|
|
|
|
|
|
2015-06-24 17:07:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ComponentLua::storeLuaTable()
|
|
|
|
{
|
|
|
|
lua_State *l = LuaEngine::getInstance()->getLuaStack()->getLuaState();
|
|
|
|
|
|
|
|
_index++;
|
2015-09-22 11:39:30 +08:00
|
|
|
_strIndex.append(StringUtils::toString(_index));
|
2015-06-24 17:07:56 +08:00
|
|
|
|
|
|
|
// LUA_REGISTRYINDEX["component"][strIndex] = table return from lua
|
|
|
|
lua_pushstring(l, KEY_COMPONENT); // stack: table_return_from_lua "component"
|
|
|
|
lua_rawget(l, LUA_REGISTRYINDEX); // stack: table_return_from_lua table_of_component
|
|
|
|
lua_pushstring(l, _strIndex.c_str()); // stack: table_return_from_lua table_of_component strIndex
|
|
|
|
lua_pushvalue(l, -3); // stack: table_return_from_lua table_of_component strIndex table_return_from_lua
|
|
|
|
lua_rawset(l, -3); // stack: table_return_from_lua table_of_component
|
|
|
|
lua_pop(l, 1); // stack: table_return_from_lua
|
|
|
|
|
|
|
|
// add table's elements to userdata's metatable
|
2015-09-25 22:46:10 +08:00
|
|
|
object_to_luaval<cocos2d::ComponentLua>(l, "cc.ComponentLua", this); // stack: table_return_from_lua userdata
|
2015-06-24 17:07:56 +08:00
|
|
|
lua_getmetatable(l, -1); // stack: table_return_from_lua userdata mt
|
|
|
|
lua_remove(l, -2); // stack: table_return_from_lua mt
|
|
|
|
lua_pushnil(l); // stack: table_return_from_lua mt nil
|
|
|
|
while (lua_next(l, -3)) // stack: table_return_from_lua mt key value
|
2015-06-19 18:54:01 +08:00
|
|
|
{
|
2015-06-24 17:07:56 +08:00
|
|
|
lua_pushvalue(l, -2); // stack: table_return_from_lua mt key value key
|
|
|
|
lua_insert(l, -2); // stack: table_return_from_lua mt key key value
|
|
|
|
lua_rawset(l, -4); // stack: table_return_from_lua mt key
|
|
|
|
}
|
2015-07-07 09:51:18 +08:00
|
|
|
lua_pop(l, 2);
|
2015-06-24 17:07:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ComponentLua::removeLuaTable()
|
|
|
|
{
|
|
|
|
if (_succeedLoadingScript)
|
|
|
|
{
|
|
|
|
// LUA_REGISTRYINDEX["component"][strIndex] = nil
|
|
|
|
|
|
|
|
lua_State *l = LuaEngine::getInstance()->getLuaStack()->getLuaState();
|
|
|
|
|
|
|
|
lua_pushstring(l, KEY_COMPONENT); // stack: "component"
|
|
|
|
lua_rawget(l, LUA_REGISTRYINDEX); // stack: LUA_REGISTRYINDEX["component"]
|
|
|
|
lua_pushstring(l, _strIndex.c_str()); // stack: LUA_REGISTRYINDEX["component"] strIndex
|
|
|
|
lua_pushnil(l); // stack: LUA_REGISTRYINDEX["component"] strIndex nil
|
|
|
|
lua_rawset(l, -3); // stack: LUA_REGISTRYINDEX["component"]
|
2015-06-19 18:54:01 +08:00
|
|
|
}
|
2015-06-17 13:59:09 +08:00
|
|
|
}
|
|
|
|
|
2015-06-19 18:54:01 +08:00
|
|
|
void ComponentLua::getUserData()
|
2015-06-17 13:59:09 +08:00
|
|
|
{
|
2015-06-24 17:07:56 +08:00
|
|
|
lua_State *l = LuaEngine::getInstance()->getLuaStack()->getLuaState();
|
|
|
|
object_to_luaval<cocos2d::ComponentLua>(l, "cc.ComponentLua",this);
|
2015-06-17 13:59:09 +08:00
|
|
|
}
|
|
|
|
|
2015-06-19 18:54:01 +08:00
|
|
|
NS_CC_END
|