Skip to content

Commit 6d6edca

Browse files
authored
Fix issue with aliases not being cleared after processing each frame. (#3236)
Reduce code duplication to ensure both load and reload are processing the frames in the same way, including frame vertices.
1 parent b14941e commit 6d6edca

2 files changed

Lines changed: 120 additions & 164 deletions

File tree

core/2d/PlistSpriteSheetLoader.cpp

Lines changed: 114 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,105 @@ void PlistSpriteSheetLoader::reload(std::string_view filePath, SpriteFrameCache&
172172
}
173173
}
174174

175+
SpriteFrame* PlistSpriteSheetLoader::parseFrame(const ValueMap& frameDict,
176+
std::vector<std::string>& frameAliases,
177+
int format,
178+
Texture2D* texture,
179+
const ax::Vec2& textureSize)
180+
{
181+
SpriteFrame* spriteFrame = nullptr;
182+
183+
if (format == 0)
184+
{
185+
auto x = optValue(frameDict, "x"sv).asFloat();
186+
auto y = optValue(frameDict, "y"sv).asFloat();
187+
auto w = optValue(frameDict, "width"sv).asFloat();
188+
auto h = optValue(frameDict, "height"sv).asFloat();
189+
auto ox = optValue(frameDict, "offsetX"sv).asFloat();
190+
auto oy = optValue(frameDict, "offsetY"sv).asFloat();
191+
auto ow = optValue(frameDict, "originalWidth"sv).asInt();
192+
auto oh = optValue(frameDict, "originalHeight"sv).asInt();
193+
// check ow/oh
194+
if (!ow || !oh)
195+
{
196+
AXLOGW(
197+
"WARNING: originalWidth/Height not found on the SpriteFrame. AnchorPoint won't work as "
198+
"expected. Regenerate the .plist");
199+
}
200+
// abs ow/oh
201+
ow = std::abs(ow);
202+
oh = std::abs(oh);
203+
// create frame
204+
spriteFrame =
205+
SpriteFrame::createWithTexture(texture, Rect(x, y, w, h), false, Vec2(ox, oy), Vec2((float)ow, (float)oh));
206+
}
207+
else if (format == 1 || format == 2)
208+
{
209+
auto frame = RectFromString(optValue(frameDict, "frame"sv).asString());
210+
auto rotated = false;
211+
212+
// rotation
213+
if (format == 2)
214+
{
215+
rotated = optValue(frameDict, "rotated"sv).asBool();
216+
}
217+
218+
auto offset = PointFromString(optValue(frameDict, "offset"sv).asString());
219+
auto sourceSize = SizeFromString(optValue(frameDict, "sourceSize"sv).asString());
220+
221+
// create frame
222+
spriteFrame = SpriteFrame::createWithTexture(texture, frame, rotated, offset, sourceSize);
223+
}
224+
else if (format == 3)
225+
{
226+
// get values
227+
auto spriteSize = SizeFromString(optValue(frameDict, "spriteSize"sv).asString());
228+
auto spriteOffset = PointFromString(optValue(frameDict, "spriteOffset"sv).asString());
229+
auto spriteSourceSize = SizeFromString(optValue(frameDict, "spriteSourceSize"sv).asString());
230+
auto textureRect = RectFromString(optValue(frameDict, "textureRect"sv).asString());
231+
auto textureRotated = optValue(frameDict, "textureRotated"sv).asBool();
232+
233+
// get aliases
234+
auto& aliases = optValue(frameDict, "aliases"sv).asValueVector();
235+
236+
for (const auto& value : aliases)
237+
{
238+
auto oneAlias = value.asString();
239+
if (std::find(frameAliases.begin(), frameAliases.end(), oneAlias) == frameAliases.end())
240+
{
241+
frameAliases.emplace_back(std::move(oneAlias));
242+
}
243+
else
244+
{
245+
AXLOGW("WARNING: an alias with name {} already exists", oneAlias);
246+
}
247+
}
248+
249+
// create frame
250+
spriteFrame = SpriteFrame::createWithTexture(
251+
texture, Rect(textureRect.origin.x, textureRect.origin.y, spriteSize.width, spriteSize.height),
252+
textureRotated, spriteOffset, spriteSourceSize);
253+
254+
if (frameDict.find("vertices") != frameDict.end())
255+
{
256+
using ax::utils::parseIntegerList;
257+
auto vertices = parseIntegerList(optValue(frameDict, "vertices"sv).asString());
258+
auto verticesUV = parseIntegerList(optValue(frameDict, "verticesUV"sv).asString());
259+
auto indices = parseIntegerList(optValue(frameDict, "triangles"sv).asString());
260+
261+
PolygonInfo info;
262+
initializePolygonInfo(textureSize, spriteSourceSize, vertices, verticesUV, indices, info);
263+
spriteFrame->setPolygonInfo(info);
264+
}
265+
if (frameDict.find("anchor") != frameDict.end())
266+
{
267+
spriteFrame->setAnchorPoint(PointFromString(optValue(frameDict, "anchor"sv).asString()));
268+
}
269+
}
270+
271+
return spriteFrame;
272+
}
273+
175274
void PlistSpriteSheetLoader::addSpriteFramesWithDictionary(ValueMap& dictionary,
176275
Texture2D* texture,
177276
std::string_view plist,
@@ -236,93 +335,7 @@ void PlistSpriteSheetLoader::addSpriteFramesWithDictionary(ValueMap& dictionary,
236335
continue;
237336
}
238337

239-
if (format == 0)
240-
{
241-
auto x = optValue(frameDict, "x"sv).asFloat();
242-
auto y = optValue(frameDict, "y"sv).asFloat();
243-
auto w = optValue(frameDict, "width"sv).asFloat();
244-
auto h = optValue(frameDict, "height"sv).asFloat();
245-
auto ox = optValue(frameDict, "offsetX"sv).asFloat();
246-
auto oy = optValue(frameDict, "offsetY"sv).asFloat();
247-
auto ow = optValue(frameDict, "originalWidth"sv).asInt();
248-
auto oh = optValue(frameDict, "originalHeight"sv).asInt();
249-
// check ow/oh
250-
if (!ow || !oh)
251-
{
252-
AXLOGW(
253-
"WARNING: originalWidth/Height not found on the SpriteFrame. AnchorPoint won't work as "
254-
"expected. Regenerate the .plist");
255-
}
256-
// abs ow/oh
257-
ow = std::abs(ow);
258-
oh = std::abs(oh);
259-
// create frame
260-
spriteFrame = SpriteFrame::createWithTexture(texture, Rect(x, y, w, h), false, Vec2(ox, oy),
261-
Vec2((float)ow, (float)oh));
262-
}
263-
else if (format == 1 || format == 2)
264-
{
265-
auto frame = RectFromString(optValue(frameDict, "frame"sv).asString());
266-
auto rotated = false;
267-
268-
// rotation
269-
if (format == 2)
270-
{
271-
rotated = optValue(frameDict, "rotated"sv).asBool();
272-
}
273-
274-
auto offset = PointFromString(optValue(frameDict, "offset"sv).asString());
275-
auto sourceSize = SizeFromString(optValue(frameDict, "sourceSize"sv).asString());
276-
277-
// create frame
278-
spriteFrame = SpriteFrame::createWithTexture(texture, frame, rotated, offset, sourceSize);
279-
}
280-
else if (format == 3)
281-
{
282-
// get values
283-
auto spriteSize = SizeFromString(optValue(frameDict, "spriteSize"sv).asString());
284-
auto spriteOffset = PointFromString(optValue(frameDict, "spriteOffset"sv).asString());
285-
auto spriteSourceSize = SizeFromString(optValue(frameDict, "spriteSourceSize"sv).asString());
286-
auto textureRect = RectFromString(optValue(frameDict, "textureRect"sv).asString());
287-
auto textureRotated = optValue(frameDict, "textureRotated"sv).asBool();
288-
289-
// get aliases
290-
auto& aliases = optValue(frameDict, "aliases"sv).asValueVector();
291-
292-
for (const auto& value : aliases)
293-
{
294-
auto oneAlias = value.asString();
295-
if (std::find(frameAliases.begin(), frameAliases.end(), oneAlias) == frameAliases.end())
296-
{
297-
frameAliases.emplace_back(std::move(oneAlias));
298-
}
299-
else
300-
{
301-
AXLOGW("WARNING: an alias with name {} already exists", oneAlias);
302-
}
303-
}
304-
305-
// create frame
306-
spriteFrame = SpriteFrame::createWithTexture(
307-
texture, Rect(textureRect.origin.x, textureRect.origin.y, spriteSize.width, spriteSize.height),
308-
textureRotated, spriteOffset, spriteSourceSize);
309-
310-
if (frameDict.find("vertices") != frameDict.end())
311-
{
312-
using ax::utils::parseIntegerList;
313-
auto vertices = parseIntegerList(optValue(frameDict, "vertices"sv).asString());
314-
auto verticesUV = parseIntegerList(optValue(frameDict, "verticesUV"sv).asString());
315-
auto indices = parseIntegerList(optValue(frameDict, "triangles"sv).asString());
316-
317-
PolygonInfo info;
318-
initializePolygonInfo(textureSize, spriteSourceSize, vertices, verticesUV, indices, info);
319-
spriteFrame->setPolygonInfo(info);
320-
}
321-
if (frameDict.find("anchor") != frameDict.end())
322-
{
323-
spriteFrame->setAnchorPoint(PointFromString(optValue(frameDict, "anchor"sv).asString()));
324-
}
325-
}
338+
spriteFrame = parseFrame(frameDict, frameAliases, format, texture, textureSize);
326339

327340
auto flag = NinePatchImageParser::isNinePatchImage(spriteFrameName);
328341
if (flag)
@@ -343,6 +356,7 @@ void PlistSpriteSheetLoader::addSpriteFramesWithDictionary(ValueMap& dictionary,
343356
{
344357
cache.insertFrame(spriteSheet, frameAlias, spriteFrame);
345358
}
359+
frameAliases.clear();
346360
}
347361

348362
spriteSheet->full = true;
@@ -407,10 +421,17 @@ void PlistSpriteSheetLoader::reloadSpriteFramesWithDictionary(ValueMap& dict,
407421
int format = 0;
408422

409423
// get the format
410-
if (dict.find("metadata") != dict.end())
424+
Vec2 textureSize;
425+
auto metaItr = dict.find("metadata"sv);
426+
if (metaItr != dict.end())
411427
{
412-
auto& metadataDict = dict["metadata"].asValueMap();
413-
format = metadataDict["format"].asInt();
428+
auto& metadataDict = metaItr->second.asValueMap();
429+
format = optValue(metadataDict, "format"sv).asInt();
430+
431+
if (metadataDict.find("size"sv) != metadataDict.end())
432+
{
433+
textureSize = SizeFromString(optValue(metadataDict, "size"sv).asString());
434+
}
414435
}
415436

416437
// check the format
@@ -421,94 +442,23 @@ void PlistSpriteSheetLoader::reloadSpriteFramesWithDictionary(ValueMap& dict,
421442
spriteSheet->format = getFormat();
422443
spriteSheet->path = plist;
423444

445+
std::vector<std::string> frameAliases;
424446
for (auto&& iter : framesDict)
425447
{
426448
const ValueMap& frameDict = iter.second.asValueMap();
427449
std::string_view spriteFrameName = iter.first;
428450

429451
cache.eraseFrame(spriteFrameName);
430452

431-
SpriteFrame* spriteFrame = nullptr;
432-
std::vector<std::string> frameAliases;
433-
434-
if (format == 0)
435-
{
436-
const auto x = optValue(frameDict, "x"sv).asFloat();
437-
const auto y = optValue(frameDict, "y"sv).asFloat();
438-
const auto w = optValue(frameDict, "width"sv).asFloat();
439-
const auto h = optValue(frameDict, "height"sv).asFloat();
440-
const auto ox = optValue(frameDict, "offsetX"sv).asFloat();
441-
const auto oy = optValue(frameDict, "offsetY"sv).asFloat();
442-
auto ow = optValue(frameDict, "originalWidth"sv).asInt();
443-
auto oh = optValue(frameDict, "originalHeight"sv).asInt();
444-
// check ow/oh
445-
if (!ow || !oh)
446-
{
447-
AXLOGW(
448-
"WARNING: originalWidth/Height not found on the SpriteFrame. AnchorPoint won't work as "
449-
"expected. Regenerate the .plist");
450-
}
451-
// abs ow/oh
452-
ow = std::abs(ow);
453-
oh = std::abs(oh);
454-
// create frame
455-
spriteFrame = SpriteFrame::createWithTexture(texture, Rect(x, y, w, h), false, Vec2(ox, oy),
456-
Vec2((float)ow, (float)oh));
457-
}
458-
else if (format == 1 || format == 2)
459-
{
460-
auto frame = RectFromString(optValue(frameDict, "frame"sv).asString());
461-
auto rotated = false;
462-
463-
// rotation
464-
if (format == 2)
465-
{
466-
rotated = optValue(frameDict, "rotated"sv).asBool();
467-
}
468-
469-
auto offset = PointFromString(optValue(frameDict, "offset"sv).asString());
470-
auto sourceSize = SizeFromString(optValue(frameDict, "sourceSize"sv).asString());
471-
472-
// create frame
473-
spriteFrame = SpriteFrame::createWithTexture(texture, frame, rotated, offset, sourceSize);
474-
}
475-
else if (format == 3)
476-
{
477-
// get values
478-
const auto spriteSize = SizeFromString(optValue(frameDict, "spriteSize"sv).asString());
479-
auto spriteOffset = PointFromString(optValue(frameDict, "spriteOffset"sv).asString());
480-
auto spriteSourceSize = SizeFromString(optValue(frameDict, "spriteSourceSize"sv).asString());
481-
const auto textureRect = RectFromString(optValue(frameDict, "textureRect"sv).asString());
482-
const auto textureRotated = optValue(frameDict, "textureRotated"sv).asBool();
483-
484-
// get aliases
485-
const ValueVector& aliases = optValue(frameDict, "aliases"sv).asValueVector();
486-
487-
for (const auto& value : aliases)
488-
{
489-
auto oneAlias = value.asString();
490-
if (std::find(frameAliases.begin(), frameAliases.end(), oneAlias) == frameAliases.end())
491-
{
492-
frameAliases.emplace_back(std::move(oneAlias));
493-
}
494-
else
495-
{
496-
AXLOGW("WARNING: an alias with name {} already exists", oneAlias);
497-
}
498-
}
499-
500-
// create frame
501-
spriteFrame = SpriteFrame::createWithTexture(
502-
texture, Rect(textureRect.origin.x, textureRect.origin.y, spriteSize.width, spriteSize.height),
503-
textureRotated, spriteOffset, spriteSourceSize);
504-
}
453+
auto spriteFrame = parseFrame(frameDict, frameAliases, format, texture, textureSize);
505454

506455
// add sprite frame
507456
cache.insertFrame(spriteSheet, spriteFrameName, spriteFrame);
508457
for (auto&& frameAlias : frameAliases)
509458
{
510459
cache.insertFrame(spriteSheet, frameAlias, spriteFrame);
511460
}
461+
frameAliases.clear();
512462
}
513463
}
514464

core/2d/PlistSpriteSheetLoader.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ class PlistSpriteSheetLoader : public SpriteSheetLoader
4646
void reload(std::string_view filePath, SpriteFrameCache& cache) override;
4747

4848
protected:
49+
SpriteFrame* parseFrame(const ValueMap& frameDict,
50+
std::vector<std::string>& frameAliases,
51+
int format,
52+
Texture2D* texture,
53+
const ax::Vec2& textureSize);
54+
4955
/*Adds multiple Sprite Frames with a dictionary. The texture will be associated with the created sprite frames.
5056
*/
5157
void addSpriteFramesWithDictionary(ValueMap& dictionary,

0 commit comments

Comments
 (0)