114 lines
3.7 KiB
C++
114 lines
3.7 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>
|
|
|
|
namespace f8
|
|
{
|
|
const unsigned short MAX_MSG_ID = 2000;
|
|
|
|
struct MsgHdr;
|
|
typedef bool (*CUSTOM_PARSER)(MsgHdr&, google::protobuf::Message*);
|
|
|
|
struct NetMsgHandler
|
|
{
|
|
int handlerid;
|
|
const ::google::protobuf::Message* prototype = nullptr;
|
|
CUSTOM_PARSER custom_parser = nullptr;
|
|
};
|
|
|
|
struct NetMsgHandlerObject
|
|
{
|
|
NetMsgHandler* handlers[MAX_MSG_ID] = { nullptr };
|
|
|
|
~NetMsgHandlerObject()
|
|
{
|
|
for (size_t i = 0; i < MAX_MSG_ID; ++i) {
|
|
if (handlers[i]) {
|
|
delete handlers[i];
|
|
handlers[i] = nullptr;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
template<typename InstanceType, typename MsgType>
|
|
static void NetMsgHandlerWrapper(InstanceType* instance, MsgHdr& hdr, NetMsgHandler* handler)
|
|
{
|
|
MsgType msg;
|
|
bool ok = false;
|
|
if (handler->custom_parser) {
|
|
ok = handler->custom_parser(hdr, &msg);
|
|
} else {
|
|
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&),
|
|
CUSTOM_PARSER custom_parser = nullptr
|
|
)
|
|
{
|
|
MsgType dumy_msg;
|
|
static int msgid = f8::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->custom_parser = custom_parser;
|
|
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);
|
|
|
|
void DumpMsgToLog(f8::MsgHdr& hdr, f8::NetMsgHandler* handler, const char* prefix);
|
|
void DumpMsgToLog(const ::google::protobuf::Message& msg, const char* prefix);
|
|
}
|
|
#endif
|