MyCurry/src/gamelib/csvloader.cpp

99 lines
3.0 KiB
C++

/*
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
This file is part of MyCurry.
MyCurry is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MyCurry is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
*/
#define BOOST_SPIRIT_USE_PHOENIX_V3 1
#include "csvloader.hpp"
#include <boost/spirit/include/qi_core.hpp>
#include <boost/spirit/include/qi_parse.hpp>
#include <boost/spirit/include/qi_lit.hpp>
#include <boost/spirit/include/qi_eoi.hpp>
#include <boost/spirit/include/qi_eol.hpp>
#include <boost/spirit/include/qi_kleene.hpp>
#include <boost/spirit/include/qi_numeric.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <boost/phoenix/core/reference.hpp>
#include <boost/phoenix/operator/arithmetic.hpp>
#include <sstream>
#include <fstream>
#include <ciso646>
#include <utility>
#include <algorithm>
namespace qi = boost::spirit::qi;
namespace curry {
CSVJointData load_csv(const std::vector<std::string>& parCsvPath) {
typedef boost::spirit::istream_iterator iter_type;
using boost::phoenix::ref;
qi::int_parser<TileIndex> idx;
//auto csv_parser = *((qi::int_ % ',') >> -qi::eol) >> qi::eoi;
CSVJointData out_csv;
std::size_t row_count = 0;
TileIndex largest_tile_idx = 0;
for (auto& csv_path : parCsvPath) {
std::ifstream f_map(csv_path);
f_map.unsetf(std::ios::skipws);
std::vector<TileIndex> curr_data;
row_count = 0;
const bool parse_fail = qi::parse(
iter_type(f_map),
iter_type(),
idx % (',' | qi::eol[ref(row_count) += 1]) >> qi::eoi,
curr_data
);
if (parse_fail) {
std::ostringstream oss;
oss << "Error parsing csv \"" << csv_path << "\"";
throw std::runtime_error(oss.str());
}
if (not curr_data.empty()) {
largest_tile_idx = std::max(*std::max_element(curr_data.begin(), curr_data.end()), largest_tile_idx);
}
out_csv.tables.emplace_back(std::move(curr_data));
}
if (not out_csv.tables.empty()) {
out_csv.height = static_cast<uint16_t>(row_count);
out_csv.width = static_cast<uint16_t>(out_csv.tables.front().size() / row_count);
}
else {
out_csv.height = out_csv.width = 0;
}
out_csv.tile_properties.resize(static_cast<size_t>(largest_tile_idx) + 1);
out_csv.tile_properties[2].walkable = false;
#if !defined(NDEBUG)
for (const auto& table : out_csv.tables) {
for (const auto& val : table) {
const auto casted_val = static_cast<size_t>(val);
assert(val < 0 or casted_val < out_csv.tile_properties.size());
}
}
#endif
return out_csv;
}
} //namespace curry