]> git.mxchange.org Git - flightgear.git/commitdiff
Multiplayer client/server system -- Message base class, "hello" message, and message...
authorcvsguest <cvsguest>
Sat, 8 Nov 2003 20:11:14 +0000 (20:11 +0000)
committercvsguest <cvsguest>
Sat, 8 Nov 2003 20:11:14 +0000 (20:11 +0000)
src/Server/message.cxx
src/Server/message.hxx
src/Server/msg_0001_hello.cxx
src/Server/msg_0001_hello.hxx
src/Server/msgtest.cxx

index e06964c5e673abd5f1401e37b8ecc5808c4f6cce..1844b434c5f7507b07f839dbbf2796aefa224aca 100644 (file)
@@ -22,6 +22,8 @@
 \r
 #include "message.hxx"\r
 \r
+FGMPSInstanceFuncMap   FGMPSMessage::funcmap;\r
+\r
 FGMPSMessage::FGMPSMessage() \r
 {\r
        msgid = 0x0000;\r
@@ -30,5 +32,118 @@ FGMPSMessage::FGMPSMessage()
        \r
 }\r
 \r
+string FGMPSMessage::encodemsg()\r
+{\r
+       FGMPSMsgElementEntry* ptr = getelements();\r
+\r
+       buf.clr();\r
+       if (msgid > 255) {\r
+               buf.put(fgmps_som16, true);\r
+               buf.write2(&msgid);\r
+       } else {\r
+               buf.put(fgmps_som8, true);\r
+               buf.write1(&msgid);\r
+       }\r
+       while (ptr->type != fgmps_null) {\r
+               buf.put(ptr->type, true);\r
+               //printf ("adding %02x\n", ptr->type);\r
+               switch (ptr->type) {\r
+               case fgmps_uchar:\r
+               case fgmps_char:\r
+                       buf.write1(ptr->data);\r
+                       break;\r
+               case fgmps_uint:\r
+               case fgmps_int:\r
+                       buf.write2(ptr->data);\r
+                       break;\r
+               case fgmps_ulong:\r
+               case fgmps_long:\r
+                       buf.write4(ptr->data);\r
+                       break;\r
+               case fgmps_float:\r
+                       buf.writef(*(float*)ptr->data);\r
+                       break;\r
+               case fgmps_double:\r
+                       buf.writed(*(double*)ptr->data);\r
+                       break;\r
+               case fgmps_string:\r
+                       buf.writes(*(string*)ptr->data);\r
+                       break;\r
+               }\r
+               ptr++;\r
+       }\r
+\r
+       buf.put(fgmps_eom, true);\r
+\r
+       return buf.str();\r
+}\r
+\r
+FGMPSMessage* FGMPSMessage::decodemsg(string msg)\r
+{\r
+       FGMPSMessageBuf                 buf;\r
+       unsigned char                   ch;\r
+       unsigned int                    mid;\r
+       FGMPSInstanceFuncMap::iterator  fmitr;\r
+\r
+       buf.set(msg);\r
+       buf.ofs(0);\r
+       ch = buf.get(true);\r
+       if (ch != fgmps_som8 && ch != fgmps_som16) {\r
+               throw FGMPSDataException("Invalid start of message");\r
+       }\r
+       if (ch == fgmps_som8) {\r
+               ch = buf.get();\r
+               mid = ch;\r
+       } else {\r
+               mid = *(unsigned int *)buf.read2();\r
+       }\r
+       \r
+       fmitr = funcmap.find(mid);\r
+       if (fmitr == funcmap.end()) {\r
+               throw FGMPSDataException("MessageID has no registered Message Class");\r
+       }\r
+       FGMPSMessage* msgclass = (fmitr->second)();\r
+       FGMPSMsgElementEntry* elements = msgclass->getelements();\r
+       while ((ch = buf.get()) != fgmps_eom) {\r
+               //printf("dump: ");\r
+               //for (int i=-1; i<16; i++) printf("%02x ", buf.peek(i));\r
+               //printf("\n");\r
+\r
+               if (ch != elements->type) {\r
+                       delete msgclass;\r
+                       throw FGMPSDataException("Decode: Message Structure Error");\r
+               }\r
+               switch (ch) {\r
+               case fgmps_uchar:\r
+               case fgmps_char:\r
+                       memcpy(elements->data, buf.read1(), 1);\r
+                       break;\r
+               case fgmps_uint:\r
+               case fgmps_int:\r
+                       memcpy(elements->data, buf.read2(), 2);\r
+                       break;\r
+               case fgmps_ulong:\r
+               case fgmps_long:\r
+                       memcpy(elements->data, buf.read4(), 4);\r
+                       break;\r
+               case fgmps_float:\r
+                       *(float*)elements->data = buf.readf();\r
+                       break;\r
+               case fgmps_double:\r
+                       *(double*)elements->data = buf.readd();\r
+                       break;\r
+               case fgmps_string:\r
+                       ch = buf.get();\r
+                       *(string*)elements->data = buf.reads(ch);\r
+                       break;\r
+               default:\r
+                       delete msgclass;\r
+                       throw FGMPSDataException("Decode: Unknown data type");\r
+                       break;\r
+               }\r
+               elements++;\r
+       }\r
+       return msgclass;\r
+}\r
 \r
 \r
index 35c7e51112ec9daedd4ab929444dae95793cbdae..30daf9f81f86443641dc730be58f3073d5b9091e 100644 (file)
 \r
 #include STL_STRING\r
 #include <stdexcept>\r
+#include <map>\r
 \r
 SG_USING_STD(string);\r
 SG_USING_STD(invalid_argument);\r
+SG_USING_STD(map);\r
 \r
 #include "messagebuf.hxx"\r
 \r
@@ -62,22 +64,35 @@ typedef struct
 \r
 #define FGMPSMsgElementArrayEnd {fgmps_null, 0}\r
 \r
+class FGMPSMessage;\r
+\r
+typedef FGMPSMessage* FGMPSMessagePtr;\r
+typedef FGMPSMessagePtr (*FGMPSMsgInstanceFunc)(void);\r
+\r
+typedef map<unsigned int, FGMPSMsgInstanceFunc> FGMPSInstanceFuncMap;\r
+\r
 class FGMPSMessage\r
 {\r
 private:\r
+       static FGMPSInstanceFuncMap     funcmap;\r
        FGMPSMsgElementEntry            elements[1];\r
-       static unsigned int             msgid;\r
 protected:\r
-       FGMPSMessageBuf                 msg;\r
+       FGMPSMessageBuf         buf;\r
+       unsigned int            msgid;\r
 public:\r
+       static int registermsg(int msgid, FGMPSMsgInstanceFunc func)\r
+       {\r
+               funcmap[msgid] = func;\r
+       }\r
+\r
        FGMPSMessage();\r
        ~FGMPSMessage() {}\r
 \r
-       virtual string                  encodemsg() {}\r
-       virtual FGMPSMessage*           decodemsg(string msg) {}\r
-       virtual FGMPSMsgElementEntry*   getelements() { return elements; }\r
-       virtual unsigned int            getmessageid() { return msgid; }\r
+       string                  encodemsg();\r
+       static FGMPSMessage*    decodemsg(string msg);\r
+       unsigned int            getmessageid() { return msgid; }\r
 \r
+       virtual FGMPSMsgElementEntry*   getelements() { return elements; }\r
 };\r
 \r
 #endif\r
index a0fad4ea98a41e1b4f1be02a1f5eedcd60136355..d2ff507148dfb5c56f828eba329722119975a7d4 100644 (file)
 \r
 FGMPSMsg0001Hello::FGMPSMsg0001Hello() \r
 {\r
-       msgid = 0x0001;\r
-       elements[0].type = fgmps_uint;          elements[0].data = &this->vermajor;     \r
-       elements[1].type = fgmps_uint;          elements[0].data = &this->verminor;     \r
-       elements[2].type = fgmps_uint;          elements[0].data = &this->verpatch;     \r
-       elements[3].type = fgmps_string;        elements[0].data = &this->servname;     \r
+       msgid = FGMPSMsg0001HelloID;\r
+       elements[0].type = fgmps_uint;          elements[0].data = &vermajor;   \r
+       elements[1].type = fgmps_uint;          elements[1].data = &verminor;   \r
+       elements[2].type = fgmps_uint;          elements[2].data = &verpatch;   \r
+       elements[3].type = fgmps_string;        elements[3].data = &servname;   \r
        elements[4].type = fgmps_null;          elements[4].data = NULL;        \r
 }\r
 \r
index 9da5bd323e5e5706cad77f5824aafda3174eb4cd..a1472cbf70898be48df52e6572bb32e6bc72b11a 100644 (file)
 \r
 #include "message.hxx"\r
 \r
-class FGMPSMsg0001Hello\r
+#define FGMPSMsg0001HelloID 0x0001\r
+\r
+class FGMPSMsg0001Hello: public FGMPSMessage\r
 {\r
 private:\r
        FGMPSMsgElementEntry            elements[5];\r
-       unsigned int                    msgid;\r
 public:\r
-       FGMPSMsg0001Hello();\r
-       ~FGMPSMsg0001Hello() {}\r
 \r
-       virtual string                  encodemsg() {}\r
-       virtual FGMPSMessage*           decodemsg(string msg) {}\r
+       static void registerme() \r
+       { \r
+               FGMPSMessage::registermsg(FGMPSMsg0001HelloID, &FGMPSMsg0001Hello::instance);\r
+       }\r
+\r
+       static FGMPSMessage* instance() { return (FGMPSMessage*) new FGMPSMsg0001Hello; }\r
+\r
        virtual FGMPSMsgElementEntry*   getelements() { return elements; }\r
-       virtual unsigned int            getmessageid() { return msgid; }\r
+\r
+       FGMPSMsg0001Hello();\r
+       ~FGMPSMsg0001Hello() {}\r
 \r
        unsigned int    vermajor;\r
        unsigned int    verminor;\r
index 96248a6fe1ef321fc8303a387a2f1a104325bed6..6130463a65b029f4069f94c77a1e432a65e24ead 100644 (file)
@@ -1,6 +1,40 @@
-#include "messagebuf.hxx"\r
+#include "msg_0001_hello.hxx"\r
 \r
 main(int argc, char **argv)\r
 {\r
-       printf("Hello\n");\r
+       string                  str;\r
+       FGMPSMsg0001Hello       msg1, *msg2;\r
+\r
+       FGMPSMsg0001Hello::registerme();\r
+\r
+       msg1.vermajor = 3;\r
+       msg1.verminor = 7;\r
+       msg1.verpatch = 42;\r
+       msg1.servname = "test";\r
+\r
+       str = msg1.encodemsg();\r
+\r
+       printf("Message ID = %ui\n", msg1.getmessageid());\r
+       printf("major = %u\n", msg1.vermajor);\r
+       printf("minor = %u\n", msg1.verminor);\r
+       printf("patch = %u\n", msg1.verpatch);\r
+       printf("sname = %s\n", msg1.servname.c_str());\r
+\r
+       printf("dump: ");\r
+       for (int i=0; i<str.length(); i++) printf("%02x ", (unsigned char)str[i]);\r
+       printf("\n");\r
+\r
+       try {\r
+               msg2 = (FGMPSMsg0001Hello*)FGMPSMessage::decodemsg(str);\r
+       } catch (FGMPSDataException e) {\r
+               printf("Exception: %s\n", e.what());\r
+               exit(1);\r
+       }\r
+\r
+       printf("Message ID = %u\n", msg2->getmessageid());\r
+       printf("major = %u\n", msg2->vermajor);\r
+       printf("minor = %u\n", msg2->verminor);\r
+       printf("patch = %u\n", msg2->verpatch);\r
+       printf("sname = %s\n", msg2->servname.c_str());\r
+       \r
 }\r