#ifndef NETMSGHANDLER_H #define NETMSGHANDLER_H #include #include #include #include #include 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 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 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; 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 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