#ifndef NETMSGHANDLER_H #define NETMSGHANDLER_H #include #include #include #include #include namespace f8 { 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 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 static void RegisterNetMsgHandler(NetMsgHandlerObject* msghandler, void (InstanceType::*ptr)(MsgHdr&, const MsgType&) ) { 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->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