3
3
4
4
using namespace geode ::prelude;
5
5
6
- void assignFallbackObj (CCNode* node) {
6
+ static constexpr int FALLBACK_TAG = 105871529 ;
7
+
8
+ static void assignFallbackObj (CCNode* node) {
7
9
if (!node) return ;
8
10
node->setUserObject (" fallback" _spr, CCBool::create (true ));
9
11
}
@@ -21,50 +23,79 @@ class $modify(CCSprite) {
21
23
}
22
24
return sprite;
23
25
}
26
+
24
27
static CCSprite* createWithSpriteFrameName (const char * name) {
25
- auto * sprite = CCSprite::createWithSpriteFrameName (name);
28
+ auto * spriteFrame = CCSpriteFrameCache::get ()->spriteFrameByName (name);
29
+
30
+ // we check for tag instead of the frame name because this is significantly better for performance
31
+ bool needFallback = !spriteFrame || spriteFrame->getTag () == FALLBACK_TAG;
32
+
33
+ if (!needFallback) {
34
+ return CCSprite::createWithSpriteFrame (spriteFrame);
35
+ }
36
+
37
+ CCSprite* sprite = CCSprite::create (" fallback.png" _spr);
26
38
if (sprite == nullptr ) {
27
- sprite = CCSprite::create (" fallback.png" _spr);
28
- if (sprite == nullptr ) {
29
- sprite = CCSprite::create (" bigFont.png" );
30
- }
31
- assignFallbackObj (sprite);
39
+ sprite = CCSprite::create (" bigFont.png" );
32
40
}
41
+ assignFallbackObj (sprite);
33
42
return sprite;
34
43
}
35
44
36
45
bool initWithSpriteFrame (CCSpriteFrame* frame) {
37
46
if (frame == nullptr ) {
38
- return CCSprite::initWithFile (" fallback.png" _spr);
47
+ bool result = CCSprite::initWithFile (" fallback.png" _spr);
48
+ if (result) {
49
+ assignFallbackObj (this );
50
+ }
51
+
52
+ return result;
39
53
}
40
54
return CCSprite::initWithSpriteFrame (frame);
41
55
}
42
56
};
43
57
44
58
class $modify(CCSpriteFrameCache) {
45
- cocos2d::CCSpriteFrame* spriteFrameByName (char const * name) {
46
- auto * frame = CCSpriteFrameCache::sharedSpriteFrameCache ()->spriteFrameByName (name);
47
- if (frame == nullptr ) {
48
- // this is stupid but rob intentionally doesnt load all icons at startup,
49
- // probably to save memory, so do this to not use fallback on icons
50
- static constexpr std::string_view prefixes[] = {
51
- " player_" ,
52
- " ship_" ,
53
- " dart_" ,
54
- " bird_" ,
55
- " robot_" ,
56
- " spider_" ,
57
- " swing_" ,
58
- " jetpack_" ,
59
- };
60
- const std::string_view nameStr = name;
61
- for (auto const & prefix : prefixes) {
62
- if (nameStr.find (prefix) != -1 ) {
63
- return frame;
64
- }
59
+ CCSpriteFrame* spriteFrameByName (char const * name) {
60
+ auto * frame = CCSpriteFrameCache::spriteFrameByName (name);
61
+
62
+ if (frame != nullptr ) {
63
+ return frame;
64
+ }
65
+
66
+ // this is stupid but rob intentionally doesnt load all icons at startup,
67
+ // probably to save memory, so do this to not use fallback on icons
68
+ static constexpr std::string_view prefixes[] = {
69
+ " player_" ,
70
+ " ship_" ,
71
+ " dart_" ,
72
+ " bird_" ,
73
+ " robot_" ,
74
+ " spider_" ,
75
+ " swing_" ,
76
+ " jetpack_" ,
77
+ };
78
+ const std::string_view nameStr = name;
79
+ for (auto const & prefix : prefixes) {
80
+ if (nameStr.find (prefix) != -1 ) {
81
+ return frame;
65
82
}
66
- frame = CCSpriteFrame::create (" fallback.png" _spr, {ccp (0 , 0 ), ccp (128 , 128 )});
67
83
}
68
- return frame;
84
+
85
+ // check if the fallback was already added
86
+ auto fallbackFrame = CCSpriteFrameCache::spriteFrameByName (" fallback.png" _spr);
87
+ if (fallbackFrame) {
88
+ return fallbackFrame;
89
+ }
90
+
91
+ // create the fallback frame and add to cache
92
+ fallbackFrame = CCSpriteFrame::create (" fallback.png" _spr, {ccp (0 , 0 ), ccp (128 , 128 )});
93
+
94
+ if (fallbackFrame) {
95
+ fallbackFrame->setTag (FALLBACK_TAG);
96
+ this ->addSpriteFrame (fallbackFrame, " fallback.png" _spr);
97
+ }
98
+
99
+ return fallbackFrame;
69
100
}
70
101
};
0 commit comments