Torque3D Documentation / _generateds / netStringTable.cpp

netStringTable.cpp

Engine/source/sim/netStringTable.cpp

More...

Public Variables

Public Functions

DefineEngineFunction(dumpNetStringTable , void , () , "@brief Dump the current contents of the networked string table <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n\n</a>" "The results are returned in three columns. The first column is the network string ID. " "The second column is the string itself. The third column is the reference <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1ad43c3812e6d13e0518d9f8b8f463ffcf">count</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the " "network <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">string.\n\n</a>" "@note This function is available only in debug <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">builds.\n\n</a>" "@ingroup Networking" )
GameAddTaggedString(const char * string)

Detailed Description

Public Variables

NetStringTable * gNetStringTable 

Public Functions

DefineEngineFunction(dumpNetStringTable , void , () , "@brief Dump the current contents of the networked string table <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n\n</a>" "The results are returned in three columns. The first column is the network string ID. " "The second column is the string itself. The third column is the reference <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1ad43c3812e6d13e0518d9f8b8f463ffcf">count</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the " "network <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">string.\n\n</a>" "@note This function is available only in debug <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">builds.\n\n</a>" "@ingroup Networking" )

GameAddTaggedString(const char * string)

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "core/dnet.h"
 25#include "core/strings/stringFunctions.h"
 26#include "core/stringTable.h"
 27#include "console/engineAPI.h"
 28#include "sim/netStringTable.h"
 29
 30
 31NetStringTable *gNetStringTable = NULL;
 32
 33NetStringTable::NetStringTable()
 34{
 35   firstFree = 1;
 36   firstValid = 1;
 37
 38   table = (Entry *) dMalloc(sizeof(Entry) * InitialSize);
 39   size = InitialSize;
 40   for(U32 i = 0; i < InitialSize; i++)
 41   {
 42      table[i].next = i + 1;
 43      table[i].refCount = 0;
 44      table[i].scriptRefCount = 0;
 45   }
 46   table[InitialSize-1].next = InvalidEntry;
 47   for(U32 j = 0; j < HashTableSize; j++)
 48      hashTable[j] = 0;
 49   allocator = new DataChunker(DataChunkerSize);
 50}
 51
 52NetStringTable::~NetStringTable()
 53{
 54   delete allocator;
 55   dFree( table );
 56}
 57
 58void NetStringTable::incStringRef(U32 id)
 59{
 60   AssertFatal(table[id].refCount != 0 || table[id].scriptRefCount != 0 , "Cannot inc ref count from zero.");
 61   table[id].refCount++;
 62}
 63
 64void NetStringTable::incStringRefScript(U32 id)
 65{
 66   AssertFatal(table[id].refCount != 0 || table[id].scriptRefCount != 0 , "Cannot inc ref count from zero.");
 67   table[id].scriptRefCount++;
 68}
 69
 70U32 NetStringTable::addString(const char *string)
 71{
 72   U32 hash = _StringTable::hashString(string);
 73   U32 bucket = hash % HashTableSize;
 74   for(U32 walk = hashTable[bucket];walk; walk = table[walk].next)
 75   {
 76      if(!dStrcmp(table[walk].string, string))
 77      {
 78         table[walk].refCount++;
 79         return walk;
 80      }
 81   }
 82   U32 e = firstFree;
 83   firstFree = table[e].next;
 84   if(firstFree == InvalidEntry)
 85   {
 86      // in this case, we should expand the table for next time...
 87      U32 newSize = size * 2;
 88      table = (Entry *) dRealloc(table, newSize * sizeof(Entry));
 89      for(U32 i = size; i < newSize; i++)
 90      {
 91         table[i].next = i + 1;
 92         table[i].refCount = 0;
 93         table[i].scriptRefCount = 0;
 94      }
 95      firstFree = size;
 96      table[newSize - 1].next = InvalidEntry;
 97      size = newSize;
 98   }
 99   table[e].refCount++;
100   table[e].string = (char *) allocator->alloc(dStrlen(string) + 1);
101   dStrcpy(table[e].string, string);
102   table[e].next = hashTable[bucket];
103   hashTable[bucket] = e;
104   table[e].link = firstValid;
105   table[firstValid].prevLink = e;
106   firstValid = e;
107   table[e].prevLink = 0;
108   return e;
109}
110
111U32 GameAddTaggedString(const char *string)
112{
113   return gNetStringTable->addString(string);
114}
115
116const char *NetStringTable::lookupString(U32 id)
117{
118   if(table[id].refCount == 0 && table[id].scriptRefCount == 0)
119      return NULL;
120   return table[id].string;
121}
122
123void NetStringTable::removeString(U32 id, bool script)
124{
125   if(!script)
126   {
127      AssertFatal(table[id].refCount != 0, "Error, ref count is already 0!!");
128      if(--table[id].refCount)
129         return;
130      if(table[id].scriptRefCount)
131         return;
132   }
133   else
134   {
135      // If both ref counts are already 0, this id is not valid. Ignore
136      // the remove
137      if (table[id].scriptRefCount == 0 && table[id].refCount == 0)
138         return;
139
140      if(table[id].scriptRefCount == 0 && table[id].refCount)
141      {
142         Con::errorf("removeTaggedString failed!  Ref count is already 0 for string: %s", table[id].string);
143         return;
144      }
145      if(--table[id].scriptRefCount)
146         return;
147      if(table[id].refCount)
148         return;
149   }
150   // unlink first:
151   U32 prev = table[id].prevLink;
152   U32 next = table[id].link;
153   if(next)
154      table[next].prevLink = prev;
155   if(prev)
156      table[prev].link = next;
157   else
158      firstValid = next;
159   // remove it from the hash table
160   U32 hash = _StringTable::hashString(table[id].string);
161   U32 bucket = hash % HashTableSize;
162   for(U32 *walk = &hashTable[bucket];*walk; walk = &table[*walk].next)
163   {
164      if(*walk == id)
165      {
166         *walk = table[id].next;
167         break;
168      }
169   }
170   table[id].next = firstFree;
171   firstFree = id;
172}
173
174void NetStringTable::repack()
175{
176   DataChunker *newAllocator = new DataChunker(DataChunkerSize);
177   for(U32 walk = firstValid; walk; walk = table[walk].link)
178   {
179      const char *prevStr = table[walk].string;
180
181
182      table[walk].string = (char *) newAllocator->alloc(dStrlen(prevStr) + 1);
183      dStrcpy(table[walk].string, prevStr);
184   }
185   delete allocator;
186   allocator = newAllocator;
187}
188
189void NetStringTable::create()
190{
191   AssertFatal(gNetStringTable == NULL, "Error, calling NetStringTable::create twice.");
192   gNetStringTable = new NetStringTable();
193}
194
195void NetStringTable::destroy()
196{
197   AssertFatal(gNetStringTable != NULL, "Error, not calling NetStringTable::create.");
198   delete gNetStringTable;
199   gNetStringTable = NULL;
200}
201
202void NetStringTable::expandString(NetStringHandle &inString, char *buf, U32 bufSize, U32 argc, const char **argv)
203{
204   buf[0] = StringTagPrefixByte;
205   dSprintf(buf + 1, bufSize - 1, "%d ", inString.getIndex());
206
207   const char *string = inString.getString();
208   if (string != NULL) {
209      U32 index = dStrlen(buf);
210      while(index < bufSize)
211      {
212         char c = *string++;
213         if(c == '%')
214         {
215            c = *string++;
216            if(c >= '1' && c <= '9')
217            {
218               U32 strIndex = c - '1';
219               if(strIndex >= argc)
220                  continue;
221               // start copying out of arg index
222               const char *copy = argv[strIndex];
223               // skip past any tags:
224               if(*copy == StringTagPrefixByte)
225               {
226                  while(*copy && *copy != ' ')
227                     copy++;
228                  if(*copy)
229                     copy++;
230               }
231
232               while(*copy && index < bufSize)
233                  buf[index++] = *copy++;
234               continue;
235            }
236         }
237         buf[index++] = c;
238         if(!c)
239            break;
240      }
241      buf[bufSize - 1] = 0;
242   } else {
243      dStrcat(buf, "<NULL>");
244   }
245}
246
247#ifdef TORQUE_DEBUG
248
249void NetStringTable::dumpToConsole()
250{
251   U32 count = 0;
252   S32 maxIndex = -1;
253   for ( U32 i = 0; i < size; i++ )
254   {
255      if ( table[i].refCount > 0 || table[i].scriptRefCount > 0)
256      {
257         Con::printf( "%d: \"%c%s%c\" REF: %d", i, 0x10, table[i].string, 0x11, table[i].refCount );
258         if ( maxIndex == -1 || table[i].refCount > table[maxIndex].refCount )
259            maxIndex = i;
260         count++;
261      }
262   }
263   Con::printf( ">> STRINGS: %d MAX REF COUNT: %d \"%c%s%c\" <<",
264         count,
265         ( maxIndex == -1 ) ? 0 : table[maxIndex].refCount,
266         0x10,
267         ( maxIndex == -1 ) ? "" : table[maxIndex].string,
268         0x11 );
269}
270
271
272
273#endif // DEBUG
274
275
276DefineEngineFunction( dumpNetStringTable, void, (),,
277   "@brief Dump the current contents of the networked string table to the console.\n\n"
278   "The results are returned in three columns.  The first column is the network string ID.  "
279   "The second column is the string itself.  The third column is the reference count to the "
280   "network string.\n\n"
281   "@note This function is available only in debug builds.\n\n"
282   "@ingroup Networking" )
283{
284#ifdef TORQUE_DEBUG
285   gNetStringTable->dumpToConsole();
286#endif
287}
288
289