Skip to content

Commit

Permalink
Use 0 GC split to instead std::getline
Browse files Browse the repository at this point in the history
  • Loading branch information
halx99 committed Jan 17, 2025
1 parent 3057f49 commit 3dd4a2d
Showing 1 changed file with 59 additions and 75 deletions.
134 changes: 59 additions & 75 deletions core/2d/TMXXMLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ THE SOFTWARE.
#include <unordered_map>
#include <sstream>
#include <regex>
// #include "2d/TMXTiledMap.h"

#include "base/ZipUtils.h"
#include "base/Director.h"
#include "base/Utils.h"
#include "platform/FileUtils.h"

// using namespace std;
#include <ranges>
#include <charconv>

namespace ax
{
Expand Down Expand Up @@ -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<int>(objectGroup->getPositionOffset().x);
const auto offsetY = static_cast<int>(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<size_t>(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<size_t>(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")
Expand All @@ -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<int>(objectGroup->getPositionOffset().x);
const auto offsetY = static_cast<int>(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<size_t>(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<size_t>(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")
Expand Down Expand Up @@ -741,31 +739,17 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char* name)
tmxMapInfo->setStoringCharacters(false);
auto currentString = tmxMapInfo->getCurrentString();

std::vector<std::string> 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<uint32_t> 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<uint32_t> tileGids;
axstd::split_cb(currentString, '\n', [&tileGids](const char* first, const char* last) {
axstd::split_cb(std::string_view{first, static_cast<size_t>(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("");
}
Expand Down

0 comments on commit 3dd4a2d

Please sign in to comment.