f8/f8/msgqueue.cc
aozhiwei 6ca822b2c7 1
2022-12-17 15:24:46 +08:00

220 lines
5.9 KiB
C++

#include <assert.h>
#include <mutex>
#include <a8/a8.h>
#include <f8/f8.h>
#include <f8/timer.h>
#include <f8/msgqueue.h>
namespace f8
{
struct MsgQueueNode
{
struct list_head entry;
MsgHandleFunc func;
};
struct IMMsgNode
{
unsigned short msgid;
const a8::Args args;
IMMsgNode* next = nullptr;
IMMsgNode(const a8::Args& args1):args(std::move(args1))
{
}
};
class MsgQueueImp
{
public:
int curr_im_msgid = 10000;
std::map<int, list_head> msg_handlers;
std::mutex im_msg_mutex_;
IMMsgNode* im_top_node_ = nullptr;
IMMsgNode* im_bot_node_ = nullptr;
IMMsgNode* im_work_node_ = nullptr;
~MsgQueueImp()
{
for (auto& pair : msg_handlers) {
while (!list_empty(&pair.second)) {
MsgQueue::Instance()->RemoveCallBack(pair.second.next);
}
}
}
#if 0
void ProcessMsg(int msgid, const a8::XParams& param)
{
auto itr = msg_handlers.find(msgid);
if (itr != msg_handlers.end()) {
list_head* head = &itr->second;
struct MsgQueueNode *node = nullptr;
struct MsgQueueNode *tmp = nullptr;
list_for_each_entry_safe(node, tmp, head, entry) {
node->func(param);
}
}
}
#endif
CallBackHandle RegisterCallBack(int msgid, MsgHandleFunc handle_func)
{
MsgQueueNode* node = new MsgQueueNode();
INIT_LIST_HEAD(&node->entry);
node->func = handle_func;
auto itr = msg_handlers.find(msgid);
if (itr == msg_handlers.end()) {
msg_handlers[msgid] = list_head();
itr = msg_handlers.find(msgid);
assert(itr != msg_handlers.end());
INIT_LIST_HEAD(&itr->second);
}
list_add_tail(&node->entry, &itr->second);
return &node->entry;
}
};
void MsgQueue::Init()
{
imp_ = std::make_shared<MsgQueueImp>();
}
void MsgQueue::UnInit()
{
#if 0
im_msg_mutex_->lock();
if (!im_work_node_) {
im_work_node_ = im_top_node_;
im_top_node_ = nullptr;
im_bot_node_ = nullptr;
}
while (im_work_node_) {
IMMsgNode* pdelnode = im_work_node_;
im_work_node_ = im_work_node_->next;
if (pdelnode->msgid == f8::IM_SysMsgQueue) {
a8::XParams* param = (a8::XParams*)pdelnode->params.param1.GetUserData();
delete param;
}
delete pdelnode;
if (!im_work_node_) {
im_work_node_ = im_top_node_;
im_top_node_ = nullptr;
im_bot_node_ = nullptr;
}
}
im_msg_mutex_->unlock();
#endif
}
void MsgQueue::Update()
{
#if 0
if (!im_work_node_ && im_top_node_) {
im_msg_mutex_->lock();
im_work_node_ = im_top_node_;
im_top_node_ = nullptr;
im_bot_node_ = nullptr;
im_msg_mutex_->unlock();
}
while (im_work_node_) {
IMMsgNode *pdelnode = im_work_node_;
switch (im_work_node_->msgid) {
case f8::IM_SysMsgQueue:
{
const a8::XParams* param = (const a8::XParams*)pdelnode->params.param1.GetUserData();
f8::MsgQueue::Instance()->ProcessMsg(pdelnode->params.sender.GetInt(),
*param
);
delete param;
}
break;
case IM_ClientSocketDisconnect:
{
PlayerMgr::Instance()->OnClientDisconnect(pdelnode->params);
}
break;
case IM_ExecGM:
{
HandlerMgr::Instance()->ProcGMMsg(pdelnode->params.param3,
pdelnode->params.sender,
pdelnode->params.param1.GetString(),
pdelnode->params.param2.GetString()
);
}
break;
}
im_work_node_ = im_work_node_->next;
delete pdelnode;
}
#endif
}
bool MsgQueue::HasMsg()
{
#if 0
if (!im_work_node_) {
im_msg_mutex_.lock();
if (!im_work_node_ && im_top_node_) {
im_work_node_ = im_top_node_;
im_top_node_ = nullptr;
im_bot_node_ = nullptr;
}
im_msg_mutex_.unlock();
}
if (im_work_node_) {
return true;
}
#endif
}
void MsgQueue::RemoveCallBack(CallBackHandle handle)
{
list_head* head = handle;
MsgQueueNode* node = list_entry(head, struct MsgQueueNode, entry);
list_del_init(&node->entry);
delete node;
}
CallBackHandle MsgQueue::RegisterCallBack(int msgid, MsgHandleFunc handle_func)
{
return imp_->RegisterCallBack(msgid, handle_func);
}
int MsgQueue::AllocIMMsgId()
{
int custom_im_msgid = ++imp_->curr_im_msgid;
return custom_im_msgid;
}
void MsgQueue::PostMsg(int msgid, const a8::Args args)
{
#if 0
IMMsgNode *p = new IMMsgNode;
p->msgid = imcmd;
p->params = params;
p->next = nullptr;
im_msg_mutex_->lock();
if (im_bot_node_) {
im_bot_node_->next = p;
im_bot_node_ = p;
} else {
im_top_node_ = p;
im_bot_node_ = p;
}
im_msg_mutex_->unlock();
NotifyLoopCond();
#endif
}
}