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(!String::compare(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   dsize_t stringLen = dStrlen(string) + 1;
101   table[e].string = (char *) allocator->alloc(stringLen);
102   dStrcpy(table[e].string, string, stringLen);
103   table[e].next = hashTable[bucket];
104   hashTable[bucket] = e;
105   table[e].link = firstValid;
106   table[firstValid].prevLink = e;
107   firstValid = e;
108   table[e].prevLink = 0;
109   return e;
110}
111
112U32 GameAddTaggedString(const char *string)
113{
114   return gNetStringTable->addString(string);
115}
116
117const char *NetStringTable::lookupString(U32 id)
118{
119   if(table[id].refCount == 0 && table[id].scriptRefCount == 0)
120      return NULL;
121   return table[id].string;
122}
123
124void NetStringTable::removeString(U32 id, bool script)
125{
126   if(!script)
127   {
128      AssertFatal(table[id].refCount != 0, "Error, ref count is already 0!!");
129      if(--table[id].refCount)
130         return;
131      if(table[id].scriptRefCount)
132         return;
133   }
134   else
135   {
136      // If both ref counts are already 0, this id is not valid. Ignore
137      // the remove
138      if (table[id].scriptRefCount == 0 && table[id].refCount == 0)
139         return;
140
141      if(table[id].scriptRefCount == 0 && table[id].refCount)
142      {
143         Con::errorf("removeTaggedString failed!  Ref count is already 0 for string: %s", table[id].string);
144         return;
145      }
146      if(--table[id].scriptRefCount)
147         return;
148      if(table[id].refCount)
149         return;
150   }
151   // unlink first:
152   U32 prev = table[id].prevLink;
153   U32 next = table[id].link;
154   if(next)
155      table[next].prevLink = prev;
156   if(prev)
157      table[prev].link = next;
158   else
159      firstValid = next;
160   // remove it from the hash table
161   U32 hash = _StringTable::hashString(table[id].string);
162   U32 bucket = hash % HashTableSize;
163   for(U32 *walk = &hashTable[bucket];*walk; walk = &table[*walk].next)
164   {
165      if(*walk == id)
166      {
167         *walk = table[id].next;
168         break;
169      }
170   }
171   table[id].next = firstFree;
172   firstFree = id;
173}
174
175void NetStringTable::repack()
176{
177   DataChunker *newAllocator = new DataChunker(DataChunkerSize);
178   for(U32 walk = firstValid; walk; walk = table[walk].link)
179   {
180      const char *prevStr = table[walk].string;
181
182
183      dsize_t prevStrLen = dStrlen(prevStr) + 1;
184      table[walk].string = (char *) newAllocator->alloc(prevStrLen);
185      dStrcpy(table[walk].string, prevStr, prevStrLen);
186   }
187   delete allocator;
188   allocator = newAllocator;
189}
190
191void NetStringTable::create()
192{
193   AssertFatal(gNetStringTable == NULL, "Error, calling NetStringTable::create twice.");
194   gNetStringTable = new NetStringTable();
195}
196
197void NetStringTable::destroy()
198{
199   AssertFatal(gNetStringTable != NULL, "Error, not calling NetStringTable::create.");
200   delete gNetStringTable;
201   gNetStringTable = NULL;
202}
203
204void NetStringTable::expandString(NetStringHandle &inString, char *buf, U32 bufSize, U32 argc, const char **argv)
205{
206   buf[0] = StringTagPrefixByte;
207   dSprintf(buf + 1, bufSize - 1, "%d ", inString.getIndex());
208
209   const char *string = inString.getString();
210   if (string != NULL) {
211      U32 index = dStrlen(buf);
212      while(index < bufSize)
213      {
214         char c = *string++;
215         if(c == '%')
216         {
217            c = *string++;
218            if(c >= '1' && c <= '9')
219            {
220               U32 strIndex = c - '1';
221               if(strIndex >= argc)
222                  continue;
223               // start copying out of arg index
224               const char *copy = argv[strIndex];
225               // skip past any tags:
226               if(*copy == StringTagPrefixByte)
227               {
228                  while(*copy && *copy != ' ')
229                     copy++;
230                  if(*copy)
231                     copy++;
232               }
233
234               while(*copy && index < bufSize)
235                  buf[index++] = *copy++;
236               continue;
237            }
238         }
239         buf[index++] = c;
240         if(!c)
241            break;
242      }
243      buf[bufSize - 1] = 0;
244   } else {
245      dStrcat(buf, "<NULL>", bufSize);
246   }
247}
248
249#ifdef TORQUE_DEBUG
250
251void NetStringTable::dumpToConsole()
252{
253   U32 count = 0;
254   S32 maxIndex = -1;
255   for ( U32 i = 0; i < size; i++ )
256   {
257      if ( table[i].refCount > 0 || table[i].scriptRefCount > 0)
258      {
259         Con::printf( "%d: \"%c%s%c\" REF: %d", i, 0x10, table[i].string, 0x11, table[i].refCount );
260         if ( maxIndex == -1 || table[i].refCount > table[maxIndex].refCount )
261            maxIndex = i;
262         count++;
263      }
264   }
265   Con::printf( ">> STRINGS: %d MAX REF COUNT: %d \"%c%s%c\" <<",
266         count,
267         ( maxIndex == -1 ) ? 0 : table[maxIndex].refCount,
268         0x10,
269         ( maxIndex == -1 ) ? "" : table[maxIndex].string,
270         0x11 );
271}
272
273
274
275#endif // DEBUG
276
277
278DefineEngineFunction( dumpNetStringTable, void, (),,
279   "@brief Dump the current contents of the networked string table to the console.\n\n"
280   "The results are returned in three columns.  The first column is the network string ID.  "
281   "The second column is the string itself.  The third column is the reference count to the "
282   "network string.\n\n"
283   "@note This function is available only in debug builds.\n\n"
284   "@ingroup Networking" )
285{
286#ifdef TORQUE_DEBUG
287   gNetStringTable->dumpToConsole();
288#endif
289}
290
291