Cocos2d在Lua层实现观察者模式

记录下我使用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()
{
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值