@@ -41,6 +41,7 @@ THE SOFTWARE.
41
41
#include " base/Director.h"
42
42
#include " renderer/Texture2D.h"
43
43
#include " base/NinePatchImageParser.h"
44
+ #include " xxhash.h"
44
45
45
46
using namespace std ;
46
47
@@ -49,6 +50,11 @@ namespace ax
49
50
50
51
static SpriteFrameCache* _sharedSpriteFrameCache = nullptr ;
51
52
53
+ static uint64_t computeHash (const std::string_view& v)
54
+ {
55
+ return XXH64 (v.data (), v.length (), 0 );
56
+ }
57
+
52
58
SpriteFrameCache* SpriteFrameCache::getInstance ()
53
59
{
54
60
if (!_sharedSpriteFrameCache)
@@ -121,15 +127,16 @@ void SpriteFrameCache::addSpriteFramesWithFileContent(const Data& content,
121
127
122
128
bool SpriteFrameCache::isSpriteFramesWithFileLoaded (std::string_view plist) const
123
129
{
124
- return isSpriteSheetInUse (plist) && isPlistFull (plist);
130
+ auto sheetId = computeHash (plist);
131
+ return isSpriteSheetInUse (sheetId) && isPlistFull (sheetId);
125
132
}
126
133
127
134
void SpriteFrameCache::addSpriteFrame (SpriteFrame* frame, std::string_view frameName)
128
135
{
129
136
AXASSERT (frame, " frame should not be nil" );
130
137
131
- const std::string name = " by#addSpriteFrame()" ;
132
- auto && itr = _spriteSheets.find (name);
138
+ const auto name = computeHash ( " by#addSpriteFrame()" ) ;
139
+ auto && itr = _spriteSheets.find (name);
133
140
if (itr != _spriteSheets.end ())
134
141
{
135
142
insertFrame (itr->second , frameName, frame);
@@ -150,7 +157,7 @@ void SpriteFrameCache::removeSpriteFrames()
150
157
void SpriteFrameCache::removeUnusedSpriteFrames ()
151
158
{
152
159
auto removed = false ;
153
- std::vector<std::string_view > toRemoveFrames;
160
+ std::vector<uint64_t > toRemoveFrames;
154
161
155
162
const auto & frames = getSpriteFrames ();
156
163
for (auto && iter : frames)
@@ -173,13 +180,13 @@ void SpriteFrameCache::removeUnusedSpriteFrames()
173
180
174
181
void SpriteFrameCache::removeUnusedSpriteSheets ()
175
182
{
176
- std::vector<std::string_view > willRemoveSpriteSheetFileNames;
183
+ std::vector<uint64_t > willRemoveSpriteSheetFileNames;
177
184
for (auto && it : _spriteSheets)
178
185
{
179
186
bool isUsed = false ;
180
187
for (auto && frame : it.second ->frames )
181
188
{
182
- auto spriteFrame = getSpriteFrameByName (frame);
189
+ auto spriteFrame = findFrame (frame);
183
190
if (spriteFrame && spriteFrame->getReferenceCount () > 1 )
184
191
{
185
192
isUsed = true ;
@@ -191,10 +198,10 @@ void SpriteFrameCache::removeUnusedSpriteSheets()
191
198
willRemoveSpriteSheetFileNames.push_back (it.first );
192
199
}
193
200
194
- for (auto & spriteSheetFileName : willRemoveSpriteSheetFileNames)
201
+ for (auto & sheetId : willRemoveSpriteSheetFileNames)
195
202
{
196
- AXLOGD (" SpriteFrameCache: removing unused sprite sheet file : {}" , spriteSheetFileName );
197
- removeSpriteSheet (spriteSheetFileName );
203
+ AXLOGD (" SpriteFrameCache: removing unused sprite sheet file : {}" , sheetId );
204
+ removeSpriteSheet (sheetId );
198
205
}
199
206
}
200
207
@@ -219,7 +226,7 @@ void SpriteFrameCache::removeSpriteFramesFromFile(std::string_view atlasPath)
219
226
// removeSpriteFramesFromDictionary(dict);
220
227
221
228
// remove it from the cache
222
- removeSpriteSheet (atlasPath);
229
+ removeSpriteSheet (computeHash ( atlasPath) );
223
230
}
224
231
225
232
void SpriteFrameCache::removeSpriteFramesFromFileContent (std::string_view plist_content)
@@ -240,13 +247,14 @@ void SpriteFrameCache::removeSpriteFramesFromDictionary(ValueMap& dictionary)
240
247
return ;
241
248
242
249
const auto & framesDict = dictionary[" frames" ].asValueMap ();
243
- std::vector<std::string_view > keysToRemove;
250
+ std::vector<uint64_t > keysToRemove;
244
251
245
252
for (const auto & iter : framesDict)
246
253
{
247
- if (findFrame (iter.first ))
254
+ auto frameId = computeHash (iter.first );
255
+ if (findFrame (frameId))
248
256
{
249
- keysToRemove.emplace_back (iter. first );
257
+ keysToRemove.emplace_back (frameId );
250
258
}
251
259
}
252
260
@@ -255,7 +263,7 @@ void SpriteFrameCache::removeSpriteFramesFromDictionary(ValueMap& dictionary)
255
263
256
264
void SpriteFrameCache::removeSpriteFramesFromTexture (Texture2D* texture)
257
265
{
258
- std::vector<std::string_view > keysToRemove;
266
+ std::vector<uint64_t > keysToRemove;
259
267
260
268
for (auto && iter : getSpriteFrames ())
261
269
{
@@ -282,19 +290,18 @@ SpriteFrame* SpriteFrameCache::getSpriteFrameByName(std::string_view name)
282
290
bool SpriteFrameCache::reloadTexture (std::string_view spriteSheetFileName)
283
291
{
284
292
AXASSERT (!spriteSheetFileName.empty (), " plist filename should not be nullptr" );
285
-
286
- const auto spriteSheetItr = _spriteSheets.find (spriteSheetFileName );
293
+ auto sheetId = computeHash (spriteSheetFileName);
294
+ const auto spriteSheetItr = _spriteSheets.find (sheetId );
287
295
if (spriteSheetItr == _spriteSheets.end ())
288
296
{
289
297
return false ; // Sprite sheet wasn't loaded, so don't reload it
290
298
}
291
299
292
300
const auto format = spriteSheetItr->second ->format ;
293
301
294
- if (isSpriteSheetInUse (spriteSheetFileName ))
302
+ if (isSpriteSheetInUse (sheetId ))
295
303
{
296
- removeSpriteSheet (
297
- spriteSheetFileName); // we've removed the associated entry, so spriteSheetItr is no longer valid
304
+ removeSpriteSheet (sheetId); // we've removed the associated entry, so spriteSheetItr is no longer valid
298
305
}
299
306
else
300
307
{
@@ -314,28 +321,35 @@ void SpriteFrameCache::insertFrame(const std::shared_ptr<SpriteSheet>& spriteShe
314
321
std::string_view frameName,
315
322
SpriteFrame* spriteFrame)
316
323
{
317
- spriteSheet->frames .emplace (frameName);
318
- _spriteFrames.insert (frameName, spriteFrame); // add SpriteFrame
319
- _spriteSheets[spriteSheet->path ] = spriteSheet;
320
- hlookup::set_item (_spriteFrameToSpriteSheetMap, frameName,
321
- spriteSheet); // _spriteFrameToSpriteSheetMap[frameName] = spriteSheet; // insert
322
- // index frameName->plist
324
+ auto frameId = computeHash (frameName);
325
+ spriteFrame->setName (frameName);
326
+ spriteSheet->frames .emplace (frameId);
327
+ _spriteFrames.insert (frameId, spriteFrame); // add SpriteFrame
328
+ if (spriteSheet->pathId == (uint64_t )-1 )
329
+ spriteSheet->pathId = computeHash (spriteSheet->path );
330
+ hlookup::set_item (_spriteSheets, spriteSheet->pathId , spriteSheet);
331
+ hlookup::set_item (_spriteFrameToSpriteSheetMap, frameId, spriteSheet);
323
332
}
324
333
325
334
bool SpriteFrameCache::eraseFrame (std::string_view frameName)
335
+ {
336
+ return eraseFrame (computeHash (frameName));
337
+ }
338
+
339
+ bool SpriteFrameCache::eraseFrame (uint64_t frameId)
326
340
{
327
341
// drop SpriteFrame
328
- const auto itFrame = _spriteFrameToSpriteSheetMap.find (frameName );
329
- bool found = itFrame != _spriteFrameToSpriteSheetMap.end ();
342
+ const auto itFrame = _spriteFrameToSpriteSheetMap.find (frameId );
343
+ bool found = itFrame != _spriteFrameToSpriteSheetMap.end ();
330
344
if (found)
331
345
{
332
346
auto & spriteSheet = itFrame->second ;
333
347
spriteSheet->full = false ;
334
- spriteSheet->frames .erase (frameName );
348
+ spriteSheet->frames .erase (frameId );
335
349
336
350
if (spriteSheet->frames .empty ())
337
351
{
338
- _spriteSheets.erase (spriteSheet->path );
352
+ _spriteSheets.erase (computeHash ( spriteSheet->path ) );
339
353
}
340
354
341
355
_spriteFrameToSpriteSheetMap.erase (itFrame); // update index frame->plist
@@ -346,11 +360,11 @@ bool SpriteFrameCache::eraseFrame(std::string_view frameName)
346
360
// _spriteSheets.clear();
347
361
// }
348
362
}
349
- _spriteFrames.erase (frameName );
363
+ _spriteFrames.erase (frameId );
350
364
return found;
351
365
}
352
366
353
- bool SpriteFrameCache::eraseFrames (const std::vector<std::string_view >& frames)
367
+ bool SpriteFrameCache::eraseFrames (const std::vector<uint64_t >& frames)
354
368
{
355
369
auto ret = false ;
356
370
for (const auto & frame : frames)
@@ -361,9 +375,9 @@ bool SpriteFrameCache::eraseFrames(const std::vector<std::string_view>& frames)
361
375
return ret;
362
376
}
363
377
364
- bool SpriteFrameCache::removeSpriteSheet (std::string_view spriteSheetFileName )
378
+ bool SpriteFrameCache::removeSpriteSheet (uint64_t sheetId )
365
379
{
366
- auto it = _spriteSheets.find (spriteSheetFileName );
380
+ auto it = _spriteSheets.find (sheetId );
367
381
if (it == _spriteSheets.end ())
368
382
return false ;
369
383
@@ -375,7 +389,7 @@ bool SpriteFrameCache::removeSpriteSheet(std::string_view spriteSheetFileName)
375
389
_spriteFrames.erase (f);
376
390
_spriteFrameToSpriteSheetMap.erase (f); // erase plist frame frameName->plist
377
391
}
378
- _spriteSheets.erase (spriteSheetFileName ); // update index plist->[frameNames]
392
+ _spriteSheets.erase (sheetId ); // update index plist->[frameNames]
379
393
380
394
return true ;
381
395
}
@@ -387,40 +401,28 @@ void SpriteFrameCache::clear()
387
401
_spriteFrames.clear ();
388
402
}
389
403
390
- bool SpriteFrameCache::hasFrame (std::string_view frame ) const
404
+ bool SpriteFrameCache::isSpriteSheetInUse ( uint64_t sheetId ) const
391
405
{
392
- return _spriteFrameToSpriteSheetMap.find (frame) != _spriteFrameToSpriteSheetMap.end ();
393
- }
394
-
395
- bool SpriteFrameCache::isSpriteSheetInUse (std::string_view spriteSheetFileName) const
396
- {
397
- const auto spriteSheetItr = _spriteSheets.find (spriteSheetFileName);
406
+ const auto spriteSheetItr = _spriteSheets.find (sheetId);
398
407
return spriteSheetItr != _spriteSheets.end () && !spriteSheetItr->second ->frames .empty ();
399
408
}
400
409
401
410
SpriteFrame* SpriteFrameCache::findFrame (std::string_view frame)
402
411
{
403
- return _spriteFrames.at (frame);
412
+ return _spriteFrames.at (computeHash ( frame) );
404
413
}
405
414
406
- std::string_view SpriteFrameCache::getSpriteFrameName (SpriteFrame* frame )
415
+ SpriteFrame* SpriteFrameCache::findFrame ( uint64_t frameId )
407
416
{
408
- for (auto & it : _spriteFrames)
409
- {
410
- if (it.second == frame)
411
- {
412
- return it.first ;
413
- }
414
- }
415
- return " " ;
417
+ return _spriteFrames.at (frameId);
416
418
}
417
419
418
420
void SpriteFrameCache::addSpriteFrameCapInset (SpriteFrame* spriteFrame, const Rect& capInsets, Texture2D* texture)
419
421
{
420
422
texture->addSpriteFrameCapInset (spriteFrame, capInsets);
421
423
}
422
424
423
- StringMap< SpriteFrame*>& SpriteFrameCache::getSpriteFrames ()
425
+ const ax::Map< uint64_t , SpriteFrame*>& SpriteFrameCache::getSpriteFrames ()
424
426
{
425
427
return _spriteFrames;
426
428
}
@@ -457,4 +459,4 @@ ISpriteSheetLoader* SpriteFrameCache::getSpriteSheetLoader(uint32_t spriteSheetF
457
459
return nullptr ;
458
460
}
459
461
460
- }
462
+ } // namespace ax
0 commit comments