...menustart
...menuend
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
LuaState::LuaState(void) {
}
LuaState::~LuaState(void) {
}
void LuaState::Init() {
L = lua_open();
// load the libs
luaL_openlibs(L);
}
- sometime lua print function will not output to your engine's console
namespace {
int lua_print(lua_State * luastate) {
int nargs = lua_gettop(luastate);
std::string t;
for (int i=1; i <= nargs; i++)
{
if (lua_istable(luastate, i))
t += "table";
else if (lua_isnone(luastate, i))
t += "none";
else if (lua_isnil(luastate, i))
t += "nil";
else if (lua_isboolean(luastate, i))
{
if (lua_toboolean(luastate, i) != 0)
t += "true";
else
t += "false";
}
else if (lua_isfunction(luastate, i))
t += "function";
else if (lua_islightuserdata(luastate, i))
t += "lightuserdata";
else if (lua_isthread(luastate, i))
t += "thread";
else
{
const char * str = lua_tostring(luastate, i);
if (str)
t += lua_tostring(luastate, i);
else
t += lua_typename(luastate, lua_type(luastate, i));
}
if (i!=nargs)
t += "\t";
}
// HERE , replace with your engine's log function
CCLOG("[LUA-print] %s", t.c_str());
return 0;
}
} // namespace {
- register lua_print
// Register our version of the global "print" function
const luaL_reg global_functions [] = {
{"print", lua_print},
{NULL, NULL}
};
luaL_register(m_state, "_G", global_functions);
void LuaState::addSearchPath(const char* path)
{
lua_getglobal(m_state, "package"); /* L: package */
lua_getfield(m_state, -1, "path"); /* get package.path, L: package path */
const char* cur_path = lua_tostring(m_state, -1);
lua_pushfstring(m_state, "%s;%s/?.lua", cur_path, path); /* L: package path newpath */
lua_setfield(m_state, -3, "path"); /* package.path = newpath, L: package path */
lua_pop(m_state, 2); /* L: - */
}
-
tolua
-
tolua_fix.h/c
-
after exporting files via tolua, you should add the generated function
TOLUA_API int tolua_onyx_plus_open (lua_State* tolua_S);
to your Lua_state init function. -
tolua 传递 userdata 总是使用 指针,然后做相应的必须转换
*ptr
https://www8.cs.umu.se/kurser/TDBD12/VT04/lab/lua/tolua++.html
-
使用 TEMPLATE_BIND 实例化多个 binding
-
目前只支持 class level ,
- function level not support yet
-
example
struct TEST_A
{
Vector<LeaderBoardItem> m_LB_items ;
};
- 假设我们导出了 如上的 struct 的 m_LB_items 字段, 我们要对 m_LB_items 做 push_back 操作
- 因为 m_LB_items 是
Vector<LeaderBoardItem>
范型, 我们需要 对 Vector 类做 TEMPLATE_BIND
- 因为 m_LB_items 是
class Vector {
TEMPLATE_BIND(T, LeaderBoardItem )
void push_back(const T& element);
} ;
- call by lua
namespace.classname:functionname( ... )
- pkg 文件 函数声明 有用到 enum的情况,需要把 enum的定义也放入 pkg 文件
- C++
- only classes (and structs) with a constructor will have a 'new()' method
- You can add the constructor on your pkg (even if it's not actually implemented).
- C
- the only solution I can think of is to have a function that creates a new struct and returns it
- 使用 cocos2dx 的 tolua-fix 方法
- 在 .pkg 文件中, 使用
LUA_FUCNTION
( 实质是一个 int 类型 ) 声明一个handlevoid registerScriptHandler(int handler);
- tolua-fix 会 处理成一个 lua function ref
LUA_FUNCTION handler = ( toluafix_ref_function(tolua_S,2,0));
- 在 c++ 代码中 保存这个handle, 然后,使用 executeFunctionByHandler 来执行这个函数
- lua 方面的相关调用
local shs = ScriptHandlerSample()
shs:registerScriptHandler( function() print("lua callback"); end )
- c++ 获取 lua 方法 返回值 , 或 变量值
- cocos2dx 提供 executeString 可以完成大部分事情
- 执行一段lua 代码
- executeString( "lua_code_string" )
- 获取 lua 变量值 (目前值支持 number/boolean 返回)
- executeString ( "require 'modulename' ;return modulename.varname" )
- 获取 lua 函数返回值
- executeString ( "require 'modulename' ;return modulename.funcname()" )
- 执行一段lua 代码
- https://segmentfault.com/a/1190000004252394
- android 平台的线程问题
- 一般 lua会在 非UI working 线程中调用 (如 GL线程)
- java 的一些callback,一般都是在 UI线程中执行,这时如果要调用lua方法,就需要 在正确的线程中调用
- 如果可以容忍阻塞,可以使用 线程安全的 ConcurrentLinkedQueue, 在 GL线程中把结果取回,再调用 lua 方法
- cocos2dx 提供了 luaj.callStaticMethod , 可以 调用 静态java 方法
-
- 使用 cocos2dx 提供的 callLuaGlobalFunctionWithString 直接调用 全局lua 方法
-
- 使用 cocos2dx 提供的 callLuaFunctionWithString, 通过 luaFunctionId 来调用 保存的 lua 方法
- 调用两次 java 方法
- 第一次, 注册 lua 方法,
- lua方法作为 参数 调用java 方法, c++层做处理, java 方法只需要
final int luaFunc
接受
- lua方法作为 参数 调用java 方法, c++层做处理, java 方法只需要
- 第二次, 调用 业务 Java 方法, 在这个业务java 方法中,使用 callLuaFunctionWithString 来调用 lua