这篇我们注册2个类来测试下LuaBridge的使用,在开始之前我们先在上篇的基础上来用C++调用下lua的函数。我们添加一个main.lua文件到资源文件夹下。lua代码如下:
1 function init() 2 print(1) 3 end
然后,在initscript()函数添加以下代码:
1 std::string filePath = FileUtils::getInstance()->fullPathForFilename("main.lua"); 2 int ret = luaL_dofile(m_luastate, filePath.c_str()); 3 if (!ret) 4 { 5 runLuaFunc("init"); 6 }
runLuaFunc函数如下:
void HelloWorld::runLuaFunc(std::string funcName) { auto lua_func = new luabridge::LuaRef(getGlobal(m_luastate, funcName.c_str())); try { if (lua_func->isFunction()) { (*lua_func)(); } } catch (LuaException& e) { CCLog("%s", e.what()); } }
ok,调用成功。。。
下面添加一个类,UIManage类,用于添加UI和注册控件事件。。。
我们把initscript和runluafunc函数移到UIManage类里面。修改initscript函数如下:
1 void UIManage::initScript() 2 { 3 m_luastate = luaL_newstate(); 4 luaL_openlibs(m_luastate); 5 6 getGlobalNamespace(m_luastate) 7 8 .beginNamespace("game") 9 10 .beginClass<Widget>("Widget") 11 .addFunction("getChildByTag", &Widget::getChildByTag) 12 .endClass() 13 14 .beginClass<UIManage>("UIManage") 15 .addStaticFunction("instance", &UIManage::getIntance) 16 .addFunction("addWidget", &UIManage::addWidget) 17 .endClass() 18 19 .endNamespace() 20 21 ; 22 23 std::string filePath = FileUtils::getInstance()->fullPathForFilename("main.lua"); 24 int ret = luaL_dofile(m_luastate, filePath.c_str()); 25 if (!ret) 26 { 27 runLuaFunc("init"); 28 } 29 else 30 { 31 CCLog("lua error: %s", lua_tostring(m_luastate, -1)); 32 } 33 }
我们注册getinstance和addWidget函数到Lua中,然后在main.lua如下:
UIManage = game.UIManage:instance() init = function() local pnl = UIManage:addWidget("LoginUI/LoginUI.ExportJson") end
首先获得UIManage单例类,然后调用函数addWidget,OK,发现成功添加界面。
补充:调用代码如下。。。
void HelloWorld::onEnter() { Layer::onEnter(); UIManage::getIntance()->initScript(); }
下面就给界面的控件添加事件。。。。
添加函数如下( void addTouchEventListener(ccWidgetTouchCallback callback)):
1 void UIManage::addEventListen(Widget* ui, std::string funcName) 2 { 3 std::string beginName = funcName + "_begin"; 4 std::string moveName = funcName + "_move"; 5 std::string endName = funcName + "_end"; 6 std::string cancelName = funcName + "_cancel"; 7 8 auto beginFunc = new LuaRef(getGlobal(m_luastate, beginName.c_str())); 9 auto moveFunc = new LuaRef(getGlobal(m_luastate, moveName.c_str())); 10 auto endFunc = new LuaRef(getGlobal(m_luastate, endName.c_str())); 11 auto cancelFunc = new LuaRef(getGlobal(m_luastate, cancelName.c_str())); 12 13 ui->addTouchEventListener([beginFunc, moveFunc, endFunc, cancelFunc](Ref* ref, Widget::TouchEventType type) 14 { 15 switch (type) 16 { 17 case cocos2d::ui::Widget::TouchEventType::BEGAN: 18 if (beginFunc->isFunction()) 19 { 20 (*beginFunc)(); 21 } 22 break; 23 case cocos2d::ui::Widget::TouchEventType::MOVED: 24 if (moveFunc->isFunction()) 25 { 26 (*moveFunc)(); 27 } 28 break; 29 case cocos2d::ui::Widget::TouchEventType::ENDED: 30 if (endFunc->isFunction()) 31 { 32 (*endFunc)(); 33 } 34 break; 35 case cocos2d::ui::Widget::TouchEventType::CANCELED: 36 if (cancelFunc->isFunction()) 37 { 38 (*cancelFunc)(); 39 } 40 break; 41 } 42 }); 43 }
注册到lua中
1 .addFunction("addEventListen",&UIManage::addEventListen)
Lua代码注册事件如下:
1 --事件 2 clcickEvent = 3 { 4 ends = function() 5 print(1) 6 end 7 } 8 9 init = function() 10 local pnl = UIManage:addWidget("LoginUI/LoginUI.ExportJson") 11 addEvent(pnl,clcickEvent) --添加事件 12 UIManage:addEventListen(pnl,"pnl") 13 end 14 15 16 17 addEvent = function(ui,event) 18 _G["pnlends"] = event.ends --全局表里 c++代码中直接访问pnlends调用event.ends 19 end
OK,事件调用成功