f8/cpp/netmsghandler.h
2018-08-03 19:57:13 +08:00

90 lines
2.6 KiB
C++

#ifndef NETMSGHANDLER_H
#define NETMSGHANDLER_H
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/unknown_field_set.h>
const unsigned short MAX_MSG_ID = 2000;
struct MsgHdr;
struct NetMsgHandler
{
int handlerid;
const ::google::protobuf::Message* prototype = nullptr;
};
struct NetMsgHandlerObject
{
NetMsgHandler* handlers[MAX_MSG_ID] = { nullptr };
};
template<typename InstanceType, typename MsgType>
static void NetMsgHandlerWrapper(InstanceType* instance, MsgHdr& hdr, NetMsgHandler* handler)
{
MsgType msg;
bool ok = msg.ParseFromArray(hdr.buf + hdr.offset, hdr.buflen - hdr.offset);
assert(ok);
if (ok) {
struct Invoker: public NetMsgHandler
{
void (*wrapper)(InstanceType*, MsgHdr&, NetMsgHandler*);
void (InstanceType::*func)(MsgHdr&, const MsgType&);
};
Invoker* invoker = (Invoker*)handler;
auto ptr = invoker->func;
(instance->*ptr)(hdr, msg);
}
}
template<typename InstanceType, typename MsgType>
static void RegisterNetMsgHandler(NetMsgHandlerObject* msghandler,
void (InstanceType::*ptr)(MsgHdr&, const MsgType&)
)
{
MsgType dumy_msg;
static int msgid = ::Net_GetMessageId(dumy_msg);
assert(msgid >= 0 || msgid < MAX_MSG_ID);
if (msgid < 0 || msgid >= MAX_MSG_ID) {
abort();
}
struct Invoker: public NetMsgHandler
{
void (*wrapper)(InstanceType*, MsgHdr&, NetMsgHandler*);
void (InstanceType::*func)(MsgHdr&, const MsgType&);
};
Invoker *p = new Invoker();
p->wrapper = &NetMsgHandlerWrapper<InstanceType, MsgType>;
p->func = ptr;
p->handlerid = InstanceType::HID;
p->prototype = ::google::protobuf::MessageFactory::generated_factory()->GetPrototype(MsgType::descriptor());
msghandler->handlers[msgid] = p;
}
template<typename InstanceType>
static bool ProcessNetMsg(NetMsgHandler* handler,
InstanceType* instance,
MsgHdr& hdr)
{
if(handler){
struct Invoker: public NetMsgHandler
{
void (*wrapper)(InstanceType*, MsgHdr&, NetMsgHandler*);
void* func;
};
Invoker *p = (Invoker*)handler;
p->wrapper(instance, hdr, p);
return true;
}else{
return false;
}
}
NetMsgHandler* GetNetMsgHandler(NetMsgHandlerObject* handlers,
unsigned short msgid);
#endif