220 lines
5.9 KiB
C++
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
|
|
}
|
|
|
|
}
|