Torque3D Documentation / _generateds / tagDictionary.cpp

tagDictionary.cpp

Engine/source/core/tagDictionary.cpp

More...

Public Variables

Public Functions

Detailed Description

Public Variables

TagDictionary tagDictionary 

Public Functions

hashDefine(StringTableEntry define, S32 tsize)

hashId(S32 id, S32 tsize)

idCompare(const void * in_p1, const void * in_p2)

  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/strings/stringFunctions.h"
 25#include "core/tagDictionary.h"
 26#include "core/stream/stream.h"
 27
 28namespace {
 29const char TAG_ASCII_HEADER[] = "// Auto-Generated by TagDictionary class";
 30} // namespace
 31
 32TagDictionary tagDictionary;
 33
 34TagDictionary::TagDictionary()
 35{
 36   numBuckets = 29;
 37   defineHashBuckets = (TagEntry **) dMalloc(numBuckets * sizeof(TagEntry *));
 38   idHashBuckets = (TagEntry **) dMalloc(numBuckets * sizeof(TagEntry *));
 39
 40   S32 i;
 41   for(i = 0; i < numBuckets; i++)
 42   {
 43      defineHashBuckets[i] = NULL;
 44      idHashBuckets[i] = NULL;
 45   }
 46   numEntries = 0;
 47   entryChain = NULL;
 48}
 49
 50TagDictionary::~TagDictionary()
 51{
 52   dFree(defineHashBuckets);
 53   dFree(idHashBuckets);
 54}
 55
 56//------------------------------------------------------------------------------
 57
 58static inline S32 hashId(S32 id, S32 tsize)
 59{
 60   return id % tsize;
 61}
 62
 63static inline S32 hashDefine(StringTableEntry define, S32 tsize)
 64{
 65   return ((S32)((dsize_t)define) >> 2) % tsize;
 66}
 67
 68//------------------------------------------------------------------------------
 69
 70bool TagDictionary::addEntry(S32 value, StringTableEntry define, StringTableEntry string)
 71{
 72   if(!value)
 73      return false;
 74//#pragma message "put console prints back"
 75   if(idToDefine(value))
 76   {
 77      AssertWarn(false, avar("Error: id %d already defined to a tag.", value));
 78      //Con::printf("Error: id %d already defined to a tag.", value);
 79      return false;
 80   }
 81   S32 tempTag;
 82   if((tempTag = defineToId(define)) != 0)
 83   {
 84      AssertWarn(false, avar("Error: define %s already defined to tag %d.", define, tempTag));
 85      //Con::printf("Error: define %s already defined to tag %d.", define, tempTag);
 86      return false;
 87   }
 88   TagEntry *newEntry = (TagEntry *) mempool.alloc(sizeof(TagEntry));
 89   
 90   newEntry->id = value;
 91   newEntry->define = define;
 92   newEntry->string = string;
 93
 94   numEntries++;
 95   if(numEntries > numBuckets)
 96   {
 97      numBuckets = numBuckets * 2 + 1;
 98      defineHashBuckets = (TagEntry **) dRealloc(defineHashBuckets, numBuckets * sizeof(TagEntry *));
 99      idHashBuckets = (TagEntry **) dRealloc(idHashBuckets, numBuckets * sizeof(TagEntry *));
100      S32 i;
101      for(i = 0; i < numBuckets; i++)
102      {
103         defineHashBuckets[i] = NULL;
104         idHashBuckets[i] = NULL;
105      }
106      TagEntry *walk = entryChain;
107   
108      while(walk)
109      {
110         S32 index = hashId(walk->id, numBuckets);
111         walk->idHashLink = idHashBuckets[index];
112         idHashBuckets[index] = walk;
113
114         index = hashDefine(walk->define, numBuckets);
115         walk->defineHashLink = defineHashBuckets[index];
116         defineHashBuckets[index] = walk;
117
118         walk = walk->chain;
119      }
120   }
121   newEntry->chain = entryChain;
122   entryChain = newEntry;
123
124   S32 index = hashId(newEntry->id, numBuckets);
125   newEntry->idHashLink = idHashBuckets[index];
126   idHashBuckets[index] = newEntry;
127
128   index = hashDefine(newEntry->define, numBuckets);
129   newEntry->defineHashLink = defineHashBuckets[index];
130   defineHashBuckets[index] = newEntry;
131   return true;
132}
133
134//------------------------------------------------------------------------------
135
136bool TagDictionary::writeHeader(Stream& io_sio)
137{
138   char buff[15000];
139   Vector<S32> v;
140
141   TagEntry *walk = entryChain;
142   while(walk)
143   {
144      v.push_back(walk->id);
145      walk = walk->chain;
146   }
147
148   sortIdVector(v);
149
150   io_sio.write( sizeof(TAG_ASCII_HEADER)-1, TAG_ASCII_HEADER);
151   io_sio.write( 4, "\r\n\r\n");
152   
153   char exclude[256];
154   char tempBuf[256];
155   dSprintf(exclude, sizeof(exclude), "_TD%10.10u_H_", Platform::getVirtualMilliseconds() / 4);
156   
157   dSprintf(tempBuf, sizeof(tempBuf), "#ifndef %s\r\n", exclude);
158   io_sio.write(dStrlen(tempBuf), tempBuf);
159   dSprintf(tempBuf, sizeof(tempBuf), "#define %s\r\n\r\n", exclude);
160   io_sio.write(dStrlen(tempBuf), tempBuf);
161   
162   for (U32 i = 0; i < v.size(); i++)
163   {
164      dSprintf(buff, sizeof(buff), "#define %s (%d)\r\n", idToDefine(v[i]), v[i]);
165      io_sio.write(dStrlen(buff), buff);
166   }
167
168   dSprintf(tempBuf, sizeof(tempBuf), "\r\n#endif // %s\r\n", exclude);
169   io_sio.write(dStrlen(tempBuf), tempBuf);
170
171   return (io_sio.getStatus() == Stream::Ok);
172}
173
174//------------------------------------------------------------------------------
175
176StringTableEntry TagDictionary::defineToString(StringTableEntry tag)
177{
178   S32 index = hashDefine(tag, numBuckets);
179   if (index < 0) return NULL;
180   TagEntry *walk = defineHashBuckets[index];
181   while(walk)
182   {
183      if(walk->define == tag)
184         return walk->string;
185      walk = walk->defineHashLink;
186   }
187   return NULL;
188}
189
190S32 TagDictionary::defineToId(StringTableEntry tag)
191{
192   S32 index = hashDefine(tag, numBuckets);
193   if (index < 0) return 0;
194   TagEntry *walk = defineHashBuckets[index];
195   while(walk)
196   {
197      if(walk->define == tag)
198         return walk->id;
199      walk = walk->defineHashLink;
200   }
201   return 0;
202}
203
204StringTableEntry TagDictionary::idToString(S32 id)
205{
206   S32 index = hashId(id, numBuckets);
207   if (index < 0) return NULL;
208   TagEntry *walk = idHashBuckets[index];
209   while(walk)
210   {
211      if(walk->id == id)
212         return walk->string;
213      walk = walk->idHashLink;
214   }
215   return NULL;
216}
217
218StringTableEntry TagDictionary::idToDefine(S32 id)
219{
220   S32 index = hashId(id, numBuckets);
221   if (index < 0) return NULL;
222   TagEntry *walk = idHashBuckets[index];
223   while(walk)
224   {
225      if(walk->id == id)
226         return walk->define;
227      walk = walk->idHashLink;
228   }
229   return NULL;
230}
231
232//------------------------------------------------------------------------------
233
234void TagDictionary::findIDs(Vector<S32>& out_v,
235                       const S32    in_minID,
236                       const S32    in_maxID )
237{
238   //locate all IDs that lie in between minID and maxID
239
240   TagEntry *walk = entryChain;
241   while(walk)
242   {
243      if(walk->id > in_minID && walk->id < in_maxID)
244         out_v.push_back(walk->id);
245      walk = walk->chain;
246   }
247   sortIdVector(out_v);
248}
249
250
251//------------------------------------------------------------------------------
252void TagDictionary::findStrings(Vector<S32>& out_v, const char*  in_pPattern)
253{
254   //locate all strings that match the pattern
255   //
256   TagEntry *walk = entryChain;
257   while(walk)
258   {
259      if (match(in_pPattern, walk->string))
260         out_v.push_back(walk->id);
261      walk = walk->chain;
262   }
263   sortIdVector(out_v);
264}
265
266
267//------------------------------------------------------------------------------
268void TagDictionary::findDefines(Vector<S32>& out_v, const char*  in_pPattern)
269{
270   //locate all define strings that match the pattern and add their ID 
271   //to the given vector
272   //
273   TagEntry *walk = entryChain;
274   while(walk)
275   {
276      if (match(in_pPattern, walk->define))
277         out_v.push_back(walk->id);
278      walk = walk->chain;
279   }
280   sortIdVector(out_v);
281}
282
283//------------------------------------------------------------------------------
284
285bool TagDictionary::match(const char* pattern, const char* str)
286{
287   //quick and dirty recursive DOS-style wild-card string matcher
288   //
289   switch (*pattern) {
290     case '\0':
291      return !*str;
292
293     case '*':
294      return match(pattern+1, str) || (*str && match(pattern, str+1));
295
296     case '?':
297      return *str && match(pattern+1, str+1);
298
299     default:
300      return (*pattern == *str) && match(pattern+1, str+1);
301   }
302}
303
304//------------------------------------------------------------------------------
305
306static S32 QSORT_CALLBACK idCompare(const void *in_p1, const void *in_p2)
307{
308   return *((S32 *) in_p1) - *((S32 *) in_p2);
309}
310
311void TagDictionary::sortIdVector(Vector<S32>& out_v)
312{
313   dQsort(out_v.address(), out_v.size(), sizeof(S32), idCompare);
314}
315
316