diff --git a/core/2d/TMXXMLParser.cpp b/core/2d/TMXXMLParser.cpp index 3d7d5c90324..d8609844222 100644 --- a/core/2d/TMXXMLParser.cpp +++ b/core/2d/TMXXMLParser.cpp @@ -32,13 +32,13 @@ THE SOFTWARE. #include #include #include -// #include "2d/TMXTiledMap.h" + #include "base/ZipUtils.h" #include "base/Director.h" #include "base/Utils.h" #include "platform/FileUtils.h" - -// using namespace std; +#include +#include namespace ax { @@ -596,36 +596,36 @@ void TMXMapInfo::startElement(void* /*ctx*/, const char* name, const char** atts ValueVector pointsArray; pointsArray.reserve(10); - // parse points string into a space-separated set of points - std::stringstream pointsStream(value); - std::string pointPair; - while (std::getline(pointsStream, pointPair, ' ')) + const auto offsetX = static_cast(objectGroup->getPositionOffset().x); + const auto offsetY = static_cast(objectGroup->getPositionOffset().y); + // std::views::split 2~3x faster than std::getline + for (auto rgn : std::views::split(value, ' ')) { - // parse each point combo into a comma-separated x,y point - std::stringstream pointStream(pointPair); - std::string xStr, yStr; - + std::string_view citem{&*rgn.begin(), static_cast(std::ranges::distance(rgn))}; + int idx = 0; ValueMap pointDict; - - // set x - if (std::getline(pointStream, xStr, ',')) - { - int x = atoi(xStr.c_str()) + (int)objectGroup->getPositionOffset().x; - pointDict["x"] = Value(x); - } - - // set y - if (std::getline(pointStream, yStr, ',')) + for (auto subrgn : std::views::split(citem, ',')) { - int y = atoi(yStr.c_str()) + (int)objectGroup->getPositionOffset().y; - pointDict["y"] = Value(y); + int axisVal = 0; + std::string_view word{&*subrgn.begin(), static_cast(std::ranges::distance(subrgn))}; + std::from_chars(word.begin(), word.end(), axisVal, 10); + switch (idx++) + { + case 0: + pointDict["x"] = Value(axisVal + offsetX); + break; + case 1: + pointDict["y"] = Value(axisVal + offsetY); + break; + } + if (idx == 2) + break; } - // add to points array - pointsArray.emplace_back(Value(pointDict)); + pointsArray.emplace_back(Value(std::move(pointDict))); } - dict["points"] = Value(pointsArray); + dict["points"] = Value(std::move(pointsArray)); } } else if (elementName == "polyline") @@ -641,36 +641,34 @@ void TMXMapInfo::startElement(void* /*ctx*/, const char* name, const char** atts ValueVector pointsArray; pointsArray.reserve(10); - // parse points string into a space-separated set of points - std::stringstream pointsStream(value); - std::string pointPair; - while (std::getline(pointsStream, pointPair, ' ')) + const auto offsetX = static_cast(objectGroup->getPositionOffset().x); + const auto offsetY = static_cast(objectGroup->getPositionOffset().y); + for (auto rgn : std::views::split(value, ' ')) { - // parse each point combo into a comma-separated x,y point - std::stringstream pointStream(pointPair); - std::string xStr, yStr; - + std::string_view citem{&*rgn.begin(), static_cast(std::ranges::distance(rgn))}; + int idx = 0; ValueMap pointDict; - - // set x - if (std::getline(pointStream, xStr, ',')) + for (auto subrgn : std::views::split(citem, ',')) { - int x = atoi(xStr.c_str()) + (int)objectGroup->getPositionOffset().x; - pointDict["x"] = Value(x); + int axisVal = 0; + std::string_view word{&*subrgn.begin(), static_cast(std::ranges::distance(subrgn))}; + std::from_chars(word.begin(), word.end(), axisVal, 10); + switch (idx++) + { + case 0: + pointDict["x"] = Value(axisVal + offsetX); + break; + case 1: + pointDict["y"] = Value(axisVal + offsetY); + break; + } + if (idx == 2) + break; } - - // set y - if (std::getline(pointStream, yStr, ',')) - { - int y = atoi(yStr.c_str()) + (int)objectGroup->getPositionOffset().y; - pointDict["y"] = Value(y); - } - // add to points array - pointsArray.emplace_back(Value(pointDict)); + pointsArray.emplace_back(Value(std::move(pointDict))); } - - dict["polylinePoints"] = Value(pointsArray); + dict["polylinePoints"] = Value(std::move(pointsArray)); } } else if (elementName == "animation") @@ -741,31 +739,17 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char* name) tmxMapInfo->setStoringCharacters(false); auto currentString = tmxMapInfo->getCurrentString(); - std::vector gidTokens; - std::stringstream filestr; - filestr << currentString; - std::string sRow; - while (std::getline(filestr, sRow, '\n')) - { - std::string sGID; - std::istringstream rowstr(sRow); - while (std::getline(rowstr, sGID, ',')) - { - gidTokens.emplace_back(sGID); - } - } - - // 32-bits per gid - axstd::pod_vector buffer(gidTokens.size()); - uint32_t* bufferPtr = buffer.data(); - for (const auto& gidToken : gidTokens) - { - auto tileGid = (uint32_t)strtoul(gidToken.c_str(), nullptr, 10); - *bufferPtr = tileGid; - bufferPtr++; - } - - layer->_tiles = buffer.release_pointer(); + axstd::pod_vector tileGids; + axstd::split_cb(currentString, '\n', [&tileGids](const char* first, const char* last) { + axstd::split_cb(std::string_view{first, static_cast(last - first)}, ',', + [&tileGids](const char* _first, const char* _last) { + unsigned int gid{0}; + std::from_chars(_first, _last, gid, 10); + tileGids.push_back(gid); + }); + }); + + layer->_tiles = tileGids.release_pointer(); tmxMapInfo->setCurrentString(""); }