connectionStringTable.cc 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "network/connectionProtocol.h"
  24. #include "sim/simBase.h"
  25. #include "network/netConnection.h"
  26. #include "io/bitStream.h"
  27. #include "console/consoleTypes.h"
  28. class NetStringEvent : public NetEvent
  29. {
  30. NetStringHandle mString;
  31. U32 mIndex;
  32. public:
  33. NetStringEvent(U32 index = 0, NetStringHandle string = NetStringHandle())
  34. {
  35. mIndex = index;
  36. mString = string;
  37. }
  38. virtual void pack(NetConnection* /*ps*/, BitStream *bstream)
  39. {
  40. bstream->writeInt(mIndex, ConnectionStringTable::EntryBitSize);
  41. bstream->writeString(mString.getString());
  42. }
  43. virtual void write(NetConnection* /*ps*/, BitStream *bstream)
  44. {
  45. bstream->writeInt(mIndex, ConnectionStringTable::EntryBitSize);
  46. bstream->writeString(mString.getString());
  47. }
  48. virtual void unpack(NetConnection* /*con*/, BitStream *bstream)
  49. {
  50. char buf[256];
  51. mIndex = bstream->readInt(ConnectionStringTable::EntryBitSize);
  52. bstream->readString(buf);
  53. mString = NetStringHandle(buf);
  54. }
  55. virtual void notifyDelivered(NetConnection *ps, bool madeit)
  56. {
  57. if(madeit)
  58. ps->confirmStringReceived(mString, mIndex);
  59. }
  60. virtual void process(NetConnection *connection)
  61. {
  62. Con::printf("Mapping string: %s to index: %d", mString.getString(), mIndex);
  63. connection->mapString(mIndex, mString);
  64. }
  65. #ifdef TORQUE_DEBUG_NET
  66. const char *getDebugName()
  67. {
  68. static char buffer[512];
  69. dSprintf(buffer, sizeof(buffer), "%s - \"", getClassName());
  70. expandEscape(buffer + dStrlen(buffer), mString.getString());
  71. dStrcat(buffer, "\"");
  72. return buffer;
  73. }
  74. #endif
  75. DECLARE_CONOBJECT(NetStringEvent);
  76. };
  77. IMPLEMENT_CO_NETEVENT_V1(NetStringEvent);
  78. //--------------------------------------------------------------------
  79. ConnectionStringTable::ConnectionStringTable(NetConnection *parent)
  80. {
  81. mParent = parent;
  82. for(U32 i = 0; i < EntryCount; i++)
  83. {
  84. mEntryTable[i].nextHash = NULL;
  85. mEntryTable[i].nextLink = &mEntryTable[i+1];
  86. mEntryTable[i].prevLink = &mEntryTable[i-1];
  87. mEntryTable[i].index = i;
  88. mHashTable[i] = NULL;
  89. }
  90. mLRUHead.nextLink = &mEntryTable[0];
  91. mEntryTable[0].prevLink = &mLRUHead;
  92. mLRUTail.prevLink = &mEntryTable[EntryCount-1];
  93. mEntryTable[EntryCount-1].nextLink = &mLRUTail;
  94. }
  95. U32 ConnectionStringTable::getNetSendId(NetStringHandle &string)
  96. {
  97. // see if the entry is in the hash table right now
  98. U32 hashIndex = string.getIndex() % EntryCount;
  99. for(Entry *walk = mHashTable[hashIndex]; walk; walk = walk->nextHash)
  100. if(walk->string == string)
  101. return walk->index;
  102. AssertFatal(0, "Net send id is not in the table. Error!");
  103. return 0;
  104. }
  105. U32 ConnectionStringTable::checkString(NetStringHandle &string, bool *isOnOtherSide)
  106. {
  107. // see if the entry is in the hash table right now
  108. U32 hashIndex = string.getIndex() % EntryCount;
  109. for(Entry *walk = mHashTable[hashIndex]; walk; walk = walk->nextHash)
  110. {
  111. if(walk->string == string)
  112. {
  113. pushBack(walk);
  114. if(isOnOtherSide)
  115. *isOnOtherSide = walk->receiveConfirmed;
  116. return walk->index;
  117. }
  118. }
  119. // not in the hash table, means we have to add it
  120. Entry *newEntry;
  121. // pull the new entry from the LRU list.
  122. newEntry = mLRUHead.nextLink;
  123. pushBack(newEntry);
  124. // remove the string from the hash table
  125. Entry **hashWalk;
  126. for (hashWalk = &mHashTable[newEntry->string.getIndex() % EntryCount]; *hashWalk; hashWalk = &((*hashWalk)->nextHash))
  127. {
  128. if(*hashWalk == newEntry)
  129. {
  130. *hashWalk = newEntry->nextHash;
  131. break;
  132. }
  133. }
  134. newEntry->string = string;
  135. newEntry->receiveConfirmed = false;
  136. newEntry->nextHash = mHashTable[hashIndex];
  137. mHashTable[hashIndex] = newEntry;
  138. mParent->postNetEvent(new NetStringEvent(newEntry->index, string));
  139. if(isOnOtherSide)
  140. *isOnOtherSide = false;
  141. return newEntry->index;
  142. }
  143. void ConnectionStringTable::mapString(U32 netId, NetStringHandle &string)
  144. {
  145. // the netId is sent by the other side... throw it in our mapping table:
  146. mRemoteStringTable[netId] = string;
  147. }
  148. void ConnectionStringTable::readDemoStartBlock(BitStream *stream)
  149. {
  150. // ok, reading the demo start block
  151. for(U32 i = 0; i < EntryCount; i++)
  152. {
  153. if(stream->readFlag())
  154. {
  155. char buffer[256];
  156. stream->readString(buffer);
  157. mRemoteStringTable[i] = NetStringHandle(buffer);
  158. }
  159. }
  160. }
  161. void ConnectionStringTable::writeDemoStartBlock(ResizeBitStream *stream)
  162. {
  163. // ok, writing the demo start block
  164. for(U32 i = 0; i < EntryCount; i++)
  165. {
  166. if(stream->writeFlag(mRemoteStringTable[i].isValidString()))
  167. {
  168. stream->writeString(mRemoteStringTable[i].getString());
  169. stream->validate();
  170. }
  171. }
  172. }