记录下我使用cocos2dx(C++/Lua混合)开发项目,实现的一个Lua端的消息分发器
功能:接收C++发送过来的消息,并在lua端分发
Lua端代码:
local msgManger = class("msgManger")
-- msgInfoT={
-- cpp_lua_key=nil,
-- lua_ptr=nil,
-- lua_fx=nil£,
-- cpp_ptr=nil
--}
--初始化容器
function msgManger:init()
if self.msgTable==nil then
self.msgTable={}
end
end
--处理分发C++传递过来的消息
--msg:C++端 TKLuaCallBackData 指针
function msgManger:cppCallBack(msg)
--msg不能为空 消息的分发需要 msg:msgKey()获取消息名称
if msg==nil then
print("msgManger cppCallBack msg is nil")
return
else
print("msgManger rec c++ msg"..msg:msgKey())
end
--dispatch
for key, value in pairs(self.msgTable) do
if value and value.lua_ptr then
if value.cpp_lua_key==msg:msgKey() then
--print('msgManger:'..key)
value.lua_fx(value.lua_ptr,msg)
end
end
end
end
--注册监听
function msgManger:registerMsg(cpp_lua_key,lua_ptr,lua_fx,cpp_ptr)
--cpp_lua_key:消息的名称,和C++通知对应消息的名称一致
--lua_ptr:lua类的self
--lua_fx:lua类的回调函数
--cpp_ptr:C++中回调lua类的指针
if cpp_lua_key~=nil and lua_ptr~=nil and lua_fx~=nil then
local tmpInfo={}
tmpInfo['cpp_lua_key']=cpp_lua_key
tmpInfo['lua_ptr']=lua_ptr
tmpInfo['lua_fx']=lua_fx
if cpp_ptr then
tmpInfo['cpp_ptr']=cpp_ptr
else
tmpInfo['cpp_ptr']=tk.TKLuaCallBackPtr:getInstance()
end
local key = lua_ptr.__cname..'--'..cpp_lua_key
self.msgTable[key]=tmpInfo
--
print('msgManger add:'..key)
local function cppCallBack(msg)
self:cppCallBack(msg)
end
ScriptHandlerMgr:getInstance():registerScriptHandler(tmpInfo['cpp_ptr'],cppCallBack, cc.Handler.CALLFUNC);
else
print('register func failed')
end
end
--删除消息监听
function msgManger:removeMsg(lua_ptr,cpp_lua_key)
--lua_ptr: lua类的self
--cpp_lua_key 回调事件的key值(可省略,省略时删除整个lua类的监听)
if lua_ptr==nil then
return
end
local suffix = lua_ptr.__cname
if cpp_lua_key then
local skey = suffix..'--'..cpp_lua_key
for key, value in pairs(self.msgTable) do
if skey==key then
print("msgManger remove "..key)
ScriptHandlerMgr:getInstance():unregisterScriptLister(value.cpp_ptr,value.lua_fx,cc.Handler.CALLFUNC)
self.msgTable[key]=nil
end
end
else
local tmpArr = {}
for key, value in pairs(self.msgTable) do
if value and value.lua_ptr.__cname==suffix then
print("msgManger remove "..key)
table.insert(tmpArr,key)
end
end
for k= 1, #tmpArr do
local aa = self.msgTable[tmpArr[k]]
ScriptHandlerMgr:getInstance():unregisterScriptLister(aa.cpp_ptr,aa.lua_fx,cc.Handler.CALLFUNC)
self.msgTable[tmpArr[k]]=nil
end
end
end
return msgManger
C++发送消息示例:
TKLuaCallBackData::xxyy(this,key);
this是一个继承cocos2d::Ref 的类;
key是消息名称;
其中TKLuaCallBackData类(此类的功能是把C++的消息发送给Lua)的实现如下:
TKLuaCallBackData.h文件
#ifndef __TKLuaCallBackData__
#define __TKLuaCallBackData__
#include "TKPrefix.h"
class TKLuaCallBackData:public Ref
{
public:
TKLuaCallBackData();
~TKLuaCallBackData();
TKLuaCallBackData(std::string msg_key, int id, int value);
int id();//for lua
std::string msgKey();//for lua
int value();//for lua
static void callBackLua(std::string msg_key);
static void callBackLua(std::string msg_key, int id);
//self is base class use
static void xxyy(Ref *, std::string msg_key, int id = 0);
//base class is Ref use
private:
static void callLuaFunc(Ref *ref, std::string msg_key, int id = 0, int value = 0);
private:
int m_id = 0;
std::string m_msg_key = "";
//c++ tell lua update key
int m_value = 0;
};
#endif /* __TKLuaCallBackData__ */
TKLuaCallBackData.cpp文件
#include "TKLuaCallBackData.h"
#include "TKLuaCallBackPtr.h"
#include "CCLuaEngine.h"
TKLuaCallBackData::TKLuaCallBackData()
:m_id(0), m_msg_key(""), m_value(0)
{
}
TKLuaCallBackData::~TKLuaCallBackData()
{
}
TKLuaCallBackData::TKLuaCallBackData(std::string msg_key, int id, int value)
:m_id(id), m_msg_key(msg_key), m_value(value)
{
}
int TKLuaCallBackData::id()
{
return m_id;
}
std::string TKLuaCallBackData::msgKey()
{
return m_msg_key;
}
int TKLuaCallBackData::value()
{
return m_value;
}
void TKLuaCallBackData::callBackLua(std::string msg_key)
{
TKLuaCallBackData::callLuaFunc(TKLuaCallBackPtr::getInstance(), msg_key);
}
void TKLuaCallBackData::callBackLua(std::string msg_key, int id)
{
TKLuaCallBackData::callLuaFunc(TKLuaCallBackPtr::getInstance(), msg_key, id);
}
void TKLuaCallBackData::xxyy(Ref *ref, std::string msg_key,int id)
{
TKLuaCallBackData::callLuaFunc(ref, msg_key, id);
}
void TKLuaCallBackData::callLuaFunc(Ref *ref, std::string msg_key, int id, int value)
{
TKLuaCallBackData tmpData(msg_key, id, value);
BasicScriptData data(ref, &tmpData);
ScriptEvent eve(kCallFuncEvent, &data); //kCallFuncEvent
//设置传递事件的类型
auto engine = LuaEngine::getInstance();
LuaEngine::getInstance()->sendEvent(&eve);
}
TKLuaCallBackPtr(单例类,C++/Lua通讯默认的桥接参数)的实现如下:
#ifndef __TKLuaCallBackPtr__
#define __TKLuaCallBackPtr__
#include "TKPrefix.h"
class TKLuaCallBackPtr:public Ref
{
public:
TKLuaCallBackPtr();
~TKLuaCallBackPtr();
static TKLuaCallBackPtr *getInstance();
};
#endif /* __TKLuaCallBackPtr__ */
#include "TKLuaCallBackPtr.h"
static TKLuaCallBackPtr *instance = nullptr;
TKLuaCallBackPtr *TKLuaCallBackPtr::getInstance()
{
if (!instance)
{
instance = new TKLuaCallBackPtr();
}
return instance;
}
TKLuaCallBackPtr::TKLuaCallBackPtr()
{
}
TKLuaCallBackPtr::~TKLuaCallBackPtr()
{
}