30#ifndef TILESON_TILESON_H
31#define TILESON_TILESON_H
60#include <initializer_list>
66#define JSON11_IS_DEFINED
71 #define noexcept throw()
75 #define snprintf _snprintf_s
102 typedef std::vector<Json> array;
103 typedef std::map<std::string, Json> object;
106 inline Json()
noexcept;
107 inline Json(std::nullptr_t)
noexcept;
108 inline Json(
double value);
109 inline Json(
int value);
110 inline Json(
bool value);
111 inline Json(
const std::string &value);
112 inline Json(std::string &&value);
113 inline Json(
const char *value);
114 inline Json(
const array &values);
115 inline Json(array &&values);
116 inline Json(
const object &values);
117 inline Json(
object &&values);
120 template<
class T,
class = decltype(&T::to_json)>
121 inline Json(
const T &t) :
Json(t.to_json())
125 template<class M, typename std::enable_if<std::is_constructible<std::string, decltype(std::declval<M>().begin()->first)>::value &&
126 std::is_constructible<
Json,
decltype(std::declval<M>().begin()->second)>::value,
128 inline Json(
const M &m) :
Json(
object(m.begin(), m.end()))
132 template<class V, typename std::enable_if<std::is_constructible<Json, decltype(*std::declval<V>().begin())>::value,
int>::type = 0>
133 inline Json(
const V &v) :
Json(array(v.begin(), v.end()))
138 Json(
void *) =
delete;
141 inline Type type()
const;
143 inline bool is_null()
const {
return type() == NUL; }
145 inline bool is_number()
const {
return type() == NUMBER; }
147 inline bool is_bool()
const {
return type() == BOOL; }
149 inline bool is_string()
const {
return type() == STRING; }
151 inline bool is_array()
const {
return type() == ARRAY; }
153 inline bool is_object()
const {
return type() == OBJECT; }
158 inline double number_value()
const;
159 inline int int_value()
const;
162 inline bool bool_value()
const;
164 inline const std::string &string_value()
const;
166 inline const array &array_items()
const;
168 inline const object &object_items()
const;
171 inline const Json &operator[](
size_t i)
const;
173 inline const Json &operator[](
const std::string &key)
const;
176 inline void dump(std::string &out)
const;
178 inline std::string dump()
const
186 static inline Json parse(
const std::string &in, std::string &err, JsonParse strategy = JsonParse::STANDARD);
188 static inline Json parse(
const char *in, std::string &err, JsonParse strategy = JsonParse::STANDARD)
191 return parse(std::string(in), err, strategy);
199 static inline std::vector<Json> parse_multi(
200 const std::string &in, std::string::size_type &parser_stop_pos, std::string &err, JsonParse strategy = JsonParse::STANDARD);
202 static inline std::vector<Json> parse_multi(
const std::string &in, std::string &err, JsonParse strategy = JsonParse::STANDARD)
204 std::string::size_type parser_stop_pos;
205 return parse_multi(in, parser_stop_pos, err, strategy);
208 inline bool operator==(
const Json &rhs)
const;
209 inline bool operator<(
const Json &rhs)
const;
211 inline bool operator!=(
const Json &rhs)
const {
return !(*
this == rhs); }
213 inline bool operator<=(
const Json &rhs)
const {
return !(rhs < *
this); }
215 inline bool operator>(
const Json &rhs)
const {
return (rhs < *
this); }
217 inline bool operator>=(
const Json &rhs)
const {
return !(*
this < rhs); }
224 typedef std::initializer_list<std::pair<std::string, Type>> shape;
225 inline bool has_shape(
const shape &types, std::string &err)
const;
228 std::shared_ptr<JsonValue> m_ptr;
237 virtual Json::Type type()
const = 0;
238 virtual bool equals(
const JsonValue *other)
const = 0;
239 virtual bool less(
const JsonValue *other)
const = 0;
240 virtual void dump(std::string &out)
const = 0;
241 virtual double number_value()
const;
242 virtual int int_value()
const;
243 virtual bool bool_value()
const;
244 virtual const std::string &string_value()
const;
245 virtual const Json::array &array_items()
const;
246 virtual const Json &operator[](
size_t i)
const;
247 virtual const Json::object &object_items()
const;
248 virtual const Json &operator[](
const std::string &key)
const;
265 static const int max_depth = 200;
267 using std::initializer_list;
268 using std::make_shared;
279 bool operator==(
NullStruct)
const {
return true; }
281 bool operator<(
NullStruct)
const {
return false; }
293 static void dump(
double value,
string &out)
295 if (std::isfinite(value)) {
297 snprintf(buf,
sizeof buf,
"%.17g", value);
304 static void dump(
int value,
string &out)
307 snprintf(buf,
sizeof buf,
"%d", value);
311 static void dump(
bool value,
string &out)
313 out += value ?
"true" :
"false";
316 static void dump(
const string &value,
string &out)
319 for (
size_t i = 0; i < value.length(); i++) {
320 const char ch = value[i];
323 }
else if (ch ==
'"') {
325 }
else if (ch ==
'\b') {
327 }
else if (ch ==
'\f') {
329 }
else if (ch ==
'\n') {
331 }
else if (ch ==
'\r') {
333 }
else if (ch ==
'\t') {
335 }
else if (
static_cast<uint8_t
>(ch) <= 0x1f) {
337 snprintf(buf,
sizeof buf,
"\\u%04x", ch);
339 }
else if (
static_cast<uint8_t
>(ch) == 0xe2 &&
static_cast<uint8_t
>(value[i + 1]) == 0x80 &&
static_cast<uint8_t
>(value[i + 2]) == 0xa8) {
342 }
else if (
static_cast<uint8_t
>(ch) == 0xe2 &&
static_cast<uint8_t
>(value[i + 1]) == 0x80 &&
static_cast<uint8_t
>(value[i + 2]) == 0xa9) {
352 static void dump(
const Json::array &values,
string &out)
356 for (
const auto &value : values) {
357 if (!first) out +=
", ";
364 static void dump(
const Json::object &values,
string &out)
368 for (
const auto &kv : values) {
369 if (!first) out +=
", ";
378 void Json::dump(
string &out)
const
387 template<Json::Type tag,
typename T>
391 explicit Value(
const T &value) : m_value(value) {}
393 explicit Value(T &&value) : m_value(move(value)) {}
396 Json::Type type()
const override {
return tag; }
399 bool equals(
const JsonValue *other)
const override {
return m_value ==
static_cast<const Value<tag, T> *
>(other)->m_value; }
401 bool less(
const JsonValue *other)
const override {
return m_value < static_cast<const Value<tag, T> *>(other)->m_value; }
405 void dump(
string &out)
const override { json11::dump(m_value, out); }
409 double number_value()
const override {
return m_value; }
411 int int_value()
const override {
return static_cast<int>(m_value); }
413 bool equals(
const JsonValue *other)
const override {
return m_value == other->number_value(); }
415 bool less(
const JsonValue *other)
const override {
return m_value < other->number_value(); }
422 double number_value()
const override {
return m_value; }
424 int int_value()
const override {
return m_value; }
426 bool equals(
const JsonValue *other)
const override {
return m_value == other->number_value(); }
428 bool less(
const JsonValue *other)
const override {
return m_value < other->number_value(); }
435 bool bool_value()
const override {
return m_value; }
442 const string &string_value()
const override {
return m_value; }
451 const Json::array &array_items()
const override {
return m_value; }
453 const Json &operator[](
size_t i)
const override;
462 const Json::object &object_items()
const override {
return m_value; }
464 const Json &operator[](
const string &key)
const override;
481 const std::shared_ptr<JsonValue> null = make_shared<JsonNull>();
482 const std::shared_ptr<JsonValue> t = make_shared<JsonBoolean>(
true);
483 const std::shared_ptr<JsonValue> f = make_shared<JsonBoolean>(
false);
484 const string empty_string;
485 const vector<Json> empty_vector;
486 const map<string, Json> empty_map;
491 static const Statics &statics()
497 static const Json &static_null()
500 static const Json json_null;
508 Json::Json() noexcept : m_ptr(statics().null) {}
510 Json::Json(std::nullptr_t) noexcept : m_ptr(statics().null) {}
512 Json::Json(
double value) : m_ptr(make_shared<JsonDouble>(value)) {}
514 Json::Json(
int value) : m_ptr(make_shared<JsonInt>(value)) {}
516 Json::Json(
bool value) : m_ptr(value ? statics().t : statics().f) {}
518 Json::Json(
const string &value) : m_ptr(make_shared<JsonString>(value)) {}
520 Json::Json(
string &&value) : m_ptr(make_shared<JsonString>(move(value))) {}
522 Json::Json(
const char *value) : m_ptr(make_shared<JsonString>(value)) {}
524 Json::Json(
const Json::array &values) : m_ptr(make_shared<JsonArray>(values)) {}
526 Json::Json(Json::array &&values) : m_ptr(make_shared<JsonArray>(move(values))) {}
528 Json::Json(
const Json::object &values) : m_ptr(make_shared<JsonObject>(values)) {}
530 Json::Json(Json::object &&values) : m_ptr(make_shared<JsonObject>(move(values))) {}
536 inline Json::Type Json::type()
const
538 return m_ptr->type();
541 inline double Json::number_value()
const
543 return m_ptr->number_value();
546 inline int Json::int_value()
const
548 return m_ptr->int_value();
551 inline bool Json::bool_value()
const
553 return m_ptr->bool_value();
556 inline const string &Json::string_value()
const
558 return m_ptr->string_value();
561 inline const vector<Json> &Json::array_items()
const
563 return m_ptr->array_items();
566 inline const map<string, Json> &Json::object_items()
const
568 return m_ptr->object_items();
571 inline const Json &Json::operator[](
size_t i)
const
576 inline const Json &Json::operator[](
const string &key)
const
578 return (*m_ptr)[key];
581 inline double JsonValue::number_value()
const
586 inline int JsonValue::int_value()
const
591 inline bool JsonValue::bool_value()
const
596 inline const string &JsonValue::string_value()
const
598 return statics().empty_string;
601 inline const vector<Json> &JsonValue::array_items()
const
603 return statics().empty_vector;
606 inline const map<string, Json> &JsonValue::object_items()
const
608 return statics().empty_map;
611 inline const Json &JsonValue::operator[](
size_t)
const
613 return static_null();
616 inline const Json &JsonValue::operator[](
const string &)
const
618 return static_null();
621 inline const Json &JsonObject::operator[](
const string &key)
const
623 auto iter = m_value.find(key);
624 return (iter == m_value.end()) ? static_null() : iter->second;
627 inline const Json &JsonArray::operator[](
size_t i)
const
629 if (i >= m_value.size())
630 return static_null();
639 bool Json::operator==(
const Json &other)
const
641 if (m_ptr == other.m_ptr)
return true;
642 if (m_ptr->type() != other.m_ptr->type())
return false;
644 return m_ptr->equals(other.m_ptr.get());
647 bool Json::operator<(
const Json &other)
const
649 if (m_ptr == other.m_ptr)
return false;
650 if (m_ptr->type() != other.m_ptr->type())
return m_ptr->type() < other.m_ptr->type();
652 return m_ptr->less(other.m_ptr.get());
663 static inline string esc(
char c)
666 if (
static_cast<uint8_t
>(c) >= 0x20 &&
static_cast<uint8_t
>(c) <= 0x7f) {
667 snprintf(buf,
sizeof buf,
"'%c' (%d)", c, c);
669 snprintf(buf,
sizeof buf,
"(%d)", c);
674 static inline bool in_range(
long x,
long lower,
long upper)
676 return (x >= lower && x <= upper);
691 const JsonParse strategy;
697 Json fail(
string &&msg) {
return fail(move(msg),
Json()); }
700 T fail(
string &&msg,
const T err_ret)
702 if (!failed) err = std::move(msg);
711 void consume_whitespace()
713 while (str[i] ==
' ' || str[i] ==
'\r' || str[i] ==
'\n' || str[i] ==
'\t')
721 bool consume_comment()
723 bool comment_found =
false;
726 if (i == str.size())
return fail(
"unexpected end of input after start of comment",
false);
730 while (i < str.size() && str[i] !=
'\n') {
733 comment_found =
true;
734 }
else if (str[i] ==
'*') {
736 if (i > str.size() - 2)
return fail(
"unexpected end of input inside multi-line comment",
false);
738 while (!(str[i] ==
'*' && str[i + 1] ==
'/')) {
740 if (i > str.size() - 2)
return fail(
"unexpected end of input inside multi-line comment",
false);
743 comment_found =
true;
745 return fail(
"malformed comment",
false);
747 return comment_found;
754 void consume_garbage()
756 consume_whitespace();
757 if (strategy == JsonParse::COMMENTS) {
758 bool comment_found =
false;
760 comment_found = consume_comment();
762 consume_whitespace();
763 }
while (comment_found);
772 char get_next_token()
775 if (failed)
return static_cast<char>(0);
776 if (i == str.size())
return fail(
"unexpected end of input",
static_cast<char>(0));
785 void encode_utf8(
long pt,
string &out)
790 out +=
static_cast<char>(pt);
791 }
else if (pt < 0x800) {
792 out +=
static_cast<char>((pt >> 6) | 0xC0);
793 out +=
static_cast<char>((pt & 0x3F) | 0x80);
794 }
else if (pt < 0x10000) {
795 out +=
static_cast<char>((pt >> 12) | 0xE0);
796 out +=
static_cast<char>(((pt >> 6) & 0x3F) | 0x80);
797 out +=
static_cast<char>((pt & 0x3F) | 0x80);
799 out +=
static_cast<char>((pt >> 18) | 0xF0);
800 out +=
static_cast<char>(((pt >> 12) & 0x3F) | 0x80);
801 out +=
static_cast<char>(((pt >> 6) & 0x3F) | 0x80);
802 out +=
static_cast<char>((pt & 0x3F) | 0x80);
810 string parse_string()
813 long last_escaped_codepoint = -1;
815 if (i == str.size())
return fail(
"unexpected end of input in string",
"");
820 encode_utf8(last_escaped_codepoint, out);
824 if (in_range(ch, 0, 0x1f))
return fail(
"unescaped " + esc(ch) +
" in string",
"");
828 encode_utf8(last_escaped_codepoint, out);
829 last_escaped_codepoint = -1;
835 if (i == str.size())
return fail(
"unexpected end of input in string",
"");
841 string esc = str.substr(i, 4);
845 if (esc.length() < 4) {
846 return fail(
"bad \\u escape: " + esc,
"");
848 for (
size_t j = 0; j < 4; j++) {
849 if (!in_range(esc[j],
'a',
'f') && !in_range(esc[j],
'A',
'F') && !in_range(esc[j],
'0',
'9'))
850 return fail(
"bad \\u escape: " + esc,
"");
853 long codepoint = strtol(esc.data(),
nullptr, 16);
859 if (in_range(last_escaped_codepoint, 0xD800, 0xDBFF) && in_range(codepoint, 0xDC00, 0xDFFF)) {
862 encode_utf8((((last_escaped_codepoint - 0xD800) << 10) | (codepoint - 0xDC00)) + 0x10000, out);
863 last_escaped_codepoint = -1;
865 encode_utf8(last_escaped_codepoint, out);
866 last_escaped_codepoint = codepoint;
873 encode_utf8(last_escaped_codepoint, out);
874 last_escaped_codepoint = -1;
878 }
else if (ch ==
'f') {
880 }
else if (ch ==
'n') {
882 }
else if (ch ==
'r') {
884 }
else if (ch ==
't') {
886 }
else if (ch ==
'"' || ch ==
'\\' || ch ==
'/') {
889 return fail(
"invalid escape character " + esc(ch),
"");
900 size_t start_pos = i;
902 if (str[i] ==
'-') i++;
907 if (in_range(str[i],
'0',
'9'))
return fail(
"leading 0s not permitted in numbers");
908 }
else if (in_range(str[i],
'1',
'9')) {
910 while (in_range(str[i],
'0',
'9'))
913 return fail(
"invalid " + esc(str[i]) +
" in number");
916 if (str[i] !=
'.' && str[i] !=
'e' && str[i] !=
'E' && (i - start_pos) <=
static_cast<size_t>(std::numeric_limits<int>::digits10)) {
917 return std::atoi(str.c_str() + start_pos);
923 if (!in_range(str[i],
'0',
'9'))
return fail(
"at least one digit required in fractional part");
925 while (in_range(str[i],
'0',
'9'))
930 if (str[i] ==
'e' || str[i] ==
'E') {
933 if (str[i] ==
'+' || str[i] ==
'-') i++;
935 if (!in_range(str[i],
'0',
'9'))
return fail(
"at least one digit required in exponent");
937 while (in_range(str[i],
'0',
'9'))
941 return std::strtod(str.c_str() + start_pos,
nullptr);
949 Json expect(
const string &expected,
Json res)
953 if (str.compare(i, expected.length(), expected) == 0) {
954 i += expected.length();
957 return fail(
"parse error: expected " + expected +
", got " + str.substr(i, expected.length()));
965 Json parse_json(
int depth)
967 if (depth > max_depth) {
968 return fail(
"exceeded maximum nesting depth");
971 char ch = get_next_token();
972 if (failed)
return Json();
974 if (ch ==
'-' || (ch >=
'0' && ch <=
'9')) {
976 return parse_number();
979 if (ch ==
't')
return expect(
"true",
true);
981 if (ch ==
'f')
return expect(
"false",
false);
983 if (ch ==
'n')
return expect(
"null",
Json());
985 if (ch ==
'"')
return parse_string();
988 map<string, Json> data;
989 ch = get_next_token();
990 if (ch ==
'}')
return data;
993 if (ch !=
'"')
return fail(
"expected '\"' in object, got " + esc(ch));
995 string key = parse_string();
996 if (failed)
return Json();
998 ch = get_next_token();
999 if (ch !=
':')
return fail(
"expected ':' in object, got " + esc(ch));
1001 data[std::move(key)] = parse_json(depth + 1);
1002 if (failed)
return Json();
1004 ch = get_next_token();
1005 if (ch ==
'}')
break;
1006 if (ch !=
',')
return fail(
"expected ',' in object, got " + esc(ch));
1008 ch = get_next_token();
1015 ch = get_next_token();
1016 if (ch ==
']')
return data;
1020 data.push_back(parse_json(depth + 1));
1021 if (failed)
return Json();
1023 ch = get_next_token();
1024 if (ch ==
']')
break;
1025 if (ch !=
',')
return fail(
"expected ',' in list, got " + esc(ch));
1027 ch = get_next_token();
1033 return fail(
"expected value, got " + esc(ch));
1038 Json Json::parse(
const string &in,
string &err, JsonParse strategy)
1040 JsonParser parser {in, 0, err,
false, strategy};
1041 Json result = parser.parse_json(0);
1044 parser.consume_garbage();
1045 if (parser.failed)
return Json();
1046 if (parser.i != in.size() &&
1047 ((parser.i + 1) != in.size() &&
1050 return parser.fail(
"unexpected trailing " + esc(in[parser.i]));
1056 vector<Json> Json::parse_multi(
const string &in, std::string::size_type &parser_stop_pos,
string &err, JsonParse strategy)
1058 JsonParser parser {in, 0, err,
false, strategy};
1059 parser_stop_pos = 0;
1060 vector<Json> json_vec;
1061 while (parser.i != in.size() && !parser.failed) {
1062 json_vec.push_back(parser.parse_json(0));
1063 if (parser.failed)
break;
1066 parser.consume_garbage();
1067 if (parser.failed)
break;
1068 parser_stop_pos = parser.i;
1077 bool Json::has_shape(
const shape &types,
string &err)
const
1080 err =
"expected JSON object, got " + dump();
1084 const auto &obj_items = object_items();
1085 for (
auto &item : types) {
1086 const auto it = obj_items.find(item.first);
1087 if (it == obj_items.cend() || it->second.type() != item.second) {
1088 err =
"bad type for " + item.first +
" in " + dump();
1107#ifndef TILESON_TILESON_PARSER_HPP
1108 #define TILESON_TILESON_PARSER_HPP
1111 #if _MSC_VER && !__INTEL_COMPILER
1112 #include <filesystem>
1113namespace fs = std::filesystem;
1115 #if __MINGW64_VERSION_MAJOR > 6
1116 #include <filesystem>
1117namespace fs = std::filesystem;
1119 #include <experimental/filesystem>
1120namespace fs = std::experimental::filesystem;
1123 #if __clang_major__ < 8
1124 #include <experimental/filesystem>
1125namespace fs = std::experimental::filesystem;
1127 #include <filesystem>
1128namespace fs = std::filesystem;
1132 #include <experimental/filesystem>
1133namespace fs = std::experimental::filesystem;
1135 #include <filesystem>
1136namespace fs = std::filesystem;
1149 #ifndef TILESON_TOOLS_HPP
1150 #define TILESON_TOOLS_HPP
1153 #include <string_view>
1162 inline static std::vector<uint32_t>
BytesToUnsignedInts(
const std::vector<uint8_t> &bytes);
1163 inline static std::vector<std::string> SplitString(
const std::string &s,
char delim);
1164 inline static bool Equal(
float a,
float b,
float precision = 8192.f);
1167 template<
typename Out>
1168 static void split(
const std::string &s,
char delim, Out result)
1170 std::stringstream ss;
1174 while (std::getline(ss, item, delim)) {
1187 std::vector<uint8_t> bytes;
1188 for (
size_t i = 0; i < str.size(); ++i) {
1189 uint8_t u8 =
static_cast<uint8_t
>(str[i]);
1190 bytes.push_back(u8);
1202 std::vector<uint32_t> uints;
1203 std::vector<uint8_t> toConvert;
1206 for (
size_t i = 0; i < bytes.size(); ++i) {
1207 toConvert.push_back(bytes[i]);
1208 if (toConvert.size() == 4) {
1209 uint32_t u32 = (toConvert[3] << 24) | (toConvert[2] << 16) | (toConvert[1] << 8) | toConvert[0];
1210 uints.push_back(u32);
1218 std::vector<std::string> Tools::SplitString(
const std::string &s,
char delim)
1220 std::vector<std::string> elems;
1221 split(s, delim, std::back_inserter(elems));
1233 float threshold = 1.f / precision;
1234 float diff = fabsf(a - b);
1235 return diff <= threshold;
1249 #ifndef TILESON_BASE64DECOMPRESSOR_HPP
1250 #define TILESON_BASE64DECOMPRESSOR_HPP
1257 #ifndef TILESON_IDECOMPRESSOR_HPP
1258 #define TILESON_IDECOMPRESSOR_HPP
1260 #include <string_view>
1263 template<
class TIn,
class TOut>
1278 virtual const std::string &
name()
const = 0;
1318 inline const std::string &
name()
const override;
1320 inline std::string
decompress(
const std::string_view &s)
override;
1322 inline std::string
decompressFile(
const fs::path &path)
override;
1323 inline std::string
decompress(
const void *data,
size_t size)
override;
1326 inline unsigned int pos_of_char(
const unsigned char chr);
1327 inline static const std::string NAME =
"base64";
1337 size_t length_of_string = s.length();
1338 if (!length_of_string)
return std::string(
"");
1340 size_t in_len = length_of_string;
1349 size_t approx_length_of_decoded_string = length_of_string / 4 * 3;
1351 ret.reserve(approx_length_of_decoded_string);
1353 while (pos < in_len) {
1354 unsigned int pos_of_char_1 = pos_of_char(s[pos + 1]);
1356 ret.push_back(
static_cast<std::string::value_type
>(((pos_of_char(s[pos + 0])) << 2) + ((pos_of_char_1 & 0x30) >> 4)));
1358 if (s[pos + 2] !=
'=' && s[pos + 2] !=
'.') {
1360 unsigned int pos_of_char_2 = pos_of_char(s[pos + 2]);
1361 ret.push_back(
static_cast<std::string::value_type
>(((pos_of_char_1 & 0x0f) << 4) + ((pos_of_char_2 & 0x3c) >> 2)));
1363 if (s[pos + 3] !=
'=' && s[pos + 3] !=
'.') {
1364 ret.push_back(
static_cast<std::string::value_type
>(((pos_of_char_2 & 0x03) << 6) + pos_of_char(s[pos + 3])));
1374 unsigned int Base64Decompressor::pos_of_char(
const unsigned char chr)
1380 if (chr >=
'A' && chr <=
'Z')
1382 else if (chr >=
'a' && chr <=
'z')
1383 return chr -
'a' + (
'Z' -
'A') + 1;
1384 else if (chr >=
'0' && chr <=
'9')
1385 return chr -
'0' + (
'Z' -
'A') + (
'z' -
'a') + 2;
1386 else if (chr ==
'+' || chr ==
'-')
1388 else if (chr ==
'/' || chr ==
'_')
1391 throw "If input is correct, this line should never be reached.";
1401 return std::string();
1411 return std::string();
1424 #ifdef POCKETLZMA_POCKETLZMA_H
1426 #ifndef TILESON_LZMA_HPP
1427 #define TILESON_LZMA_HPP
1430 class Lzma :
public IDecompressor<std::vector<uint8_t>, std::vector<uint8_t>> {
1432 inline const std::string &name()
const override {
return NAME; }
1434 inline std::vector<uint8_t> decompress(
const std::vector<uint8_t> &input)
override
1436 std::vector<uint8_t> out;
1439 plz::StatusCode status = p.decompress(input, out);
1441 if (status != plz::StatusCode::Ok)
return std::vector<uint8_t>();
1446 inline std::vector<uint8_t> decompressFile(
const fs::path &path)
override
1448 std::vector<uint8_t> in;
1449 std::vector<uint8_t> out;
1452 plz::FileStatus fileStatus = plz::File::FromFile(path.generic_string(), in);
1453 if (fileStatus.status() != plz::FileStatus::Code::Ok)
return std::vector<uint8_t>();
1455 plz::StatusCode status = p.decompress(in, out);
1457 if (status != plz::StatusCode::Ok)
return std::vector<uint8_t>();
1462 inline std::vector<uint8_t> decompress(
const void *data,
size_t size)
override
1464 std::vector<uint8_t> out;
1467 plz::StatusCode status = p.decompress((uint8_t *) data, size, out);
1469 if (status != plz::StatusCode::Ok)
return std::vector<uint8_t>();
1475 inline static const std::string NAME {
"lzma"};
1489 #ifndef TILESON_DECOMPRESSORCONTAINER_HPP
1490 #define TILESON_DECOMPRESSORCONTAINER_HPP
1492 #include <functional>
1494 #include <string_view>
1501 template<
typename T,
typename... Args>
1502 inline void add(Args &&...args);
1503 inline void remove(std::string_view name);
1504 inline bool contains(std::string_view name)
const;
1505 inline bool empty()
const;
1506 inline size_t size()
const;
1507 inline void clear();
1513 std::vector<std::unique_ptr<IDecompressor<std::string_view, std::string>>> m_decompressors;
1516 template<
typename T,
typename... Args>
1517 void DecompressorContainer::add(Args &&...args)
1519 m_decompressors.emplace_back(
new T(args...));
1529 auto iter = std::find_if(m_decompressors.begin(), m_decompressors.end(), [&](
const auto &item) { return item->name() == name; });
1531 return iter != m_decompressors.end();
1540 auto iter = std::remove_if(m_decompressors.begin(), m_decompressors.end(), [&](
const auto &item) { return item->name() == name; });
1541 m_decompressors.erase(iter);
1544 size_t DecompressorContainer::size()
const
1546 return m_decompressors.size();
1556 auto iter = std::find_if(m_decompressors.begin(), m_decompressors.end(), [&](
const auto &item) { return item->name() == name; });
1558 return (iter != m_decompressors.end()) ? iter->get() :
nullptr;
1567 return m_decompressors.empty();
1575 m_decompressors.clear();
1587 #ifndef TILESON_MEMORYSTREAM_HPP
1588 #define TILESON_MEMORYSTREAM_HPP
1595 #ifndef TILESON_MEMORYBUFFER_HPP
1596 #define TILESON_MEMORYBUFFER_HPP
1603 MemoryBuffer(
const uint8_t *p,
size_t l) { setg((
char *) p, (
char *) p, (
char *) p + l); }
1614 MemoryStream(
const uint8_t *p,
size_t l) : std::istream(&m_buffer), m_buffer(p, l) { rdbuf(&m_buffer); }
1630 #ifndef TILESON_MAP_HPP
1631 #define TILESON_MAP_HPP
1638 #ifndef TILESON_COLOR_HPP
1639 #define TILESON_COLOR_HPP
1643 #include <type_traits>
1647 template<
typename T>
1655 inline explicit Color(
const std::string &color) { parseHexString(color); }
1657 inline Color(T red, T green, T blue, T alpha);
1665 inline bool operator==(
const Color &rhs)
const;
1666 inline bool operator==(
const std::string &rhs)
const;
1667 inline bool operator!=(
const Color &rhs)
const;
1682 void parseHexString(
const std::string &color)
1684 if constexpr (std::is_same<T, float>::value) {
1685 if (color.size() == 9) {
1686 a = (float) std::stoi(color.substr(1, 2),
nullptr, 16) / 255;
1687 r = (float) std::stoi(color.substr(3, 2),
nullptr, 16) / 255;
1688 g = (float) std::stoi(color.substr(5, 2),
nullptr, 16) / 255;
1689 b = (float) std::stoi(color.substr(7, 2),
nullptr, 16) / 255;
1690 }
else if (color.size() == 7) {
1691 r = (float) std::stoi(color.substr(1, 2),
nullptr, 16) / 255;
1692 g = (float) std::stoi(color.substr(3, 2),
nullptr, 16) / 255;
1693 b = (float) std::stoi(color.substr(5, 2),
nullptr, 16) / 255;
1696 }
else if constexpr (std::is_same<T, uint8_t>::value) {
1697 if (color.size() == 9) {
1698 a =
static_cast<uint8_t
>(std::stoi(color.substr(1, 2),
nullptr, 16));
1699 r =
static_cast<uint8_t
>(std::stoi(color.substr(3, 2),
nullptr, 16));
1700 g =
static_cast<uint8_t
>(std::stoi(color.substr(5, 2),
nullptr, 16));
1701 b =
static_cast<uint8_t
>(std::stoi(color.substr(7, 2),
nullptr, 16));
1702 }
else if (color.size() == 7) {
1703 r =
static_cast<uint8_t
>(std::stoi(color.substr(1, 2),
nullptr, 16));
1704 g =
static_cast<uint8_t
>(std::stoi(color.substr(3, 2),
nullptr, 16));
1705 b =
static_cast<uint8_t
>(std::stoi(color.substr(5, 2),
nullptr, 16));
1712 typedef Color<uint8_t> Colori;
1713 typedef Color<float> Colorf;
1721 template<
typename T>
1724 if constexpr (std::is_same<T, float>::value)
1727 return tson::Colorf((
float) r / 255, (
float) g / 255, (
float) b / 255, (
float) a / 255);
1736 template<
typename T>
1739 if constexpr (std::is_same<T, float>::value)
1741 static_cast<std::uint8_t
>((
float) r * 255),
static_cast<std::uint8_t
>((float) g * 255),
static_cast<std::uint8_t
>((float) b * 255),
1742 static_cast<std::uint8_t
>((float) a * 255));
1755 template<
typename T>
1764 template<
typename T>
1768 return *
this == other;
1771 template<
typename T>
1772 bool Color<T>::operator==(
const Color &rhs)
const
1774 return r == rhs.
r && g == rhs.g && b == rhs.b && a == rhs.a;
1777 template<
typename T>
1778 bool Color<T>::operator!=(
const Color &rhs)
const
1780 return !(rhs == *
this);
1794 #ifndef TILESON_VECTOR2_HPP
1795 #define TILESON_VECTOR2_HPP
1798 template<
typename T>
1803 inline Vector2() { x = y = 0; }
1805 inline bool operator==(
const Vector2 &rhs)
const;
1806 inline bool operator!=(
const Vector2 &rhs)
const;
1818 template<
typename T>
1825 template<
typename T>
1828 return x == rhs.x && y == rhs.y;
1831 template<
typename T>
1832 bool Vector2<T>::operator!=(
const Vector2 &rhs)
const
1834 return !(rhs == *
this);
1837 typedef Vector2<int> Vector2i;
1838 typedef Vector2<float> Vector2f;
1852 #ifndef TILESON_IJSON_HPP
1853 #define TILESON_IJSON_HPP
1858 virtual IJson &operator[](std::string_view key) = 0;
1859 virtual IJson &at(std::string_view key) = 0;
1860 virtual IJson &at(
size_t pos) = 0;
1866 virtual std::vector<std::unique_ptr<IJson>>
array() = 0;
1868 virtual std::vector<std::unique_ptr<IJson>> &
array(std::string_view key) = 0;
1877 virtual bool parse(
const fs::path &path) = 0;
1879 virtual bool parse(
const void *data,
size_t size) = 0;
1881 template<
typename T>
1883 T get(std::string_view key);
1884 template<
typename T>
1888 virtual size_t count(std::string_view key)
const = 0;
1890 virtual bool any(std::string_view key)
const = 0;
1892 virtual bool isArray()
const = 0;
1894 virtual bool isObject()
const = 0;
1896 virtual bool isNull()
const = 0;
1914 virtual int32_t getInt32(std::string_view key) = 0;
1916 virtual uint32_t getUInt32(std::string_view key) = 0;
1918 virtual int64_t getInt64(std::string_view key) = 0;
1920 virtual uint64_t getUInt64(std::string_view key) = 0;
1922 virtual double getDouble(std::string_view key) = 0;
1924 virtual float getFloat(std::string_view key) = 0;
1926 virtual std::string getString(std::string_view key) = 0;
1928 virtual bool getBool(std::string_view key) = 0;
1931 virtual int32_t getInt32() = 0;
1933 virtual uint32_t getUInt32() = 0;
1935 virtual int64_t getInt64() = 0;
1937 virtual uint64_t getUInt64() = 0;
1939 virtual double getDouble() = 0;
1941 virtual float getFloat() = 0;
1943 virtual std::string getString() = 0;
1945 virtual bool getBool() = 0;
1948 template<
typename T>
1949 T IJson::get(std::string_view key)
1951 if constexpr (std::is_same<T, double>::value)
return getDouble(key);
1952 if constexpr (std::is_same<T, float>::value)
1953 return getFloat(key);
1954 else if constexpr (std::is_same<T, int32_t>::value)
1955 return getInt32(key);
1956 else if constexpr (std::is_same<T, uint32_t>::value)
1957 return getUInt32(key);
1958 else if constexpr (std::is_same<T, int64_t>::value)
1959 return getInt64(key);
1960 else if constexpr (std::is_same<T, uint64_t>::value)
1961 return getUInt64(key);
1962 else if constexpr (std::is_same<T, std::string>::value)
1963 return getString(key);
1964 else if constexpr (std::is_same<T, bool>::value)
1965 return getBool(key);
1970 template<
typename T>
1973 if constexpr (std::is_same<T, double>::value)
return getDouble();
1974 if constexpr (std::is_same<T, float>::value)
1976 else if constexpr (std::is_same<T, int32_t>::value)
1978 else if constexpr (std::is_same<T, uint32_t>::value)
1980 else if constexpr (std::is_same<T, int64_t>::value)
1982 else if constexpr (std::is_same<T, uint64_t>::value)
1984 else if constexpr (std::is_same<T, std::string>::value)
1986 else if constexpr (std::is_same<T, bool>::value)
2003 #ifdef INCLUDE_NLOHMANN_JSON_HPP_
2005 #ifndef TILESON_NLOHMANNJSON_HPP
2006 #define TILESON_NLOHMANNJSON_HPP
2011 inline NlohmannJson() =
default;
2013 IJson &operator[](std::string_view key)
override
2015 if (m_arrayCache.count(key.data()) == 0) m_arrayCache[key.data()] = std::make_unique<NlohmannJson>(&m_json->operator[](key.data()));
2017 return *m_arrayCache[key.data()].get();
2020 inline explicit NlohmannJson(nlohmann::json *json) : m_json {json} {}
2022 inline IJson &at(std::string_view key)
override
2024 if (m_arrayCache.count(key.data()) == 0) m_arrayCache[key.data()] = std::make_unique<NlohmannJson>(&m_json->operator[](key.data()));
2026 return *m_arrayCache[key.data()].get();
2029 inline IJson &at(
size_t pos)
override
2031 if (m_arrayPosCache.count(pos) == 0) m_arrayPosCache[pos] = std::make_unique<NlohmannJson>(&m_json->at(pos));
2033 return *m_arrayPosCache[pos];
2036 std::vector<std::unique_ptr<IJson>> array()
override
2038 std::vector<std::unique_ptr<IJson>> vec;
2039 for (
auto &item : *m_json) {
2040 nlohmann::json *ptr = &item;
2041 vec.emplace_back(std::make_unique<NlohmannJson>(ptr));
2047 inline std::vector<std::unique_ptr<IJson>> &array(std::string_view key)
override
2049 if (m_arrayListDataCache.count(key.data()) == 0) {
2050 if (m_json->count(key.data()) > 0 && m_json->operator[](key.data()).is_array()) {
2051 std::for_each(m_json->operator[](key.data()).begin(), m_json->operator[](key.data()).end(), [&](nlohmann::json &item) {
2052 nlohmann::json *ptr = &item;
2053 m_arrayListDataCache[key.data()].emplace_back(std::make_unique<NlohmannJson>(ptr));
2058 return m_arrayListDataCache[key.data()];
2062 inline size_t size()
const override
2064 return m_json->size();
2067 inline bool parse(
const fs::path &path)
override
2072 if (fs::exists(path) && fs::is_regular_file(path)) {
2073 m_path = path.parent_path();
2074 m_data = std::make_unique<nlohmann::json>();
2075 std::ifstream i(path.generic_string());
2078 m_json = m_data.get();
2079 }
catch (
const nlohmann::json::parse_error &error) {
2080 std::string message =
"Parse error: ";
2081 message += std::string(error.what());
2082 message += std::string(
"\n");
2083 std::cerr << message;
2091 inline bool parse(
const void *data,
size_t size)
override
2095 m_data = std::make_unique<nlohmann::json>();
2099 m_json = m_data.get();
2100 }
catch (
const nlohmann::json::parse_error &error) {
2101 std::string message =
"Parse error: ";
2102 message += std::string(error.what());
2103 message += std::string(
"\n");
2104 std::cerr << message;
2111 inline size_t count(std::string_view key)
const override
2113 return m_json->count(key);
2117 inline bool any(std::string_view key)
const override
2119 return count(key) > 0;
2123 inline bool isArray()
const override
2125 return m_json->is_array();
2129 inline bool isObject()
const override
2131 return m_json->is_object();
2135 inline bool isNull()
const override
2137 return m_json->is_null();
2140 fs::path directory()
const override {
return m_path; }
2142 void directory(
const fs::path &directory)
override { m_path = directory; }
2146 inline int32_t getInt32(std::string_view key)
override
2148 return m_json->operator[](key.data()).get<int32_t>();
2152 inline uint32_t getUInt32(std::string_view key)
override
2154 return m_json->operator[](key.data()).get<uint32_t>();
2158 inline int64_t getInt64(std::string_view key)
override
2160 return m_json->operator[](key.data()).get<int64_t>();
2164 inline uint64_t getUInt64(std::string_view key)
override
2166 return m_json->operator[](key.data()).get<uint64_t>();
2170 inline double getDouble(std::string_view key)
override
2172 return m_json->operator[](key.data()).get<double>();
2176 inline std::string getString(std::string_view key)
override
2178 return m_json->operator[](key.data()).get<std::string>();
2182 inline bool getBool(std::string_view key)
override
2184 return m_json->operator[](key.data()).get<bool>();
2188 float getFloat(std::string_view key)
override
2190 return m_json->operator[](key.data()).get<float>();
2194 inline int32_t getInt32()
override
2196 return m_json->get<int32_t>();
2200 inline uint32_t getUInt32()
override
2202 return m_json->get<uint32_t>();
2206 inline int64_t getInt64()
override
2208 return m_json->get<int64_t>();
2212 inline uint64_t getUInt64()
override
2214 return m_json->get<uint64_t>();
2218 inline double getDouble()
override
2220 return m_json->get<
double>();
2224 inline std::string getString()
override
2226 return m_json->get<std::string>();
2230 inline bool getBool()
override
2232 return m_json->get<
bool>();
2236 float getFloat()
override
2238 return m_json->get<
float>();
2242 inline void clearCache()
2244 m_arrayCache.clear();
2245 m_arrayPosCache.clear();
2246 m_arrayListDataCache.clear();
2249 nlohmann::json *m_json =
nullptr;
2250 std::unique_ptr<nlohmann::json> m_data =
nullptr;
2254 std::map<std::string, std::unique_ptr<IJson>> m_arrayCache;
2255 std::map<size_t, std::unique_ptr<IJson>> m_arrayPosCache;
2256 std::map<std::string, std::vector<std::unique_ptr<IJson>>> m_arrayListDataCache;
2270 #ifndef TILESON_PICOJSON_HPP
2271 #define TILESON_PICOJSON_HPP
2276 inline PicoJson() =
default;
2278 IJson &operator[](std::string_view key)
override
2280 if (m_arrayCache.count(key.data()) == 0) {
2281 if (m_json->is<picojson::object>()) {
2282 picojson::object &o = m_json->get<picojson::object>();
2283 m_arrayCache[key.data()] = std::make_unique<PicoJson>(&o[key.data()]);
2287 return *m_arrayCache[key.data()].get();
2290 inline explicit PicoJson(picojson::value *json) : m_json {json} {}
2292 inline IJson &at(std::string_view key)
override
2294 if (m_arrayCache.count(key.data()) == 0) {
2295 if (m_json->is<picojson::object>()) {
2296 picojson::object &o = m_json->get<picojson::object>();
2297 m_arrayCache[key.data()] = std::make_unique<PicoJson>(&o[key.data()]);
2300 return *m_arrayCache[key.data()].get();
2303 inline IJson &at(
size_t pos)
override
2305 if (m_arrayPosCache.count(pos) == 0) {
2306 picojson::array &a = m_json->get<picojson::array>();
2307 m_arrayPosCache[pos] = std::make_unique<PicoJson>(&a.at(pos));
2310 return *m_arrayPosCache[pos];
2313 std::vector<std::unique_ptr<IJson>> array()
override
2315 std::vector<std::unique_ptr<IJson>> vec;
2316 if (m_json->is<picojson::array>()) {
2317 picojson::array &a = m_json->get<picojson::array>();
2318 for (
auto &item : a) {
2319 picojson::value *ptr = &item;
2320 vec.emplace_back(std::make_unique<PicoJson>(ptr));
2327 inline std::vector<std::unique_ptr<IJson>> &array(std::string_view key)
override
2329 if (m_arrayListDataCache.count(key.data()) == 0) {
2330 if (count(key.data()) > 0) {
2332 picojson::object &obj = m_json->get<picojson::object>();
2333 picojson::value &v = obj.at(key.data());
2334 bool isArray = v.is<picojson::array>();
2336 picojson::array &a = v.get<picojson::array>();
2338 std::for_each(a.begin(), a.end(), [&](picojson::value &item) {
2339 picojson::value *ptr = &item;
2340 m_arrayListDataCache[key.data()].emplace_back(std::make_unique<PicoJson>(ptr));
2347 return m_arrayListDataCache[key.data()];
2351 inline size_t size()
const override
2353 if (m_json->is<picojson::object>()) {
2354 picojson::object obj = m_json->get<picojson::object>();
2360 inline bool parse(
const fs::path &path)
override
2365 if (fs::exists(path) && fs::is_regular_file(path)) {
2366 m_path = path.parent_path();
2367 m_data = std::make_unique<picojson::value>();
2368 std::ifstream i(path.generic_string());
2370 std::string error = picojson::parse(*m_data, i);
2371 if (!error.empty()) {
2372 std::cerr <<
"PicoJson parse error: " << error <<
"\n";
2376 m_json = m_data.get();
2377 }
catch (
const std::exception &error) {
2378 std::string message =
"Parse error: ";
2379 message += std::string(error.what());
2380 message += std::string(
"\n");
2381 std::cerr << message;
2389 inline bool parse(
const void *data,
size_t size)
override
2393 m_data = std::make_unique<picojson::value>();
2396 std::string error = picojson::parse(*m_data, mem);
2397 if (!error.empty()) {
2398 std::cerr <<
"PicoJson parse error: " << error <<
"\n";
2402 m_json = m_data.get();
2403 }
catch (
const std::exception &error) {
2404 std::string message =
"Parse error: ";
2405 message += std::string(error.what());
2406 message += std::string(
"\n");
2407 std::cerr << message;
2414 inline size_t count(std::string_view key)
const override
2417 picojson::object obj = m_json->get<picojson::object>();
2418 return obj.count(key.data());
2421 return m_json->contains(key.data()) ? 1 : 0;
2425 inline bool any(std::string_view key)
const override
2427 return count(key) > 0;
2431 inline bool isArray()
const override
2433 return m_json->is<picojson::array>();
2437 inline bool isObject()
const override
2439 return m_json->is<picojson::object>();
2443 inline bool isNull()
const override
2445 return m_json->is<picojson::null>();
2448 fs::path directory()
const override {
return m_path; }
2450 void directory(
const fs::path &directory)
override { m_path = directory; }
2454 inline int32_t getInt32(std::string_view key)
override
2456 picojson::object obj = m_json->get<picojson::object>();
2457 return static_cast<int32_t
>(getDouble(key));
2461 inline uint32_t getUInt32(std::string_view key)
override
2463 picojson::object obj = m_json->get<picojson::object>();
2464 return static_cast<uint32_t
>(getDouble(key));
2468 inline int64_t getInt64(std::string_view key)
override
2470 picojson::object obj = m_json->get<picojson::object>();
2471 return static_cast<int64_t
>(getDouble(key));
2475 inline uint64_t getUInt64(std::string_view key)
override
2477 picojson::object obj = m_json->get<picojson::object>();
2478 return static_cast<uint64_t
>(getDouble(key));
2482 inline double getDouble(std::string_view key)
override
2484 picojson::object obj = m_json->get<picojson::object>();
2485 return obj[key.data()].get<
double>();
2489 inline std::string getString(std::string_view key)
override
2491 picojson::object obj = m_json->get<picojson::object>();
2492 return obj[key.data()].get<std::string>();
2496 inline bool getBool(std::string_view key)
override
2498 picojson::object obj = m_json->get<picojson::object>();
2499 return obj[key.data()].get<
bool>();
2503 float getFloat(std::string_view key)
override
2505 picojson::object obj = m_json->get<picojson::object>();
2506 return static_cast<float>(getDouble(key));
2510 inline int32_t getInt32()
override
2512 return static_cast<int32_t
>(getDouble());
2516 inline uint32_t getUInt32()
override
2518 return static_cast<uint32_t
>(getDouble());
2522 inline int64_t getInt64()
override
2524 return static_cast<int64_t
>(getDouble());
2528 inline uint64_t getUInt64()
override
2530 return static_cast<uint64_t
>(getDouble());
2534 inline double getDouble()
override
2536 return m_json->get<
double>();
2540 inline std::string getString()
override
2542 return m_json->get<std::string>();
2546 inline bool getBool()
override
2548 return m_json->get<
bool>();
2552 float getFloat()
override
2554 return static_cast<float>(getDouble());
2558 inline void clearCache()
2560 m_arrayCache.clear();
2561 m_arrayPosCache.clear();
2562 m_arrayListDataCache.clear();
2565 picojson::value *m_json =
nullptr;
2566 std::unique_ptr<picojson::value> m_data =
nullptr;
2570 std::map<std::string, std::unique_ptr<IJson>> m_arrayCache;
2571 std::map<size_t, std::unique_ptr<IJson>> m_arrayPosCache;
2572 std::map<std::string, std::vector<std::unique_ptr<IJson>>> m_arrayListDataCache;
2587 #ifndef TILESON_JSON11_HPP
2588 #define TILESON_JSON11_HPP
2593 inline Json11() =
default;
2595 IJson &operator[](std::string_view key)
override
2597 if (m_arrayCache.count(key.data()) == 0) {
2598 if (m_json->is_object()) {
2599 m_arrayCache[key.data()] = std::make_unique<Json11>(m_json->operator[](key.data()));
2603 return *m_arrayCache[key.data()].get();
2608 inline IJson &at(std::string_view key)
override
2610 if (m_arrayCache.count(key.data()) == 0) {
2611 if (m_json->is_object()) {
2612 m_arrayCache[key.data()] = std::make_unique<Json11>(m_json->operator[](key.data()));
2615 return *m_arrayCache[key.data()].get();
2618 inline IJson &at(
size_t pos)
override
2620 if (m_arrayPosCache.count(pos) == 0) {
2621 const std::vector<json11::Json> &a = m_json->array_items();
2622 m_arrayPosCache[pos] = std::make_unique<Json11>(a.at(pos));
2625 return *m_arrayPosCache[pos];
2628 std::vector<std::unique_ptr<IJson>>
array()
override
2630 std::vector<std::unique_ptr<IJson>> vec;
2631 if (m_json->is_array()) {
2632 for (
const json11::Json &item : m_json->array_items()) {
2633 vec.emplace_back(std::make_unique<Json11>(item));
2640 inline std::vector<std::unique_ptr<IJson>> &
array(std::string_view key)
override
2642 if (m_arrayListDataCache.count(key.data()) == 0) {
2643 if (count(key.data()) > 0) {
2645 const json11::Json &v = m_json->operator[](key.data());
2648 m_arrayListDataCache[key.data()].emplace_back(std::make_unique<Json11>(item));
2655 return m_arrayListDataCache[key.data()];
2659 inline size_t size()
const override
2661 if (m_json->is_object())
2662 return m_json->object_items().size();
2663 else if (m_json->is_array())
2664 return m_json->array_items().size();
2669 inline bool parse(
const fs::path &path)
override
2674 if (fs::exists(path) && fs::is_regular_file(path)) {
2675 std::ifstream file(path.generic_string());
2677 m_path = path.parent_path();
2679 file.seekg(0, std::ios::end);
2680 str.reserve(
static_cast<size_t>(file.tellg()));
2681 file.seekg(0, std::ios::beg);
2683 str.assign((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
2685 m_data = std::make_unique<json11::Json>();
2688 std::string strError;
2689 *m_data = json11::Json::parse(str, strError);
2690 if (!strError.empty()) {
2691 std::cerr << strError <<
"\n";
2694 m_json = m_data.get();
2695 }
catch (
const std::exception &error) {
2696 std::string message =
"Json11 parse error: ";
2697 message += std::string(error.what());
2698 message += std::string(
"\n");
2699 std::cerr << message;
2707 inline bool parse(
const void *data,
size_t size)
override
2717 str.assign((std::istreambuf_iterator<char>(mem)), std::istreambuf_iterator<char>());
2719 m_data = std::make_unique<json11::Json>();
2722 std::string strError;
2724 *m_data = json11::Json::parse(str, strError);
2725 if (!strError.empty()) {
2726 std::cout << strError <<
"\n";
2729 m_json = m_data.get();
2730 }
catch (
const std::exception &error) {
2731 std::string message =
"Json11 parse error: ";
2732 message += std::string(error.what());
2733 message += std::string(
"\n");
2734 std::cerr << message;
2741 inline size_t count(std::string_view key)
const override
2746 return m_json->object_items().count(key.data());
2753 inline bool any(std::string_view key)
const override
2755 return count(key) > 0;
2759 inline bool isArray()
const override
2761 return m_json->is_array();
2765 inline bool isObject()
const override
2767 return m_json->is_object();
2771 inline bool isNull()
const override
2773 return m_json->is_null();
2782 inline int32_t getInt32(std::string_view key)
override
2784 return static_cast<int32_t
>(getDouble(key));
2788 inline uint32_t getUInt32(std::string_view key)
override
2790 return static_cast<uint32_t
>(getDouble(key));
2794 inline int64_t getInt64(std::string_view key)
override
2796 return static_cast<int64_t
>(getDouble(key));
2800 inline uint64_t getUInt64(std::string_view key)
override
2802 return static_cast<uint64_t
>(getDouble(key));
2806 inline double getDouble(std::string_view key)
override
2808 return m_json->operator[](key.data()).number_value();
2812 inline std::string getString(std::string_view key)
override
2814 return m_json->operator[](key.data()).string_value();
2818 inline bool getBool(std::string_view key)
override
2820 return m_json->operator[](key.data()).bool_value();
2824 float getFloat(std::string_view key)
override
2826 return static_cast<float>(getDouble(key));
2830 inline int32_t getInt32()
override
2832 return static_cast<int32_t
>(getDouble());
2836 inline uint32_t getUInt32()
override
2838 return static_cast<uint32_t
>(getDouble());
2842 inline int64_t getInt64()
override
2844 return static_cast<int64_t
>(getDouble());
2848 inline uint64_t getUInt64()
override
2850 return static_cast<uint64_t
>(getDouble());
2854 inline double getDouble()
override
2856 return m_json->number_value();
2860 inline std::string getString()
override
2862 return m_json->string_value();
2866 inline bool getBool()
override
2868 return m_json->bool_value();
2872 float getFloat()
override
2874 return static_cast<float>(getDouble());
2878 inline void clearCache()
2880 m_arrayCache.clear();
2881 m_arrayPosCache.clear();
2882 m_arrayListDataCache.clear();
2886 std::unique_ptr<json11::Json> m_data =
nullptr;
2892 std::map<std::string, std::unique_ptr<IJson>> m_arrayCache;
2893 std::map<size_t, std::unique_ptr<IJson>> m_arrayPosCache;
2894 std::map<std::string, std::vector<std::unique_ptr<IJson>>> m_arrayListDataCache;
2907 #ifndef TILESON_LAYER_HPP
2908 #define TILESON_LAYER_HPP
2918 #ifndef TILESON_CHUNK_HPP
2919 #define TILESON_CHUNK_HPP
2926 inline Chunk() =
default;
2931 inline const std::vector<int> &
getData()
const;
2940 std::vector<int> m_data;
2965 bool allFound =
true;
2967 if (json.count(
"width") > 0 && json.count(
"height") > 0)
2968 m_size = {json[
"width"].get<
int>(), json[
"height"].get<int>()};
2971 if (json.count(
"x") > 0 && json.count(
"y") > 0)
2972 m_position = {json[
"x"].get<
int>(), json[
"y"].get<int>()};
2977 if (json.count(
"data") > 0) {
2978 if (json[
"data"].isArray()) {
2979 auto &data = json.
array(
"data");
2980 std::for_each(data.begin(), data.end(), [&](std::unique_ptr<IJson> &item) { m_data.push_back(item->get<int>()); });
2982 m_base64Data = json[
"data"].get<std::string>();
3003 return m_base64Data;
3031 #ifndef TILESON_OBJECT_HPP
3032 #define TILESON_OBJECT_HPP
3041 #ifndef TILESON_PROPERTYCOLLECTION_HPP
3042 #define TILESON_PROPERTYCOLLECTION_HPP
3049 #ifndef TILESON_PROPERTY_HPP
3050 #define TILESON_PROPERTY_HPP
3064 #ifndef TILESON_ENUMS_HPP
3065 #define TILESON_ENUMS_HPP
3073 #ifndef TILESON_ENUMBITFLAGS_HPP
3074 #define TILESON_ENUMBITFLAGS_HPP
3077 #include <type_traits>
3079 #define TILESON_ENABLE_BITMASK_OPERATORS(x) \
3081 ENABLE_BITMASK_OPERATORS(x) \
3085 #define ENABLE_BITMASK_OPERATORS(x) \
3087 struct EnableBitMaskOperators<x> { \
3088 static const bool enable = true; \
3091 template<
typename Enum>
3093 static const bool enable =
false;
3096 template<
typename Enum>
3097 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type operator|(Enum lhs, Enum rhs)
3099 static_assert(std::is_enum<Enum>::value,
"template parameter is not an enum type");
3101 using underlying =
typename std::underlying_type<Enum>::type;
3103 return static_cast<Enum
>(
static_cast<underlying
>(lhs) |
static_cast<underlying
>(rhs));
3107 template<
typename Enum>
3108 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type operator&(Enum lhs, Enum rhs)
3110 static_assert(std::is_enum<Enum>::value,
"template parameter is not an enum type");
3112 using underlying =
typename std::underlying_type<Enum>::type;
3114 return static_cast<Enum
>(
static_cast<underlying
>(lhs) &
static_cast<underlying
>(rhs));
3118 template<
typename Enum>
3119 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type operator^(Enum lhs, Enum rhs)
3121 static_assert(std::is_enum<Enum>::value,
"template parameter is not an enum type");
3123 using underlying =
typename std::underlying_type<Enum>::type;
3125 return static_cast<Enum
>(
static_cast<underlying
>(lhs) ^
static_cast<underlying
>(rhs));
3129 template<
typename Enum>
3130 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type operator~(Enum rhs)
3132 static_assert(std::is_enum<Enum>::value,
"template parameter is not an enum type");
3134 using underlying =
typename std::underlying_type<Enum>::type;
3136 return static_cast<Enum
>(~static_cast<underlying>(rhs));
3140 template<
typename Enum>
3141 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type &operator|=(Enum &lhs, Enum rhs)
3143 static_assert(std::is_enum<Enum>::value,
"template parameter is not an enum type");
3145 using underlying =
typename std::underlying_type<Enum>::type;
3147 lhs =
static_cast<Enum
>(
static_cast<underlying
>(lhs) |
static_cast<underlying
>(rhs));
3153 template<
typename Enum>
3154 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type &operator&=(Enum &lhs, Enum rhs)
3156 static_assert(std::is_enum<Enum>::value,
"template parameter is not an enum type");
3158 using underlying =
typename std::underlying_type<Enum>::type;
3160 lhs =
static_cast<Enum
>(
static_cast<underlying
>(lhs) &
static_cast<underlying
>(rhs));
3166 template<
typename Enum>
3167 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type &operator^=(Enum &lhs, Enum rhs)
3169 static_assert(std::is_enum<Enum>::value,
"template parameter is not an enum type");
3171 using underlying =
typename std::underlying_type<Enum>::type;
3173 lhs =
static_cast<Enum
>(
static_cast<underlying
>(lhs) ^
static_cast<underlying
>(rhs));
3187 enum class Type : uint8_t {
3204 enum class LayerType : uint8_t {
3215 enum class ParseStatus : uint8_t {
3220 DecompressionError = 4
3226 enum class ObjectType : uint8_t {
3238 static constexpr uint32_t FLIPPED_HORIZONTALLY_FLAG = 0x80000000;
3239 static constexpr uint32_t FLIPPED_VERTICALLY_FLAG = 0x40000000;
3240 static constexpr uint32_t FLIPPED_DIAGONALLY_FLAG = 0x20000000;
3244 enum class TileFlipFlags : uint32_t {
3246 Diagonally = FLIPPED_DIAGONALLY_FLAG,
3247 Vertically = FLIPPED_VERTICALLY_FLAG,
3248 Horizontally = FLIPPED_HORIZONTALLY_FLAG
3254 enum class ObjectAlignment : uint8_t {
3270 enum class TextAlignment : uint8_t {
3283 enum class TileRenderSize : uint8_t {
3292 enum class FillMode : uint8_t {
3295 PreserveAspectFit = 2
3298 enum class EnumStorageType : uint8_t {
3304 ENABLE_BITMASK_OPERATORS(TileFlipFlags)
3331 inline Property(std::string name, std::any value, Type type);
3333 inline void setValue(
const std::any &value);
3334 inline void setStrValue(
const std::string &value);
3335 inline void setName(
const std::string &name);
3341 inline const std::any &getValue()
const;
3342 template<
typename T>
3343 inline T getValue()
const;
3345 inline const std::string &getName()
const;
3347 inline Type getType()
const;
3349 inline const std::string &getPropertyType()
const;
3352 inline void setValueByType(
IJson &json);
3355 inline void setTypeByString(
const std::string &str);
3358 Type m_type = Type::Undefined;
3359 std::string m_name {};
3360 std::string m_propertyType {};
3364 template<
typename T>
3365 T Property::getValue()
const
3367 bool isCorrectType = (m_value.type() ==
typeid(T));
3369 if (isCorrectType) {
3370 T value = std::any_cast<T>(m_value);
3373 static T defaultValue;
3374 return defaultValue;
3379tson::Property::Property() : m_name {
"unnamed"} {}
3381tson::Property::Property(IJson &json,
tson::Project *project) : m_project {project}
3383 m_name = json[
"name"].get<std::string>();
3384 if (json.count(
"propertytype") > 0)
3385 m_propertyType = json[
"propertytype"].get<std::string>();
3386 else if (json.count(
"propertyType") > 0)
3387 m_propertyType = json[
"propertyType"].get<std::string>();
3389 setTypeByString(json[
"type"].get<std::string>());
3390 setValueByType(json[
"value"]);
3393tson::Property::Property(std::string name, std::any value, Type type) : m_type {type}, m_name {move(name)}, m_value {move(value)} {}
3395void tson::Property::setValue(
const std::any &value)
3411const std::any &tson::Property::getValue()
const
3416void tson::Property::setName(
const std::string &name)
3421const std::string &tson::Property::getName()
const
3435 return m_value.type();
3448 return m_value.type().name();
3451tson::Type tson::Property::getType()
const
3456void tson::Property::setTypeByString(
const std::string &str)
3459 m_type = tson::Type::Color;
3460 else if (str ==
"file")
3461 m_type = tson::Type::File;
3462 else if (str ==
"int")
3463 m_type = tson::Type::Int;
3464 else if (str ==
"bool")
3465 m_type = tson::Type::Boolean;
3466 else if (str ==
"float")
3467 m_type = tson::Type::Float;
3468 else if (str ==
"string")
3469 m_type = tson::Type::String;
3470 else if (str ==
"class")
3471 m_type = tson::Type::Class;
3472 else if (str ==
"object")
3473 m_type = tson::Type::Object;
3475 m_type = tson::Type::Undefined;
3478const std::string &tson::Property::getPropertyType()
const
3480 return m_propertyType;
3499 inline tson::Property *add(
const std::string &name,
const std::any &value, tson::Type type);
3501 inline void remove(
const std::string &name);
3503 inline void setValue(
const std::string &name,
const std::any &value);
3505 inline void setId(
const std::string &
id);
3507 inline bool hasProperty(
const std::string &name);
3509 inline std::map<std::string, Property> &getProperties();
3510 inline std::vector<Property *>
get();
3511 template<
typename T>
3512 inline T getValue(
const std::string &name);
3514 inline const std::string &getId()
const;
3516 inline size_t getSize()
const;
3520 std::map<std::string, tson::Property> m_properties;
3525T tson::PropertyCollection::getValue(
const std::string &name)
3528 return (m_properties.count(name) > 0) ? m_properties[name].getValue<T>() : defaultT;
3531tson::PropertyCollection::PropertyCollection(std::string
id) : m_id {std::move(id)} {}
3535 m_properties[
property.getName()] = property;
3536 return &m_properties[
property.getName()];
3542 std::string name =
property.getName();
3543 m_properties[name] = std::move(property);
3544 return &m_properties[name];
3547tson::Property *tson::PropertyCollection::add(
const std::string &name,
const std::any &value, tson::Type type)
3549 m_properties[name] = {name, value, type};
3550 return &m_properties[name];
3553void tson::PropertyCollection::remove(
const std::string &name)
3555 m_properties.erase(name);
3566 if (m_properties.count(name) > 0) m_properties[name].setValue(value);
3576 m_properties[name] = value;
3579void tson::PropertyCollection::setId(
const std::string &
id)
3584bool tson::PropertyCollection::hasProperty(
const std::string &name)
3586 return m_properties.count(name) > 0;
3589tson::Property *tson::PropertyCollection::getProperty(
const std::string &name)
3591 return (m_properties.count(name) > 0) ? &m_properties[name] :
nullptr;
3594std::map<std::string, tson::Property> &tson::PropertyCollection::getProperties()
3596 return m_properties;
3605 std::vector<tson::Property *> props;
3606 for (
auto &i : m_properties)
3607 props.emplace_back(&i.second);
3612const std::string &tson::PropertyCollection::getId()
const
3617size_t tson::PropertyCollection::getSize()
const
3619 return m_properties.size();
3631 #ifndef TILESON_TEXT_HPP
3632 #define TILESON_TEXT_HPP
3639 inline Text() =
default;
3649 bool hasColor = json.count(
"color") > 0;
3652 text = (json.count(
"text") > 0) ? json[
"text"].get<std::string>() :
"";
3653 wrap = (json.count(
"wrap") > 0) ? json[
"wrap"].get<bool>() :
false;
3656 bold = (json.count(
"bold") > 0) ? json[
"bold"].get<bool>() :
false;
3657 fontFamily = (json.count(
"fontfamily") > 0) ? json[
"fontfamily"].get<std::string>() :
"sans-serif";
3658 horizontalAlignment = (json.count(
"halign") > 0) ? resolveTextAlignmentByString(json[
"halign"].get<std::string>()) : TextAlignment::Left;
3659 italic = (json.count(
"italic") > 0) ? json[
"italic"].get<bool>() :
false;
3660 kerning = (json.count(
"kerning") > 0) ? json[
"kerning"].get<bool>() :
true;
3661 pixelSize = (json.count(
"pixelsize") > 0) ? json[
"pixelsize"].get<int32_t>() : 16;
3662 strikeout = (json.count(
"strikeout") > 0) ? json[
"strikeout"].get<bool>() :
false;
3663 underline = (json.count(
"underline") > 0) ? json[
"underline"].get<bool>() :
false;
3664 verticalAlignment = (json.count(
"valign") > 0) ? resolveTextAlignmentByString(json[
"valign"].get<std::string>()) : TextAlignment::Top;
3668 std::string text {};
3674 std::string fontFamily {
"sans-serif"};
3675 TextAlignment horizontalAlignment {TextAlignment::Left};
3676 bool italic {
false};
3677 bool kerning {
true};
3679 bool strikeout {
false};
3680 bool underline {
false};
3681 TextAlignment verticalAlignment {TextAlignment::Top};
3685 TextAlignment resolveTextAlignmentByString(
const std::string &str)
const
3687 if (str ==
"left")
return TextAlignment::Left;
3688 if (str ==
"center")
return TextAlignment::Center;
3689 if (str ==
"right")
return TextAlignment::Right;
3690 if (str ==
"justify")
return TextAlignment::Justify;
3691 if (str ==
"top")
return TextAlignment::Top;
3692 if (str ==
"bottom")
return TextAlignment::Bottom;
3694 return TextAlignment::Unresolved;
3724 inline Object() =
default;
3733 inline uint32_t
getGid()
const;
3737 inline int getId()
const;
3739 inline const std::string &
getName()
const;
3747 inline const std::string &
getType()
const;
3758 inline const std::vector<tson::Vector2i> &
getPolygons()
const;
3760 inline const std::vector<tson::Vector2i> &
getPolylines()
const;
3766 template<
typename T>
3767 inline T
get(
const std::string &name);
3778 ObjectType m_objectType = ObjectType::Undefined;
3799 std::shared_ptr<tson::TiledClass> m_class {};
3808 template<
typename T>
3811 return m_properties.getValue<T>(name);
3833 bool allFound =
true;
3835 if (json.count(
"ellipse") > 0) m_ellipse = json[
"ellipse"].get<
bool>();
3836 if (json.count(
"gid") > 0) {
3837 uint32_t gid = json[
"gid"].get<uint32_t>();
3838 if (gid & FLIPPED_HORIZONTALLY_FLAG) m_flipFlags |= TileFlipFlags::Horizontally;
3839 if (gid & FLIPPED_VERTICALLY_FLAG) m_flipFlags |= TileFlipFlags::Vertically;
3840 if (gid & FLIPPED_DIAGONALLY_FLAG) m_flipFlags |= TileFlipFlags::Diagonally;
3843 gid &= ~(FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG);
3847 if (json.count(
"id") > 0)
3848 m_id = json[
"id"].get<int>();
3851 if (json.count(
"name") > 0)
3852 m_name = json[
"name"].get<std::string>();
3855 if (json.count(
"point") > 0) m_point = json[
"point"].get<bool>();
3856 if (json.count(
"rotation") > 0)
3857 m_rotation = json[
"rotation"].get<float>();
3860 if (json.count(
"template") > 0) m_template = json[
"template"].get<std::string>();
3862 if (json.count(
"type") > 0)
3863 m_type = json[
"type"].get<std::string>();
3864 else if (json.count(
"class") > 0)
3865 m_type = json[
"class"].get<std::string>();
3869 if (json.count(
"visible") > 0)
3870 m_visible = json[
"visible"].get<bool>();
3874 if (json.count(
"width") > 0 && json.count(
"height") > 0)
3875 m_size = {json[
"width"].get<
int>(), json[
"height"].get<int>()};
3878 if (json.count(
"x") > 0 && json.count(
"y") > 0)
3879 m_position = {json[
"x"].get<
int>(), json[
"y"].get<int>()};
3883 if (json.count(
"text") > 0) {
3892 setObjectTypeByJson(json);
3894 if (m_objectType == ObjectType::Template) allFound =
true;
3897 if (json.count(
"polygon") > 0 && json[
"polygon"].isArray()) {
3898 auto &polygon = json.
array(
"polygon");
3899 std::for_each(polygon.begin(), polygon.end(), [&](std::unique_ptr<IJson> &item) {
3901 m_polygon.emplace_back(j[
"x"].get<int>(), j[
"y"].get<int>());
3905 if (json.count(
"polyline") > 0 && json[
"polyline"].isArray()) {
3906 auto &polyline = json.
array(
"polyline");
3907 std::for_each(polyline.begin(), polyline.end(), [&](std::unique_ptr<IJson> &item) {
3909 m_polyline.emplace_back(j[
"x"].get<int>(), j[
"y"].get<int>());
3913 if (json.count(
"properties") > 0 && json[
"properties"].isArray()) {
3914 auto &properties = json.
array(
"properties");
3915 std::for_each(properties.begin(), properties.end(), [&](std::unique_ptr<IJson> &item) { m_properties.add(*item); });
3927 m_objectType = ObjectType::Undefined;
3929 m_objectType = ObjectType::Ellipse;
3931 m_objectType = ObjectType::Point;
3932 else if (json.count(
"polygon") > 0)
3933 m_objectType = ObjectType::Polygon;
3934 else if (json.count(
"polyline") > 0)
3935 m_objectType = ObjectType::Polyline;
3936 else if (json.count(
"text") > 0)
3937 m_objectType = ObjectType::Text;
3938 else if (json.count(
"gid") > 0)
3939 m_objectType = ObjectType::Object;
3940 else if (json.count(
"template") > 0)
3941 m_objectType = ObjectType::Template;
3943 m_objectType = ObjectType::Rectangle;
3953 return m_objectType;
4092 return m_properties;
4111 if (m_properties.hasProperty(name))
return m_properties.getProperty(name);
4134 return ((m_flipFlags & flags) == flags) ? true :
false;
4146 #ifndef TILESON_TILEOBJECT_HPP
4147 #define TILESON_TILEOBJECT_HPP
4154 #ifndef TILESON_RECT_HPP
4155 #define TILESON_RECT_HPP
4160 inline Rect() =
default;
4161 inline Rect(
int x_,
int y_,
int width_,
int height_);
4163 inline bool operator==(
const Rect &rhs)
const;
4164 inline bool operator!=(
const Rect &rhs)
const;
4172 Rect::Rect(
int x_,
int y_,
int width_,
int height_)
4180 bool Rect::operator==(
const Rect &rhs)
const
4182 return x == rhs.x && y == rhs.y && width == rhs.width && height == rhs.height;
4185 bool Rect::operator!=(
const Rect &rhs)
const
4187 return !(rhs == *
this);
4208 inline const tson::Rect &getDrawingRect()
const;
4216 TileObject::TileObject(
const std::tuple<int, int> &posInTileUnits,
tson::Tile *tile)
4236 return m_posInTileUnits;
4258 #ifndef TILESON_FLAGGEDTILE_HPP
4259 #define TILESON_FLAGGEDTILE_HPP
4264 FlaggedTile(
size_t x_,
size_t y_, uint32_t id_, uint32_t tileId_) : x {x_}, y {y_},
id {id_},
tileId {tileId_} {}
4284 inline Layer() =
default;
4291 inline const std::vector<uint32_t> &
getData()
const;
4299 inline int getId()
const;
4301 inline const std::string &
getImage()
const;
4303 inline const std::string &
getName()
const;
4320 inline LayerType
getType()
const;
4322 inline const std::string &getClassType()
const;
4327 inline const std::string &
getTypeStr()
const;
4331 inline int getX()
const;
4333 inline int getY()
const;
4336 inline std::vector<tson::Chunk> &
getChunks();
4338 inline std::vector<tson::Layer> &
getLayers();
4340 inline std::vector<tson::Object> &
getObjects();
4346 inline std::vector<tson::Object>
getObjectsByName(
const std::string &name);
4349 template<
typename T>
4350 inline T
get(
const std::string &name);
4353 inline void assignTileMap(std::map<uint32_t, tson::Tile *> *tileMap);
4370 inline const std::set<uint32_t> &getUniqueFlaggedTiles()
const;
4371 inline void resolveFlaggedTiles();
4376 std::vector<tson::Chunk> m_chunks;
4407 std::map<std::tuple<int, int>,
tson::Tile *> m_tileData;
4417 std::set<uint32_t> m_uniqueFlaggedTiles;
4418 std::vector<tson::FlaggedTile> m_flaggedTiles;
4420 std::string m_classType {};
4430 template<
typename T>
4448 uint32_t tileId = id;
4449 tileId &= ~(FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG);
4450 m_uniqueFlaggedTiles.insert(
id);
4451 m_flaggedTiles.emplace_back(x, y,
id, tileId);
4461 std::vector<tson::Object> found;
4463 std::copy_if(m_objects.begin(), m_objects.end(), std::back_inserter(found), [&](
const tson::Object &item) { return item.getName() == name; });
4475 std::vector<tson::Object> found;
4477 std::copy_if(m_objects.begin(), m_objects.end(), std::back_inserter(found), [&](
const tson::Object &item) { return item.getObjectType() == type; });
4489 auto result = std::find_if(m_objects.begin(), m_objects.end(), [&](
const tson::Object &obj) { return obj.getName() == name; });
4490 if (result == m_objects.end())
return nullptr;
4492 return &result.operator*();
4502 auto result = std::find_if(m_objects.begin(), m_objects.end(), [&](
const tson::Object &obj) { return obj.getId() == id; });
4503 if (result == m_objects.end())
return nullptr;
4505 return &result.operator*();
4514 if (m_typeStr ==
"tilelayer")
4515 m_type = LayerType::TileLayer;
4516 else if (m_typeStr ==
"objectgroup")
4517 m_type = LayerType::ObjectGroup;
4518 else if (m_typeStr ==
"imagelayer")
4519 m_type = LayerType::ImageLayer;
4520 else if (m_typeStr ==
"group")
4521 m_type = LayerType::Group;
4523 m_type = LayerType::Undefined;
4532 return m_compression;
4550 return m_base64Data;
4632 return m_transparentColor;
4704 return m_properties;
4714 if (m_properties.hasProperty(name))
return m_properties.getProperty(name);
4733 m_tileMap = tileMap;
4765 return (m_tileData.count({x, y}) > 0) ? m_tileData[{x, y}] :
nullptr;
4788 if (!isInfiniteMap) {
4789 std::for_each(m_data.begin(), m_data.end(), [&](uint32_t tileId) {
4790 if (static_cast<int>(x) == mapSize.x) {
4795 if (tileId > 0 && m_tileMap->count(tileId) > 0) {
4796 m_tileData[{static_cast<int>(x), static_cast<int>(y)}] = m_tileMap->at(tileId);
4797 m_tileObjects[{static_cast<int>(x), static_cast<int>(y)}] = {
4798 {static_cast<int>(x), static_cast<int>(y)}, m_tileData[{static_cast<int>(x), static_cast<int>(y)}]};
4799 }
else if (tileId > 0 && m_tileMap->count(tileId) == 0)
4801 queueFlaggedTile(x, y, tileId);
4808std::map<std::tuple<int, int>,
tson::TileObject> &tson::Layer::getTileObjects()
4810 return m_tileObjects;
4815 return (m_tileObjects.count({x, y}) > 0) ? &m_tileObjects[{x, y}] :
nullptr;
4818const std::set<uint32_t> &tson::Layer::getUniqueFlaggedTiles()
const
4820 return m_uniqueFlaggedTiles;
4823void tson::Layer::resolveFlaggedTiles()
4825 std::for_each(m_flaggedTiles.begin(), m_flaggedTiles.end(), [&](
const tson::FlaggedTile &tile) {
4826 if (tile.id > 0 && m_tileMap->count(tile.id) > 0) {
4827 m_tileData[{static_cast<int>(tile.x), static_cast<int>(tile.y)}] = m_tileMap->at(tile.id);
4828 m_tileObjects[{static_cast<int>(tile.x), static_cast<int>(tile.y)}] = {
4829 {static_cast<int>(tile.x), static_cast<int>(tile.y)}, m_tileData[{static_cast<int>(tile.x), static_cast<int>(tile.y)}]};
4874const std::string &tson::Layer::getClassType()
const
4888 #ifndef TILESON_TILESET_HPP
4889 #define TILESON_TILESET_HPP
4898 #ifndef TILESON_TRANSFORMATIONS_HPP
4899 #define TILESON_TRANSFORMATIONS_HPP
4906 inline bool parse(
IJson &json);
4921 Transformations::Transformations(IJson &json)
4926 bool Transformations::parse(IJson &json)
4928 if (json.count(
"hflip") > 0) m_hflip = json[
"hflip"].get<
bool>();
4929 if (json.count(
"preferuntransformed") > 0)
m_preferuntransformed = json[
"preferuntransformed"].get<bool>();
4930 if (json.count(
"rotate") > 0)
m_rotate = json[
"rotate"].get<bool>();
4931 if (json.count(
"vflip") > 0)
m_vflip = json[
"vflip"].get<bool>();
4983 #ifndef TILESON_WANGSET_HPP
4984 #define TILESON_WANGSET_HPP
4993 #ifndef TILESON_WANGCOLOR_HPP
4994 #define TILESON_WANGCOLOR_HPP
5008 inline const std::string &
getName()
const;
5015 template<
typename T>
5016 inline T
get(
const std::string &name);
5020 inline const std::string &getClassType()
const;
5033 std::string m_classType {};
5038tson::WangColor::WangColor(IJson &json,
tson::Map *map)
5043bool tson::WangColor::parse(IJson &json,
tson::Map *map)
5046 bool allFound =
true;
5048 if (json.count(
"color") > 0)
5049 m_color =
tson::Colori(json[
"color"].get<std::string>());
5052 if (json.count(
"name") > 0)
5053 m_name = json[
"name"].get<std::string>();
5056 if (json.count(
"probability") > 0)
5057 m_probability = json[
"probability"].get<float>();
5060 if (json.count(
"tile") > 0)
5061 m_tile = json[
"tile"].get<int>();
5064 if (json.count(
"class") > 0) m_classType = json[
"class"].get<std::string>();
5066 if (json.count(
"properties") > 0 && json[
"properties"].isArray()) {
5067 auto &properties = json.array(
"properties");
5068 std::for_each(properties.begin(), properties.end(), [&](std::unique_ptr<IJson> &item) { m_properties.add(*item); });
5098 return m_probability;
5117 return m_properties;
5129 return m_properties.getValue<T>(name);
5139 if (m_properties.hasProperty(name))
return m_properties.getProperty(name);
5144const std::string &tson::WangColor::getClassType()
const
5158 #ifndef TILESON_WANGTILE_HPP
5159 #define TILESON_WANGTILE_HPP
5180 inline const std::vector<uint32_t> &
getWangIds()
const;
5191tson::WangTile::WangTile(IJson &json)
5203 bool allFound =
true;
5205 if (json.count(
"dflip") > 0) m_dflip = json[
"dflip"].get<
bool>();
5206 if (json.count(
"hflip") > 0) m_hflip = json[
"hflip"].get<bool>();
5207 if (json.count(
"vflip") > 0) m_vflip = json[
"vflip"].get<bool>();
5209 if (json.count(
"tileid") > 0)
5210 m_tileid = json[
"tileid"].get<uint32_t>();
5213 if (json.count(
"wangid") > 0 && json[
"wangid"].isArray()) {
5214 auto &wangid = json.
array(
"wangid");
5215 std::for_each(wangid.begin(), wangid.end(), [&](std::unique_ptr<IJson> &item) { m_wangId.emplace_back(item->get<uint32_t>()); });
5284 inline const std::string &
getName()
const;
5289 inline const std::vector<tson::WangTile> &
getWangTiles()
const;
5293 inline const std::vector<tson::WangColor> &
getEdgeColors()
const;
5296 inline const std::vector<tson::WangColor> &
getColors()
const;
5299 template<
typename T>
5300 inline T
get(
const std::string &name);
5304 inline const std::string &getClassType()
const;
5322 std::string m_classType {};
5332 template<
typename T>
5335 return m_properties.getValue<T>(name);
5339tson::WangSet::WangSet(IJson &json,
tson::Map *map)
5344bool tson::WangSet::parse(IJson &json,
tson::Map *map)
5347 bool allFound =
true;
5349 if (json.count(
"tile") > 0)
5350 m_tile = json[
"tile"].
get<
int>();
5353 if (json.count(
"name") > 0)
5354 m_name = json[
"name"].get<std::string>();
5359 if (json.count(
"wangtiles") > 0 && json[
"wangtiles"].isArray()) {
5360 auto &wangtiles = json.array(
"wangtiles");
5361 std::for_each(wangtiles.begin(), wangtiles.end(), [&](std::unique_ptr<IJson> &item) { m_wangTiles.emplace_back(*item); });
5363 if (json.count(
"cornercolors") > 0 && json[
"cornercolors"].isArray()) {
5364 auto &cornercolors = json.array(
"cornercolors");
5365 std::for_each(cornercolors.begin(), cornercolors.end(), [&](std::unique_ptr<IJson> &item) { m_cornerColors.emplace_back(*item, m_map); });
5367 if (json.count(
"edgecolors") > 0 && json[
"edgecolors"].isArray()) {
5368 auto &edgecolors = json.array(
"edgecolors");
5369 std::for_each(edgecolors.begin(), edgecolors.end(), [&](std::unique_ptr<IJson> &item) { m_edgeColors.emplace_back(*item, m_map); });
5371 if (json.count(
"properties") > 0 && json[
"properties"].isArray()) {
5372 auto &properties = json.array(
"properties");
5373 std::for_each(properties.begin(), properties.end(), [&](std::unique_ptr<IJson> &item) { m_properties.add(*item); });
5376 if (json.count(
"class") > 0) m_classType = json[
"class"].get<std::string>();
5378 if (!parseTiled15Props(json)) allFound =
false;
5391 if (json.count(
"colors") > 0 && json[
"colors"].isArray()) {
5392 auto &colors = json.
array(
"colors");
5393 std::for_each(colors.begin(), colors.end(), [&](std::unique_ptr<IJson> &item) { m_colors.emplace_back(*item, m_map); });
5431 return m_cornerColors;
5440 return m_edgeColors;
5449 return m_properties;
5459 if (m_properties.hasProperty(name))
return m_properties.getProperty(name);
5482 auto color = std::find_if(m_colors.begin(), m_colors.end(), [&](
const auto &c) { return c.getName() == name; });
5484 if (color != m_colors.end())
return &color.operator*();
5489const std::string &tson::WangSet::getClassType()
const
5503 #ifndef TILESON_TILE_HPP
5504 #define TILESON_TILE_HPP
5513 #ifndef TILESON_FRAME_HPP
5514 #define TILESON_FRAME_HPP
5521 inline Frame() =
default;
5522 inline Frame(
int duration, uint32_t tileId);
5543tson::Frame::Frame(
int duration, uint32_t tileId) : m_duration {duration}, m_tileId {tileId} {}
5561 bool allFound =
true;
5563 if (json.count(
"duration") > 0)
5564 m_duration = json[
"duration"].get<
int>();
5567 if (json.count(
"tileid") > 0)
5568 m_tileId = json[
"tileid"].get<uint32_t>() + 1;
5602 #ifndef TILESON_ANIMATION_HPP
5603 #define TILESON_ANIMATION_HPP
5609 inline Animation(
const std::vector<tson::Frame> &frames) : m_frames {frames} {};
5611 inline void update(
float timeDeltaMs);
5612 inline void reset();
5614 inline void setFrames(
const std::vector<tson::Frame> &frames);
5615 inline void setCurrentFrame(uint32_t currentFrame);
5616 inline void setTimeDelta(
float timeDelta);
5618 inline const std::vector<tson::Frame> &getFrames()
const;
5620 inline uint32_t getCurrentFrameNumber()
const;
5621 inline uint32_t getCurrentTileId()
const;
5622 inline float getTimeDelta()
const;
5624 inline bool any()
const;
5625 inline size_t size()
const;
5628 inline int nextFrame();
5629 std::vector<tson::Frame> m_frames;
5630 uint32_t m_currentFrame {0};
5631 float m_timeDelta {0};
5634 const std::vector<tson::Frame> &Animation::getFrames()
const
5654 return (m_frames.size() == 0 || m_currentFrame >= m_frames.size()) ? nullptr : &m_frames.at(m_currentFrame);
5657 size_t Animation::size()
const
5659 return m_frames.size();
5669 if (frame !=
nullptr) {
5670 m_timeDelta += timeDeltaMs;
5672 m_timeDelta =
static_cast<float>((int32_t) m_timeDelta % frame->
getDuration());
5673 m_currentFrame = nextFrame();
5678 int Animation::nextFrame()
5680 return (m_currentFrame + 1 >= m_frames.size()) ? 0 : m_currentFrame + 1;
5683 float Animation::getTimeDelta()
const
5688 uint32_t Animation::getCurrentFrameNumber()
const
5690 return m_currentFrame;
5693 uint32_t Animation::getCurrentTileId()
const
5698 void Animation::setFrames(
const std::vector<tson::Frame> &frames)
5703 void Animation::setCurrentFrame(uint32_t currentFrame)
5705 m_currentFrame = currentFrame;
5708 void Animation::setTimeDelta(
float timeDelta)
5710 m_timeDelta = timeDelta;
5719 return m_frames.size() > 0;
5733 inline Tile() =
default;
5738 inline bool parseId(
IJson &json);
5741 inline uint32_t
getId()
const;
5743 inline const fs::path &
getImage()
const;
5747 inline const std::string &
getType()
const;
5761 inline const std::vector<int> &
getTerrain()
const;
5763 template<
typename T>
5764 inline T
get(
const std::string &name);
5788 inline uint32_t getGid()
const;
5814 std::shared_ptr<tson::TiledClass> m_class {};
5823 template<
typename T>
5826 return m_properties.getValue<T>(name);
5832 parse(json, tileset, map);
5851tson::Tile::Tile(uint32_t
id,
tson::Map *map) : m_id {id}, m_gid {id}
5863 m_tileset = tileset;
5864 performDataCalculations();
5874 m_tileset = tileset;
5877 if (json.count(
"image") > 0) m_image = fs::path(json[
"image"].get<std::string>());
5879 bool allFound = parseId(json);
5881 if (json.count(
"type") > 0)
5882 m_type = json[
"type"].get<std::string>();
5883 else if (json.count(
"class") > 0)
5884 m_type = json[
"class"].get<std::string>();
5886 if (json.count(
"objectgroup") > 0) m_objectgroup =
tson::Layer(json[
"objectgroup"], m_map);
5888 if (json.count(
"imagewidth") > 0 && json.count(
"imageheight") > 0)
5889 m_imageSize = {json[
"imagewidth"].get<
int>(), json[
"imageheight"].get<int>()};
5891 m_subRect = {0, 0, m_imageSize.x, m_imageSize.y};
5892 if (json.count(
"x") > 0) m_subRect.x = json[
"x"].get<
int>();
5893 if (json.count(
"y") > 0) m_subRect.y = json[
"y"].get<
int>();
5894 if (json.count(
"width") > 0) m_subRect.width = json[
"width"].get<
int>();
5895 if (json.count(
"height") > 0) m_subRect.height = json[
"height"].get<
int>();
5898 if (json.count(
"animation") > 0 && json[
"animation"].isArray()) {
5899 auto &animation = json.
array(
"animation");
5900 std::vector<tson::Frame> frames;
5901 std::for_each(animation.begin(), animation.end(), [&](std::unique_ptr<IJson> &item) { frames.emplace_back(*item); });
5902 if (frames.size() > 0) {
5903 m_animation.setFrames(frames);
5906 if (json.count(
"terrain") > 0 && json[
"terrain"].isArray()) {
5907 auto &terrain = json.
array(
"terrain");
5908 std::for_each(terrain.begin(), terrain.end(), [&](std::unique_ptr<IJson> &item) { m_terrain.emplace_back(item->get<int>()); });
5911 if (json.count(
"properties") > 0 && json[
"properties"].isArray()) {
5912 auto &properties = json.
array(
"properties");
5913 std::for_each(properties.begin(), properties.end(), [&](std::unique_ptr<IJson> &item) { m_properties.add(*item); });
5916 performDataCalculations();
5984 return m_objectgroup;
5993 return m_properties;
6012 if (m_properties.hasProperty(name))
return m_properties.getProperty(name);
6041 return m_drawingRect;
6056 return {std::get<0>(tileDataPos), std::get<1>(tileDataPos)};
6061 if (
id & FLIPPED_HORIZONTALLY_FLAG) m_flipFlags |= TileFlipFlags::Horizontally;
6062 if (
id & FLIPPED_VERTICALLY_FLAG) m_flipFlags |= TileFlipFlags::Vertically;
6063 if (
id & FLIPPED_DIAGONALLY_FLAG) m_flipFlags |= TileFlipFlags::Diagonally;
6065 id &= ~(FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG);
6083 return ((m_flipFlags & flags) == flags) ? true :
false;
6086uint32_t tson::Tile::getGid()
const
6093 m_properties = properties;
6114 #ifndef TILESON_TERRAIN_HPP
6115 #define TILESON_TERRAIN_HPP
6123 inline Terrain(std::string name,
int tile);
6126 inline bool parse(
IJson &json);
6129 inline const std::string &
getName()
const;
6135 template<
typename T>
6136 inline T
get(
const std::string &name);
6151 template<
typename T>
6154 return m_properties.getValue<T>(name);
6158tson::Terrain::Terrain(std::string name,
int tile) : m_name {std::move(name)}, m_tile {tile} {}
6160tson::Terrain::Terrain(IJson &json)
6165bool tson::Terrain::parse(IJson &json)
6167 bool allFound =
true;
6169 if (json.count(
"name") > 0)
6170 m_name = json[
"name"].get<std::string>();
6173 if (json.count(
"tile") > 0)
6174 m_tile = json[
"tile"].get<int>();
6178 if (json.count(
"properties") > 0 && json[
"properties"].isArray()) {
6179 auto &properties = json.array(
"properties");
6180 std::for_each(properties.begin(), properties.end(), [&](std::unique_ptr<IJson> &item) { m_properties.add(*item); });
6210 return m_properties;
6220 if (m_properties.hasProperty(name))
return m_properties.getProperty(name);
6233 #ifndef TILESON_GRID_HPP
6234 #define TILESON_GRID_HPP
6243 inline Grid() =
default;
6254 std::string m_orientation;
6275 bool allFound =
true;
6277 if (json.count(
"orientation") > 0) m_orientation = json[
"orientation"].get<std::string>();
6279 if (json.count(
"width") > 0 && json.count(
"height") > 0)
6280 m_size = {json[
"width"].get<
int>(), json[
"height"].get<int>()};
6293 return m_orientation;
6309 #include <functional>
6328 inline const fs::path &
getImage()
const;
6334 inline const std::string &
getName()
const;
6344 inline const std::string &
getType()
const;
6346 inline const std::string &getClassType()
const;
6350 inline std::vector<tson::Tile> &
getTiles();
6352 inline const std::vector<tson::WangSet> &
getWangsets()
const;
6356 inline const std::vector<tson::Terrain> &
getTerrains()
const;
6362 inline TileRenderSize getTileRenderSize()
const;
6364 inline FillMode getFillMode()
const;
6369 template<
typename T>
6370 inline T
get(
const std::string &name);
6377 inline ObjectAlignment getObjectAlignment()
const;
6386 #ifndef TSON_TEST_ENABLED
6442 template<
typename T>
6445 return m_properties.getValue<T>(name);
6449tson::Tileset::Tileset(IJson &json,
tson::Map *map)
6454bool tson::Tileset::parse(IJson &json,
tson::Map *map)
6457 bool allFound =
true;
6459 if (json.count(
"firstgid") > 0)
6460 m_firstgid = json[
"firstgid"].
get<
int>();
6465 if (json.count(
"source") > 0) {
6466 if (!allFound)
return allFound;
6468 std::string sourceStr = json[
"source"].get<std::string>();
6469 m_source = fs::path(sourceStr);
6470 m_path = json.directory() / m_source;
6472 if (!json.parse(m_path))
return false;
6475 if (json.count(
"columns") > 0)
6476 m_columns = json[
"columns"].get<
int>();
6480 if (json.count(
"image") > 0)
6481 m_image = fs::path(json[
"image"].get<std::string>());
6485 if (json.count(
"margin") > 0)
6486 m_margin = json[
"margin"].get<int>();
6489 if (json.count(
"name") > 0)
6490 m_name = json[
"name"].get<std::string>();
6493 if (json.count(
"spacing") > 0)
6494 m_spacing = json[
"spacing"].get<int>();
6497 if (json.count(
"tilecount") > 0)
6498 m_tileCount = json[
"tilecount"].get<int>();
6501 if (json.count(
"transparentcolor") > 0) m_transparentColor =
tson::Colori(json[
"transparentcolor"].get<std::string>());
6502 if (json.count(
"type") > 0) m_type = json[
"type"].get<std::string>();
6503 if (json.count(
"grid") > 0) m_grid =
tson::Grid(json[
"grid"]);
6504 if (json.count(
"class") > 0) m_classType = json[
"class"].get<std::string>();
6506 if (json.count(
"imagewidth") > 0 && json.count(
"imageheight") > 0)
6507 m_imageSize = {json[
"imagewidth"].get<
int>(), json[
"imageheight"].get<int>()};
6510 if (json.count(
"tilewidth") > 0 && json.count(
"tileheight") > 0)
6511 m_tileSize = {json[
"tilewidth"].get<
int>(), json[
"tileheight"].get<int>()};
6514 if (json.count(
"tileoffset") > 0) m_tileOffset = {json[
"tileoffset"][
"x"].get<
int>(), json[
"tileoffset"][
"y"].get<int>()};
6516 if (json.count(
"tilerendersize") > 0) {
6517 std::string tileRenderStr = json[
"tilerendersize"].get<std::string>();
6518 if (tileRenderStr ==
"tile")
6519 m_tileRenderSize = TileRenderSize::Tile;
6520 else if (tileRenderStr ==
"grid")
6521 m_tileRenderSize = TileRenderSize::Grid;
6524 if (json.count(
"fillmode") > 0) {
6525 std::string fillmode = json[
"fillmode"].get<std::string>();
6526 if (fillmode ==
"stretch")
6527 m_fillMode = FillMode::Stretch;
6528 else if (fillmode ==
"preserve-aspect-fit")
6529 m_fillMode = FillMode::PreserveAspectFit;
6533 if (json.count(
"wangsets") > 0 && json[
"wangsets"].isArray()) {
6534 auto &wangsets = json.array(
"wangsets");
6535 std::for_each(wangsets.begin(), wangsets.end(), [&](std::unique_ptr<IJson> &item) { m_wangsets.emplace_back(*item, m_map); });
6537 if (json.count(
"tiles") > 0 && json[
"tiles"].isArray()) {
6538 auto &tiles = json.array(
"tiles");
6539 std::for_each(tiles.begin(), tiles.end(), [&](std::unique_ptr<IJson> &item) { m_tiles.emplace_back(*item, this, m_map); });
6541 if (json.count(
"terrains") > 0 && json[
"terrains"].isArray()) {
6542 auto &terrains = json.array(
"terrains");
6543 std::for_each(terrains.begin(), terrains.end(), [&](std::unique_ptr<IJson> &item) { m_terrains.emplace_back(*item); });
6546 if (json.count(
"properties") > 0 && json[
"properties"].isArray()) {
6547 auto &properties = json.array(
"properties");
6548 std::for_each(properties.begin(), properties.end(), [&](std::unique_ptr<IJson> &item) { m_properties.add(*item); });
6551 if (json.count(
"objectalignment") > 0) {
6552 std::string alignment = json[
"objectalignment"].get<std::string>();
6553 m_objectAlignment = StringToAlignment(alignment);
6556 if (json.count(
"transformations") > 0) {
6557 m_transformations.parse(json[
"transformations"]);
6560 generateMissingTiles();
6653 return m_transparentColor;
6699 return m_properties;
6717 return m_tileOffset;
6738 auto result = std::find_if(m_tiles.begin(), m_tiles.end(), [&](
const tson::Tile &item) { return item.getId() == id; });
6739 if (result == m_tiles.end())
return nullptr;
6741 return &result.operator*();
6751 auto result = std::find_if(m_terrains.begin(), m_terrains.end(), [&](
const tson::Terrain &item) { return item.getName() == name; });
6752 if (result == m_terrains.end())
return nullptr;
6754 return &result.operator*();
6764 if (m_properties.hasProperty(name))
return m_properties.getProperty(name);
6774 std::vector<uint32_t> tileIds;
6775 for (
auto &tile : m_tiles)
6776 tileIds.push_back(tile.getId());
6778 for (uint32_t i = m_firstgid; i < m_firstgid + (uint32_t) m_tileCount; ++i) {
6779 if (std::count(tileIds.begin(), tileIds.end(), i) == 0) {
6780 m_tiles.emplace_back(
Tile(i,
this, m_map));
6801 if (str ==
"unspecified")
6802 return tson::ObjectAlignment::Unspecified;
6803 else if (str ==
"topleft")
6804 return tson::ObjectAlignment::TopLeft;
6805 else if (str ==
"top")
6806 return tson::ObjectAlignment::Top;
6807 else if (str ==
"topright")
6808 return tson::ObjectAlignment::TopRight;
6809 else if (str ==
"left")
6810 return tson::ObjectAlignment::Left;
6811 else if (str ==
"center")
6812 return tson::ObjectAlignment::Center;
6813 else if (str ==
"right")
6814 return tson::ObjectAlignment::Right;
6815 else if (str ==
"bottomleft")
6816 return tson::ObjectAlignment::BottomLeft;
6817 else if (str ==
"bottom")
6818 return tson::ObjectAlignment::Bottom;
6819 else if (str ==
"bottomright")
6820 return tson::ObjectAlignment::BottomRight;
6822 return tson::ObjectAlignment::Unspecified;
6825tson::ObjectAlignment tson::Tileset::getObjectAlignment()
const
6827 return m_objectAlignment;
6839 if (m_margin == 0 && m_spacing == 0)
return {0, 0};
6841 tson::Vector2i offset {(posInTileUnits.x * m_spacing) + m_margin, (posInTileUnits.y * m_spacing) + m_margin};
6852 auto wangset = std::find_if(m_wangsets.begin(), m_wangsets.end(), [&](
const auto &w) { return w.getName() == name; });
6854 if (wangset != m_wangsets.end())
return &wangset.operator*();
6867 return m_transformations;
6870tson::TileRenderSize tson::Tileset::getTileRenderSize()
const
6872 return m_tileRenderSize;
6875tson::FillMode tson::Tileset::getFillMode()
const
6880const std::string &tson::Tileset::getClassType()
const
6891 inline Map() =
default;
6892 inline Map(ParseStatus status, std::string description);
6921 inline const std::string &
getType()
const;
6923 inline const std::string &getClassType()
const;
6931 inline std::vector<tson::Layer> &
getLayers();
6938 inline ParseStatus getStatus()
const;
6940 inline const std::string &getStatusMessage()
const;
6942 inline const std::map<uint32_t, tson::Tile *> &
getTileMap()
const;
6944 inline Layer *getLayer(
const std::string &name);
6947 template<
typename T>
6948 inline T
get(
const std::string &name);
6962 Colori m_backgroundColor;
6983 std::string m_statusMessage {
"OK"};
6985 std::map<uint32_t, tson::Tile *> m_tileMap {};
6993 std::map<uint32_t, tson::Tile> m_flaggedTileMap {};
7005 template<
typename T>
7008 return m_properties.getValue<T>(name);
7017tson::Map::Map(tson::ParseStatus status, std::string description) : m_status {status}, m_statusMessage {std::move(description)} {}
7026 parse(json, decompressors, project);
7036 m_decompressors = decompressors;
7037 m_project = project;
7039 bool allFound =
true;
7040 if (json.count(
"compressionlevel") > 0) m_compressionLevel = json[
"compressionlevel"].get<
int>();
7042 if (json.count(
"backgroundcolor") > 0) m_backgroundColor =
Colori(json[
"backgroundcolor"].get<std::string>());
7043 if (json.count(
"width") > 0 && json.count(
"height") > 0)
7044 m_size = {json[
"width"].get<
int>(), json[
"height"].get<int>()};
7047 if (json.count(
"hexsidelength") > 0) m_hexsideLength = json[
"hexsidelength"].get<int>();
7048 if (json.count(
"infinite") > 0) m_isInfinite = json[
"infinite"].get<bool>();
7049 if (json.count(
"nextlayerid") > 0) m_nextLayerId = json[
"nextlayerid"].get<int>();
7050 if (json.count(
"nextobjectid") > 0)
7051 m_nextObjectId = json[
"nextobjectid"].get<int>();
7054 if (json.count(
"orientation") > 0)
7055 m_orientation = json[
"orientation"].get<std::string>();
7058 if (json.count(
"renderorder") > 0) m_renderOrder = json[
"renderorder"].get<std::string>();
7059 if (json.count(
"staggeraxis") > 0) m_staggerAxis = json[
"staggeraxis"].get<std::string>();
7060 if (json.count(
"staggerindex") > 0) m_staggerIndex = json[
"staggerindex"].get<std::string>();
7061 if (json.count(
"tiledversion") > 0)
7062 m_tiledVersion = json[
"tiledversion"].get<std::string>();
7065 if (json.count(
"tilewidth") > 0 && json.count(
"tileheight") > 0)
7066 m_tileSize = {json[
"tilewidth"].get<
int>(), json[
"tileheight"].get<int>()};
7069 if (json.count(
"type") > 0) m_type = json[
"type"].get<std::string>();
7070 if (json.count(
"class") > 0) m_classType = json[
"class"].get<std::string>();
7077 if (json.count(
"layers") > 0 && json[
"layers"].isArray()) {
7078 auto &array = json.
array(
"layers");
7079 std::for_each(array.begin(), array.end(), [&](std::unique_ptr<IJson> &item) { m_layers.emplace_back(*item, this); });
7082 if (json.count(
"properties") > 0 && json[
"properties"].isArray()) {
7083 auto &array = json.
array(
"properties");
7084 std::for_each(array.begin(), array.end(), [&](std::unique_ptr<IJson> &item) { m_properties.add(*item, m_project); });
7088 if (json.count(
"parallaxoriginx") > 0) parallaxOrigin.x = json[
"parallaxoriginx"].get<
float>();
7089 if (json.count(
"parallaxoriginy") > 0) parallaxOrigin.y = json[
"parallaxoriginy"].get<
float>();
7091 m_parallaxOrigin = parallaxOrigin;
7093 if (!createTilesetData(json)) allFound =
false;
7106 if (json.count(
"tilesets") > 0 && json[
"tilesets"].isArray()) {
7108 auto &tilesets = json.
array(
"tilesets");
7109 std::for_each(tilesets.begin(), tilesets.end(), [&](std::unique_ptr<IJson> &) { m_tilesets.emplace_back(); });
7113 std::for_each(tilesets.begin(), tilesets.end(), [&](std::unique_ptr<IJson> &item) {
7114 item->directory(json.directory());
7115 if (!m_tilesets[i].parse(*item, this)) ok = false;
7129 for (
auto &tileset : m_tilesets) {
7130 std::set<std::uint32_t> usedIds;
7131 for (
auto &tile : tileset.getTiles()) {
7132 if (usedIds.count(tile.getGid()) != 0) {
7135 usedIds.insert(tile.getGid());
7136 m_tileMap[tile.getGid()] = &tile;
7139 std::for_each(m_layers.begin(), m_layers.end(), [&](
tson::Layer &layer) {
7140 layer.assignTileMap(&m_tileMap);
7141 layer.createTileData(m_size, m_isInfinite);
7142 const std::set<uint32_t> &flaggedTiles = layer.getUniqueFlaggedTiles();
7143 for (uint32_t ftile : flaggedTiles) {
7144 tson::Tile tile {ftile, layer.getMap()};
7145 if (m_tileMap.count(tile.getGid())) {
7146 tson::Tile *originalTile = m_tileMap[tile.getGid()];
7147 tile.addTilesetAndPerformCalculations(originalTile->getTileset());
7148 tile.setProperties(originalTile->getProperties());
7149 m_flaggedTileMap[ftile] = tile;
7150 m_tileMap[ftile] = &m_flaggedTileMap[ftile];
7153 layer.resolveFlaggedTiles();
7163 return m_backgroundColor;
7181 return m_hexsideLength;
7190 return m_isInfinite;
7199 return m_nextLayerId;
7208 return m_nextObjectId;
7217 return m_orientation;
7226 return m_renderOrder;
7235 return m_staggerAxis;
7244 return m_staggerIndex;
7253 return m_tiledVersion;
7298 return m_properties;
7310tson::Layer *tson::Map::getLayer(
const std::string &name)
7312 auto result = std::find_if(m_layers.begin(), m_layers.end(), [&](
const tson::Layer &item) { return item.getName() == name; });
7313 if (result == m_layers.end())
return nullptr;
7315 return &result.operator*();
7326 auto result = std::find_if(m_tilesets.begin(), m_tilesets.end(), [&](
const tson::Tileset &item) { return item.getName() == name; });
7327 if (result == m_tilesets.end())
return nullptr;
7329 return &result.operator*();
7340 auto result = std::find_if(m_tilesets.begin(), m_tilesets.end(), [&](
const tson::Tileset &tileset) {
7341 auto const firstId = static_cast<uint32_t>(tileset.getFirstgid());
7342 auto const lastId = static_cast<uint32_t>((firstId + tileset.getTileCount()) - 1);
7344 return (gid >= firstId && gid <= lastId);
7346 if (result == m_tilesets.end())
return nullptr;
7348 return &result.operator*();
7358 if (m_properties.hasProperty(name))
return m_properties.getProperty(name);
7362tson::ParseStatus tson::Map::getStatus()
const
7367const std::string &tson::Map::getStatusMessage()
const
7369 return m_statusMessage;
7383 return m_decompressors;
7393 return m_compressionLevel;
7403 return m_parallaxOrigin;
7411const std::string &tson::Map::getClassType()
const
7425 #ifndef TILESON_TILEDENUM_HPP
7426 #define TILESON_TILEDENUM_HPP
7432 inline uint32_t getValue(
const std::string &str);
7433 inline std::string getValue(uint32_t num);
7434 inline std::vector<std::string> getValues(uint32_t num);
7435 inline bool exists(
const std::string &str);
7436 inline bool exists(uint32_t num);
7439 inline uint32_t getId()
const;
7441 inline uint32_t getMaxValue()
const;
7443 inline const std::string &getName()
const;
7445 inline EnumStorageType getStorageType()
const;
7447 inline bool hasValuesAsFlags()
const;
7450 inline bool hasFlag(uint32_t value, uint32_t flag)
const;
7452 uint32_t m_maxValue {};
7453 std::string m_name {};
7454 std::map<uint32_t, std::string> m_values {};
7455 bool m_valuesAsFlags {
false};
7456 EnumStorageType m_storageType {EnumStorageType::Unspecified};
7459 EnumDefinition::EnumDefinition(
IJson &json)
7461 m_id = json.get<uint32_t>(
"id");
7462 m_name = json.get<std::string>(
"name");
7463 std::string type = json.get<std::string>(
"storageType");
7464 m_storageType = (type ==
"int") ? EnumStorageType::Int : (type ==
"string") ? EnumStorageType::String : EnumStorageType::Unspecified;
7465 m_valuesAsFlags = json.get<
bool>(
"valuesAsFlags");
7467 if (json.count(
"values") > 0 && json[
"values"].isArray()) {
7468 m_values[0] =
"None";
7469 uint32_t valueCounter = (m_valuesAsFlags) ? 1 : 0;
7470 uint8_t flagBit = 1;
7471 auto &array = json.
array(
"values");
7472 std::for_each(array.begin(), array.end(), [&](std::unique_ptr<IJson> &item) {
7473 std::string v = item->get<std::string>();
7474 m_values[valueCounter] = v;
7475 if (m_valuesAsFlags) {
7476 valueCounter = 1 << flagBit;
7483 m_maxValue = valueCounter;
7487 uint32_t EnumDefinition::getValue(
const std::string &str)
7489 auto result = std::find_if(m_values.begin(), m_values.end(), [&](
const std::pair<uint32_t, std::string> &pair) { return pair.second == str; });
7491 if (result != m_values.end())
return result->first;
7496 std::string EnumDefinition::getValue(uint32_t num)
7498 return (m_values.count(num) > 0) ? m_values[num] :
"";
7501 bool EnumDefinition::hasValuesAsFlags()
const
7503 return m_valuesAsFlags;
7506 bool EnumDefinition::exists(
const std::string &str)
7508 auto result = std::find_if(m_values.begin(), m_values.end(), [&](
const std::pair<uint32_t, std::string> &pair) { return pair.second == str; });
7510 if (result != m_values.end())
return true;
7515 bool EnumDefinition::exists(uint32_t num)
7517 return (m_values.count(num) > 0);
7520 uint32_t EnumDefinition::getId()
const
7525 const std::string &EnumDefinition::getName()
const
7530 EnumStorageType EnumDefinition::getStorageType()
const
7532 return m_storageType;
7535 uint32_t EnumDefinition::getMaxValue()
const
7540 std::vector<std::string> EnumDefinition::getValues(uint32_t num)
7542 std::vector<std::string> values;
7543 if (m_valuesAsFlags) {
7546 while (flag < m_maxValue) {
7549 if (m_values.count(flag) > 0 && hasFlag(num, flag)) {
7550 values.emplace_back(m_values[flag]);
7554 std::string v = getValue(num);
7555 if (!v.empty()) values.emplace_back();
7561 bool EnumDefinition::hasFlag(uint32_t value, uint32_t flag)
const
7563 return ((value & flag) == flag);
7573 inline uint32_t getValue()
const;
7574 inline std::string getValueName()
const;
7576 inline std::vector<std::string> getValueNames()
const;
7580 inline bool hasFlagValue(uint32_t flag)
const;
7581 template<
typename T>
7582 inline bool hasFlag(T flags)
const;
7583 inline bool hasAnyFlagValue(uint32_t flags)
const;
7584 template<
typename T>
7585 inline bool hasAnyFlag(T flags)
const;
7587 inline bool containsValueName(
const std::string &value)
const;
7590 uint32_t m_value {0};
7594 EnumValue::EnumValue(uint32_t value,
EnumDefinition *definition) : m_value {value}, m_definition {definition} {}
7596 EnumValue::EnumValue(
const std::string &value, EnumDefinition *definition) : m_definition {definition}
7598 if (!value.empty() && definition !=
nullptr) {
7599 std::vector<std::string> values = Tools::SplitString(value,
',');
7600 for (
auto &item : values) {
7601 uint32_t v = definition->getValue(item);
7615 if (m_definition->hasValuesAsFlags())
return ((m_value & flags) == flags) ? true :
false;
7617 return m_value == flags;
7628 if (m_definition->hasValuesAsFlags())
return ((m_value & flags) != 0);
7630 return m_value == flags;
7633 uint32_t EnumValue::getValue()
const
7646 return (m_definition ==
nullptr) ?
"" : m_definition->getValue(m_value);
7656 template<
typename T>
7669 template<
typename T>
7677 return m_definition;
7680 std::vector<std::string> EnumValue::getValueNames()
const
7682 return (m_definition ==
nullptr) ? std::vector<std::string>() : m_definition->getValues(m_value);
7692 if (m_definition !=
nullptr) {
7693 if (m_definition->hasValuesAsFlags()) {
7694 std::vector<std::string> values = m_definition->getValues(m_value);
7695 auto it = std::find(values.begin(), values.end(), value);
7696 return it != values.end();
7698 return m_definition->getValue(value) == m_value;
7713 #ifndef TILESON_TILEDCLASS_HPP
7714 #define TILESON_TILEDCLASS_HPP
7723 inline uint32_t getId()
const;
7725 inline const std::string &getName()
const;
7727 inline const std::string &getType()
const;
7733 template<
typename T>
7734 inline T get(
const std::string &name);
7739 std::string m_name {};
7740 std::string m_type {};
7746 if (json.count(
"id") > 0) m_id = json[
"id"].get<uint32_t>();
7748 if (json.count(
"name") > 0) m_name = json[
"name"].get<std::string>();
7749 if (json.count(
"type") > 0) m_type = json[
"type"].get<std::string>();
7751 if (json.count(
"members") > 0 && json[
"members"].isArray()) {
7752 auto &array = json.
array(
"members");
7753 std::for_each(array.begin(), array.end(), [&](std::unique_ptr<IJson> &item) { m_members.add(*item, project); });
7757 uint32_t TiledClass::getId()
const
7762 const std::string &TiledClass::getName()
const
7767 const std::string &TiledClass::getType()
const
7772 const PropertyCollection &TiledClass::getMembers()
const
7777 template<
typename T>
7778 T TiledClass::get(
const std::string &name)
7780 return m_members.getValue<T>(name);
7785 if (m_members.hasProperty(name))
return m_members.getProperty(name);
7796 if (json.any(property->getName())) {
7797 property->setValueByType(json[property->getName()]);
7804 std::vector<Property *> toUpdate;
7806 if (properties.hasProperty(member->getName())) {
7807 Property *
property = properties.getProperty(member->getName());
7808 if (member->getType() == property->getType()) {
7809 toUpdate.push_back(property);
7814 std::for_each(toUpdate.begin(), toUpdate.end(), [&](Property *p) { m_members.setProperty(p->getName(), *p); });
7827 #ifndef TILESON_PROJECT_HPP
7828 #define TILESON_PROJECT_HPP
7839 #ifndef TILESON_WORLD_HPP
7840 #define TILESON_WORLD_HPP
7847 #ifndef TILESON_WORLDMAPDATA_HPP
7848 #define TILESON_WORLDMAPDATA_HPP
7854 inline void parse(
const fs::path &folder_,
IJson &json);
7862 std::string fileName;
7867 WorldMapData::WorldMapData(
const fs::path &folder_,
IJson &json)
7869 parse(folder_, json);
7872 void WorldMapData::parse(
const fs::path &folder_, IJson &json)
7875 if (json.count(
"fileName") > 0) fileName = json[
"fileName"].get<std::string>();
7876 if (json.count(
"height") > 0) size = {json[
"width"].get<
int>(), json[
"height"].get<int>()};
7877 if (json.count(
"x") > 0) position = {json[
"x"].get<
int>(), json[
"y"].get<int>()};
7879 path = (!fileName.empty()) ? folder / fileName : folder;
7893 #ifdef JSON11_IS_DEFINED
7894 inline explicit World(std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>()) : m_json {std::move(jsonParser)} {}
7896 inline explicit World(
const fs::path &path, std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>());
7898 inline explicit World(std::unique_ptr<tson::IJson> jsonParser) : m_json {std::move(jsonParser)} {}
7900 inline explicit World(
const fs::path &path, std::unique_ptr<tson::IJson> jsonParser);
7902 inline bool parse(
const fs::path &path);
7904 inline bool contains(std::string_view filename);
7908 inline const fs::path &getPath()
const;
7910 inline const fs::path &getFolder()
const;
7912 inline const std::vector<WorldMapData> &getMapData()
const;
7914 inline bool onlyShowAdjacentMaps()
const;
7916 inline const std::string &getType()
const;
7918 inline const std::vector<std::unique_ptr<tson::Map>> &
getMaps()
const;
7921 inline void parseJson(
IJson &json);
7923 std::unique_ptr<IJson> m_json =
nullptr;
7926 std::vector<WorldMapData> m_mapData;
7927 std::vector<std::unique_ptr<tson::Map>> m_maps;
7928 bool m_onlyShowAdjacentMaps;
7932 World::World(
const fs::path &path, std::unique_ptr<tson::IJson> jsonParser) : m_json {std::move(jsonParser)}
7937 bool World::parse(
const fs::path &path)
7940 m_folder = m_path.parent_path();
7942 if (!m_json->parse(path))
return false;
7948 const fs::path &World::getPath()
const
7953 const std::vector<WorldMapData> &World::getMapData()
const
7958 bool World::onlyShowAdjacentMaps()
const
7960 return m_onlyShowAdjacentMaps;
7963 const std::string &World::getType()
const
7968 void World::parseJson(IJson &json)
7970 if (json.count(
"onlyShowAdjacentMaps") > 0) m_onlyShowAdjacentMaps = json[
"onlyShowAdjacentMaps"].get<
bool>();
7971 if (json.count(
"type") > 0) m_type = json[
"type"].get<std::string>();
7973 if (json[
"maps"].isArray()) {
7974 auto &maps = json.array(
"maps");
7975 std::for_each(maps.begin(), maps.end(), [&](std::unique_ptr<IJson> &item) { m_mapData.emplace_back(m_folder, *item); });
7979 const fs::path &World::getFolder()
const
7993 return std::any_of(m_mapData.begin(), m_mapData.end(), [&](
const auto &item) { return item.fileName == filename; });
8003 auto iter = std::find_if(m_mapData.begin(), m_mapData.end(), [&](
const auto &item) { return item.fileName == filename; });
8004 return (iter == m_mapData.end()) ? nullptr : iter.operator->();
8029 #ifndef TILESON_PROJECTPROPERTYTYPES_HPP
8030 #define TILESON_PROJECTPROPERTYTYPES_HPP
8038 inline const std::vector<tson::EnumDefinition> &getEnums()
const;
8039 inline const std::vector<tson::TiledClass> &getClasses()
const;
8044 inline bool isUnhandledContentFound()
const;
8047 std::vector<tson::EnumDefinition> m_enums;
8048 std::vector<tson::TiledClass> m_classes;
8049 bool m_unhandledContentFound {
false};
8056 m_unhandledContentFound =
false;
8058 if (json.count(
"propertyTypes") > 0 && json[
"propertyTypes"].isArray()) {
8059 auto &array = json.
array(
"propertyTypes");
8060 std::vector<tson::IJson *> classes;
8061 std::vector<tson::IJson *> other;
8062 std::for_each(array.begin(), array.end(), [&](std::unique_ptr<IJson> &item) {
8064 if (j.count(
"type") > 0) {
8065 std::string t = j[
"type"].get<std::string>();
8067 m_enums.emplace_back(j);
8068 } else if (t ==
"class") {
8069 classes.push_back(item.get());
8071 other.push_back(item.get());
8075 std::for_each(classes.begin(), classes.end(), [&](IJson *item) { m_classes.emplace_back(*item, project); });
8077 if (!other.empty()) m_unhandledContentFound =
true;
8082 const std::vector<tson::EnumDefinition> &ProjectPropertyTypes::getEnums()
const
8087 const std::vector<tson::TiledClass> &ProjectPropertyTypes::getClasses()
const
8092 bool ProjectPropertyTypes::isUnhandledContentFound()
const
8094 return m_unhandledContentFound;
8099 auto it = std::find_if(m_enums.begin(), m_enums.end(), [&](
const EnumDefinition &def) { return def.getName() == name; });
8101 if (it != m_enums.end())
return &it.operator*();
8108 auto it = std::find_if(m_classes.begin(), m_classes.end(), [&](
const TiledClass &def) { return def.getName() == name; });
8110 if (it != m_classes.end())
return &it.operator*();
8125 #ifndef TILESON_PROJECTFOLDER_HPP
8126 #define TILESON_PROJECTFOLDER_HPP
8133 inline const fs::path &getPath()
const;
8134 inline bool hasWorldFile()
const;
8135 inline const std::vector<ProjectFolder> &getSubFolders()
const;
8136 inline const std::vector<fs::path> &getFiles()
const;
8140 inline void loadData();
8142 bool m_hasWorldFile;
8144 std::vector<ProjectFolder> m_subFolders;
8145 std::vector<fs::path> m_files;
8148 ProjectFolder::ProjectFolder(
const fs::path &path) : m_path {path}
8153 void ProjectFolder::loadData()
8155 m_hasWorldFile =
false;
8156 m_subFolders.clear();
8160 for (
const auto &entry : fs::directory_iterator(m_path)) {
8161 if (fs::is_regular_file(entry.path())) {
8162 if (entry.path().extension() ==
".world") {
8163 m_hasWorldFile =
true;
8164 worldPath = entry.path();
8169 if (m_hasWorldFile) m_world.parse(worldPath);
8171 for (
const auto &entry : fs::directory_iterator(m_path)) {
8172 if (fs::is_directory(entry.path()))
8173 m_subFolders.emplace_back(entry.path());
8174 else if (fs::is_regular_file(entry.path())) {
8175 if (m_hasWorldFile && m_world.
contains(entry.path().filename().generic_string()))
8176 m_files.emplace_back(entry.path());
8177 else if (!m_hasWorldFile)
8178 m_files.emplace_back(entry.path());
8183 const fs::path &ProjectFolder::getPath()
const
8188 bool ProjectFolder::hasWorldFile()
const
8190 return m_hasWorldFile;
8193 const std::vector<ProjectFolder> &ProjectFolder::getSubFolders()
const
8195 return m_subFolders;
8198 const std::vector<fs::path> &ProjectFolder::getFiles()
const
8221 #ifndef TILESON_PROJECTDATA_HPP
8222 #define TILESON_PROJECTDATA_HPP
8228 std::string automappingRulesFile;
8229 std::vector<std::string> commands;
8230 std::string extensionsPath;
8231 std::vector<std::string> folders;
8232 std::string objectTypesFile;
8237 std::vector<tson::ProjectFolder> folderPaths;
8247 #ifdef JSON11_IS_DEFINED
8248 inline explicit Project(std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>()) : m_json {std::move(jsonParser)} {}
8250 inline explicit Project(
const fs::path &path, std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>());
8252 inline explicit Project(std::unique_ptr<tson::IJson> jsonParser) : m_json {std::move(jsonParser)} {}
8254 inline explicit Project(
const fs::path &path, std::unique_ptr<tson::IJson> jsonParser);
8256 inline bool parse(
const fs::path &path);
8257 inline void parse();
8262 inline const fs::path &getPath()
const;
8264 inline const std::vector<ProjectFolder> &getFolders()
const;
8271 inline void parseJson(
IJson &json);
8273 std::vector<ProjectFolder> m_folders;
8275 std::unique_ptr<IJson> m_json =
nullptr;
8278 Project::Project(
const fs::path &path, std::unique_ptr<tson::IJson> jsonParser) : m_json {std::move(jsonParser)}
8286 std::ifstream i(m_path.generic_string());
8289 if (!m_json->parse(path))
return false;
8290 }
catch (
const std::exception &error) {
8291 std::string message =
"Parse error: ";
8292 message += std::string(error.what());
8293 message += std::string(
"\n");
8300 const ProjectData &Project::getData()
const
8305 void Project::parseJson(IJson &json)
8307 m_data.basePath = (m_path.empty()) ? fs::path() : m_path.parent_path();
8310 if (json.count(
"propertyTypes") > 0) {
8311 m_data.projectPropertyTypes.parse(json,
this);
8314 if (json.count(
"automappingRulesFile") > 0) m_data.automappingRulesFile = json[
"automappingRulesFile"].get<std::string>();
8315 if (json.count(
"commands") > 0) {
8316 m_data.commands.clear();
8317 auto &commands = json.array(
"commands");
8318 std::for_each(commands.begin(), commands.end(), [&](std::unique_ptr<IJson> &item) { m_data.commands.emplace_back(item->get<std::string>()); });
8320 if (json.count(
"extensionsPath") > 0) m_data.extensionsPath = json[
"extensionsPath"].get<std::string>();
8321 if (json.count(
"folders") > 0) {
8322 m_data.folders.clear();
8323 m_data.folderPaths.clear();
8324 auto &folders = json.array(
"folders");
8325 std::for_each(folders.begin(), folders.end(), [&](std::unique_ptr<IJson> &item) {
8326 std::string folder = item->get<std::string>();
8327 m_data.folders.emplace_back(folder);
8328 m_data.folderPaths.emplace_back(m_data.basePath / folder);
8329 m_folders.emplace_back(m_data.basePath / folder);
8332 if (json.count(
"objectTypesFile") > 0) m_data.objectTypesFile = json[
"objectTypesFile"].get<std::string>();
8335 const fs::path &Project::getPath()
const
8340 const std::vector<ProjectFolder> &Project::getFolders()
const
8347 return m_data.projectPropertyTypes.getEnumDefinition(name);
8352 return m_data.projectPropertyTypes.getClass(name);
8373 #ifdef JSON11_IS_DEFINED
8374 inline explicit Tileson(std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>(),
bool includeBase64Decoder =
true);
8376 tson::Project *project, std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>(),
bool includeBase64Decoder =
true);
8378 inline explicit Tileson(std::unique_ptr<tson::IJson> jsonParser,
bool includeBase64Decoder =
true);
8379 inline explicit Tileson(
tson::Project *project, std::unique_ptr<tson::IJson> jsonParser,
bool includeBase64Decoder =
true);
8382 inline std::unique_ptr<tson::Map>
parse(
8383 const fs::path &path, std::unique_ptr<
IDecompressor<std::vector<uint8_t>, std::vector<uint8_t>>> decompressor =
nullptr);
8384 inline std::unique_ptr<tson::Map>
parse(
8385 const void *data,
size_t size, std::unique_ptr<
IDecompressor<std::vector<uint8_t>, std::vector<uint8_t>>> decompressor =
nullptr);
8389 inline std::unique_ptr<tson::Map>
parseJson();
8390 std::unique_ptr<tson::IJson> m_json;
8408 m_project = project;
8419 bool result =
false;
8421 if (decompressor !=
nullptr) {
8422 std::vector<uint8_t> decompressed = decompressor->decompressFile(path);
8423 result = (decompressed.empty()) ?
false :
true;
8424 if (!result)
return std::make_unique<tson::Map>(tson::ParseStatus::DecompressionError,
"Error during decompression");
8426 result = m_json->parse(&decompressed[0], decompressed.size());
8428 if (result)
return parseJson();
8429 }
else if (m_json->parse(path)) {
8433 std::string msg =
"File not found: ";
8434 msg += std::string(path.generic_string());
8435 return std::make_unique<tson::Map>(tson::ParseStatus::FileNotFound, msg);
8445 const void *data,
size_t size, std::unique_ptr<
IDecompressor<std::vector<uint8_t>, std::vector<uint8_t>>> decompressor)
8447 bool result =
false;
8449 if (decompressor !=
nullptr) {
8450 std::vector<uint8_t> decompressed = decompressor->decompress(data, size);
8451 result = (decompressed.empty()) ?
false :
true;
8452 if (!result)
return std::make_unique<tson::Map>(tson::ParseStatus::DecompressionError,
"Error during decompression");
8453 result = m_json->parse(&decompressed[0], decompressed.size());
8455 result = m_json->parse(data, size);
8457 if (!result)
return std::make_unique<tson::Map>(tson::ParseStatus::ParseError,
"Memory error");
8469 std::unique_ptr<tson::Map> map = std::make_unique<tson::Map>();
8471 if (map->parse(*m_json, &m_decompressors, m_project))
return map;
8473 return std::make_unique<tson::Map>(tson::ParseStatus::MissingData,
"Missing map data...");
8485 return &m_decompressors;
8497#ifndef TILESON_TILESON_FORWARD_HPP
8498 #define TILESON_TILESON_FORWARD_HPP
8515 if (m_class ==
nullptr) {
8516 TiledClass *baseClass = (m_project !=
nullptr) ? m_project->getClass(m_classType) :
nullptr;
8517 if (baseClass !=
nullptr) {
8518 m_class = std::make_shared<TiledClass>(*baseClass);
8519 m_class->update(m_properties);
8522 return (m_class !=
nullptr) ? m_class.get() :
nullptr;
8534 if (m_map !=
nullptr)
8535 return m_map->getTileSize();
8540bool tson::Tile::parseId(
IJson &json)
8542 if (json.count(
"id") > 0) {
8543 m_id = json[
"id"].get<uint32_t>() + 1;
8544 if (m_tileset !=
nullptr)
8545 m_gid = m_tileset->getFirstgid() + m_id - 1;
8548 manageFlipFlagsByIdThenRemoveFlags(m_gid);
8560 if (m_tileset ==
nullptr || m_map ==
nullptr)
return;
8562 int firstId = m_tileset->getFirstgid();
8563 int columns = m_tileset->getColumns();
8564 int rows = m_tileset->getTileCount() / columns;
8565 int lastId = (m_tileset->getFirstgid() + m_tileset->getTileCount()) - 1;
8567 int const gid =
static_cast<int>(getGid());
8568 if (gid >= firstId && gid <= lastId) {
8569 int const baseTilePosition = (gid - firstId);
8571 int const tileModX = (baseTilePosition % columns);
8572 int const currentRow = (baseTilePosition / columns);
8573 int const offsetX = (tileModX != 0) ? ((tileModX) *m_map->getTileSize().x) : (0 * m_map->getTileSize().x);
8574 int const offsetY = (currentRow < rows - 1) ? (currentRow * m_map->getTileSize().y) : ((rows - 1) * m_map->getTileSize().y);
8576 tson::Vector2i spacing = m_tileset->getMarginSpacingOffset({tileModX, currentRow});
8577 m_drawingRect = {offsetX + spacing.x, offsetY + spacing.y, m_map->getTileSize().x, m_map->getTileSize().y};
8579 m_drawingRect = {0, 0, 0, 0};
8588 return {((float) std::get<0>(tileDataPos)) * m_drawingRect.width, ((
float) std::get<1>(tileDataPos)) * m_drawingRect.height};
8598 if (m_class ==
nullptr) {
8599 TiledClass *baseClass = (m_map !=
nullptr && m_map->getProject() !=
nullptr) ? m_map->getProject()->getClass(m_type) :
nullptr;
8600 if (baseClass !=
nullptr) {
8601 m_class = std::make_shared<TiledClass>(*baseClass);
8602 m_class->update(m_properties);
8605 return (m_class !=
nullptr) ? m_class.get() :
nullptr;
8613 if (m_class ==
nullptr) {
8614 TiledClass *baseClass = (m_map !=
nullptr && m_map->getProject() !=
nullptr) ? m_map->getProject()->getClass(m_classType) :
nullptr;
8615 if (baseClass !=
nullptr) {
8616 m_class = std::make_shared<TiledClass>(*baseClass);
8617 m_class->update(m_properties);
8620 return (m_class !=
nullptr) ? m_class.get() :
nullptr;
8639const tson::Rect &tson::TileObject::getDrawingRect()
const
8641 return m_tile->getDrawingRect();
8653 if (container->
empty())
return;
8655 if (m_encoding.empty() && m_compression.empty())
return;
8657 std::string data = m_base64Data;
8658 bool hasBeenDecoded =
false;
8659 if (!m_encoding.empty() && container->
contains(m_encoding)) {
8661 hasBeenDecoded =
true;
8664 if (!m_compression.empty() && container->
contains(m_compression)) {
8668 if (hasBeenDecoded) {
8683 bool allFound =
true;
8684 if (json.count(
"tintcolor") > 0) m_tintColor =
tson::Colori(json[
"tintcolor"].get<std::string>());
8685 if (json.count(
"compression") > 0) m_compression = json[
"compression"].get<std::string>();
8686 if (json.count(
"draworder") > 0) m_drawOrder = json[
"draworder"].get<std::string>();
8687 if (json.count(
"encoding") > 0) m_encoding = json[
"encoding"].get<std::string>();
8688 if (json.count(
"id") > 0) m_id = json[
"id"].get<int>();
8689 if (json.count(
"image") > 0) m_image = json[
"image"].get<std::string>();
8690 if (json.count(
"name") > 0)
8691 m_name = json[
"name"].get<std::string>();
8694 if (json.count(
"offsetx") > 0 && json.count(
"offsety") > 0) m_offset = {json[
"offsetx"].get<
float>(), json[
"offsety"].get<float>()};
8695 if (json.count(
"opacity") > 0)
8696 m_opacity = json[
"opacity"].get<float>();
8699 if (json.count(
"width") > 0 && json.count(
"height") > 0)
8700 m_size = {json[
"width"].get<
int>(), json[
"height"].get<int>()};
8701 if (json.count(
"transparentcolor") > 0) m_transparentColor =
tson::Colori(json[
"transparentcolor"].get<std::string>());
8702 if (json.count(
"type") > 0)
8703 m_typeStr = json[
"type"].get<std::string>();
8706 if (json.count(
"class") > 0) m_classType = json[
"class"].get<std::string>();
8707 if (json.count(
"visible") > 0)
8708 m_visible = json[
"visible"].get<bool>();
8711 if (json.count(
"x") > 0)
8712 m_x = json[
"x"].get<int>();
8715 if (json.count(
"y") > 0)
8716 m_y = json[
"y"].get<int>();
8719 if (json.count(
"repeatx") > 0) m_repeatX = json[
"repeatx"].get<bool>();
8720 if (json.count(
"repeaty") > 0) m_repeatY = json[
"repeaty"].get<bool>();
8723 if (json.count(
"parallaxx") > 0) parallax.x = json[
"parallaxx"].get<
float>();
8724 if (json.count(
"parallaxy") > 0) parallax.y = json[
"parallaxy"].get<
float>();
8726 m_parallax = parallax;
8729 if (json.count(
"data") > 0) {
8730 if (json[
"data"].isArray()) {
8731 auto &array = json.
array(
"data");
8732 std::for_each(array.begin(), array.end(), [&](std::unique_ptr<IJson> &item) { m_data.push_back(item->get<uint32_t>()); });
8734 m_base64Data = json[
"data"].get<std::string>();
8740 if (json.count(
"chunks") > 0 && json[
"chunks"].isArray()) {
8741 auto &chunks = json.
array(
"chunks");
8742 std::for_each(chunks.begin(), chunks.end(), [&](std::unique_ptr<IJson> &item) { m_chunks.emplace_back(*item); });
8744 if (json.count(
"layers") > 0 && json[
"layers"].isArray()) {
8745 auto &layers = json.
array(
"layers");
8746 std::for_each(layers.begin(), layers.end(), [&](std::unique_ptr<IJson> &item) { m_layers.emplace_back(*item, m_map); });
8748 if (json.count(
"objects") > 0 && json[
"objects"].isArray()) {
8749 auto &objects = json.
array(
"objects");
8750 std::for_each(objects.begin(), objects.end(), [&](std::unique_ptr<IJson> &item) { m_objects.emplace_back(*item, m_map); });
8752 if (json.count(
"properties") > 0 && json[
"properties"].isArray()) {
8753 auto &properties = json.
array(
"properties");
8754 tson::Project *project = (m_map !=
nullptr) ? m_map->getProject() :
nullptr;
8755 std::for_each(properties.begin(), properties.end(), [&](std::unique_ptr<IJson> &item) { m_properties.add(*item, project); });
8765 if (m_class ==
nullptr) {
8766 TiledClass *baseClass = (m_map !=
nullptr && m_map->getProject() !=
nullptr) ? m_map->getProject()->getClass(m_classType) :
nullptr;
8767 if (baseClass !=
nullptr) {
8768 m_class = std::make_shared<TiledClass>(*baseClass);
8769 m_class->update(m_properties);
8772 return (m_class !=
nullptr) ? m_class.get() :
nullptr;
8782 if (m_class ==
nullptr) {
8783 TiledClass *baseClass = (m_map !=
nullptr && m_map->getProject() !=
nullptr) ? m_map->getProject()->getClass(m_classType) :
nullptr;
8784 if (baseClass !=
nullptr) {
8785 m_class = std::make_shared<TiledClass>(*baseClass);
8786 m_class->update(m_properties);
8789 return (m_class !=
nullptr) ? m_class.get() :
nullptr;
8796 if (m_class ==
nullptr) {
8797 TiledClass *baseClass = (m_map !=
nullptr && m_map->getProject() !=
nullptr) ? m_map->getProject()->getClass(m_classType) :
nullptr;
8798 if (baseClass !=
nullptr) {
8799 m_class = std::make_shared<TiledClass>(*baseClass);
8800 m_class->update(m_properties);
8803 return (m_class !=
nullptr) ? m_class.get() :
nullptr;
8813 if (m_class ==
nullptr) {
8814 TiledClass *baseClass = (m_map !=
nullptr && m_map->getProject() !=
nullptr) ? m_map->getProject()->getClass(m_type) :
nullptr;
8815 if (baseClass !=
nullptr) {
8816 m_class = std::make_shared<TiledClass>(*baseClass);
8817 m_class->update(m_properties);
8820 return (m_class !=
nullptr) ? m_class.get() :
nullptr;
8835 std::for_each(m_mapData.begin(), m_mapData.end(), [&](
const tson::WorldMapData &data) {
8836 if (fs::exists(data.path)) {
8837 std::unique_ptr<tson::Map> map = parser->parse(data.path);
8838 m_maps.push_back(std::move(map));
8842 return m_maps.size();
8847void tson::Property::setValueByType(IJson &json)
8850 case Type::Color: m_value = Colori(json.get<std::string>());
break;
8852 case Type::File: m_value = fs::path(json.get<std::string>());
break;
8855 if (!m_propertyType.empty()) {
8856 m_type = Type::Enum;
8857 tson::EnumDefinition *def = (m_project !=
nullptr) ? m_project->getEnumDefinition(m_propertyType) :
nullptr;
8858 if (def !=
nullptr) {
8859 uint32_t v = json.get<uint32_t>();
8864 m_value = json.get<
int>();
8868 case Type::Boolean: m_value = json.get<
bool>();
break;
8870 case Type::Float: m_value = json.get<
float>();
break;
8873 if (!m_propertyType.empty()) {
8874 m_type = Type::Enum;
8875 tson::EnumDefinition *def = (m_project !=
nullptr) ? m_project->getEnumDefinition(m_propertyType) :
nullptr;
8876 if (def !=
nullptr) {
8877 std::string v = json.get<std::string>();
8882 setStrValue(json.get<std::string>());
8887 tson::TiledClass *baseClass = (m_project !=
nullptr) ? m_project->getClass(m_propertyType) :
nullptr;
8888 if (baseClass !=
nullptr) {
8895 case Type::Object: m_value = json.get<uint32_t>();
break;
8896 default: setStrValue(json.get<std::string>());
break;
Definition: Tileson.hpp:450
Definition: Tileson.hpp:434
Definition: Tileson.hpp:408
Definition: Tileson.hpp:89
Definition: Tileson.hpp:421
Definition: Tileson.hpp:472
Definition: Tileson.hpp:461
Definition: Tileson.hpp:441
Definition: Tileson.hpp:232
Definition: Tileson.hpp:388
Definition: Tileson.hpp:5606
const tson::Frame * getCurrentFrame() const
Definition: Tileson.hpp:5652
void update(float timeDeltaMs)
Definition: Tileson.hpp:5666
void reset()
Definition: Tileson.hpp:5642
bool any() const
Definition: Tileson.hpp:5717
Definition: Tileson.hpp:1315
std::string decompressFile(const fs::path &path) override
Definition: Tileson.hpp:1399
std::string decompress(const std::string_view &s) override
Definition: Tileson.hpp:1335
const std::string & name() const override
Definition: Tileson.hpp:1330
Definition: Tileson.hpp:2924
const Vector2i & getSize() const
Definition: Tileson.hpp:3010
const std::string & getBase64Data() const
Definition: Tileson.hpp:3001
const std::vector< int > & getData() const
Definition: Tileson.hpp:2992
std::string m_base64Data
Definition: Tileson.hpp:2941
tson::Vector2i m_size
Definition: Tileson.hpp:2942
bool parse(IJson &json)
Definition: Tileson.hpp:2963
const Vector2i & getPosition() const
Definition: Tileson.hpp:3019
tson::Vector2i m_position
Definition: Tileson.hpp:2943
Definition: Tileson.hpp:1648
Color< uint8_t > asInt()
Definition: Tileson.hpp:1737
Color< float > asFloat()
Definition: Tileson.hpp:1722
Color(T red, T green, T blue, T alpha)
Definition: Tileson.hpp:1756
T a
Definition: Tileson.hpp:1679
T b
Definition: Tileson.hpp:1677
T g
Definition: Tileson.hpp:1675
T r
Definition: Tileson.hpp:1673
Definition: Tileson.hpp:1498
bool contains(std::string_view name) const
Definition: Tileson.hpp:1527
void remove(std::string_view name)
Definition: Tileson.hpp:1538
bool empty() const
Definition: Tileson.hpp:1565
IDecompressor< std::string_view, std::string > * get(std::string_view name)
Definition: Tileson.hpp:1554
void clear()
Definition: Tileson.hpp:1573
Definition: Tileson.hpp:7429
Definition: Tileson.hpp:7566
bool hasFlagValue(uint32_t flag) const
Definition: Tileson.hpp:7613
bool hasAnyFlagValue(uint32_t flags) const
Definition: Tileson.hpp:7626
bool containsValueName(const std::string &value) const
Definition: Tileson.hpp:7690
bool hasFlag(T flags) const
Definition: Tileson.hpp:7657
bool hasAnyFlag(T flags) const
Definition: Tileson.hpp:7670
std::string getValueName() const
Definition: Tileson.hpp:7644
Definition: Tileson.hpp:4262
uint32_t tileId
Definition: Tileson.hpp:4271
uint32_t id
Definition: Tileson.hpp:4269
Definition: Tileson.hpp:5519
int getDuration() const
Definition: Tileson.hpp:5579
uint32_t m_tileId
Definition: Tileson.hpp:5534
uint32_t getTileId() const
Definition: Tileson.hpp:5588
bool parse(IJson &json)
Definition: Tileson.hpp:5559
Definition: Tileson.hpp:6241
bool parse(IJson &json)
Definition: Tileson.hpp:6273
const Vector2i & getSize() const
Definition: Tileson.hpp:6300
tson::Vector2i m_size
Definition: Tileson.hpp:6255
const std::string & getOrientation() const
Definition: Tileson.hpp:6291
Definition: Tileson.hpp:1264
virtual TOut decompressFile(const fs::path &path)=0
virtual TOut decompress(const TIn &input)=0
virtual const std::string & name() const =0
virtual TOut decompress(const void *data, size_t size)=0
virtual ~IDecompressor()=default
Definition: Tileson.hpp:1856
virtual fs::path directory() const =0
virtual size_t size() const =0
virtual std::vector< std::unique_ptr< IJson > > array()=0
Definition: Tileson.hpp:2591
fs::path directory() const override
Definition: Tileson.hpp:2776
std::vector< std::unique_ptr< IJson > > array() override
Definition: Tileson.hpp:2628
size_t size() const override
Definition: Tileson.hpp:2659
Definition: Tileson.hpp:4282
std::vector< tson::Object > getObjectsByType(tson::ObjectType type)
Definition: Tileson.hpp:4473
const std::map< std::tuple< int, int >, tson::Tile * > & getTileData() const
Definition: Tileson.hpp:4746
std::vector< tson::Layer > & getLayers()
Definition: Tileson.hpp:4684
void createTileData(const Vector2i &mapSize, bool isInfiniteMap)
Definition: Tileson.hpp:4784
bool m_visible
Definition: Tileson.hpp:4398
const std::string & getBase64Data() const
Definition: Tileson.hpp:4548
PropertyCollection & getProperties()
Definition: Tileson.hpp:4702
tson::Object * firstObj(const std::string &name)
Definition: Tileson.hpp:4487
void assignTileMap(std::map< uint32_t, tson::Tile * > *tileMap)
Definition: Tileson.hpp:4731
int m_id
Definition: Tileson.hpp:4384
int getId() const
Definition: Tileson.hpp:4575
bool hasRepeatY() const
Definition: Tileson.hpp:4869
std::string m_compression
Definition: Tileson.hpp:4377
tson::Vector2i m_size
Definition: Tileson.hpp:4393
tson::Object * getObj(int id)
Definition: Tileson.hpp:4500
std::string m_base64Data
Definition: Tileson.hpp:4380
void queueFlaggedTile(size_t x, size_t y, uint32_t id)
Definition: Tileson.hpp:4446
const std::string & getName() const
Definition: Tileson.hpp:4593
bool parse(IJson &json, tson::Map *map)
Definition: Tileson.hpp:8679
LayerType getType() const
Definition: Tileson.hpp:4722
std::string m_image
Definition: Tileson.hpp:4385
std::vector< uint32_t > m_data
Definition: Tileson.hpp:4378
bool m_repeatY
Definition: Tileson.hpp:4404
tson::Vector2f m_parallax
Definition: Tileson.hpp:4401
LayerType m_type
Definition: Tileson.hpp:4397
const Vector2i & getSize() const
Definition: Tileson.hpp:4621
T get(const std::string &name)
Definition: Tileson.hpp:4431
std::string m_name
Definition: Tileson.hpp:4387
std::vector< tson::Layer > m_layers
Definition: Tileson.hpp:4386
void setTypeByString()
Definition: Tileson.hpp:4512
std::string m_typeStr
Definition: Tileson.hpp:4396
std::vector< tson::Chunk > & getChunks()
Definition: Tileson.hpp:4675
tson::Map * getMap() const
Definition: Tileson.hpp:4772
std::string m_drawOrder
Definition: Tileson.hpp:4382
tson::Vector2f m_offset
Definition: Tileson.hpp:4389
std::string m_encoding
Definition: Tileson.hpp:4383
const std::string & getEncoding() const
Definition: Tileson.hpp:4566
float getOpacity() const
Definition: Tileson.hpp:4611
const std::vector< uint32_t > & getData() const
Definition: Tileson.hpp:4539
const std::string & getCompression() const
Definition: Tileson.hpp:4530
bool hasRepeatX() const
Definition: Tileson.hpp:4859
tson::Map * m_map
Definition: Tileson.hpp:4415
int m_y
Definition: Tileson.hpp:4400
const Vector2f & getOffset() const
Definition: Tileson.hpp:4602
tson::Property * getProp(const std::string &name)
Definition: Tileson.hpp:4712
int m_x
Definition: Tileson.hpp:4399
bool isVisible() const
Definition: Tileson.hpp:4648
bool m_repeatX
Definition: Tileson.hpp:4403
const std::string & getTypeStr() const
Definition: Tileson.hpp:4639
const Colori & getTransparentColor() const
Definition: Tileson.hpp:4630
std::shared_ptr< tson::TiledClass > m_class
Definition: Tileson.hpp:4421
std::map< uint32_t, tson::Tile * > * m_tileMap
Definition: Tileson.hpp:4406
tson::PropertyCollection m_properties
Definition: Tileson.hpp:4392
const Colori & getTintColor() const
Definition: Tileson.hpp:4839
const std::string & getImage() const
Definition: Tileson.hpp:4584
const Vector2f & getParallax() const
Definition: Tileson.hpp:4849
std::vector< tson::Object > & getObjects()
Definition: Tileson.hpp:4693
float m_opacity
Definition: Tileson.hpp:4391
tson::Colori m_tintColor
Definition: Tileson.hpp:4410
std::vector< tson::Object > m_objects
Definition: Tileson.hpp:4388
void decompressData()
Definition: Tileson.hpp:8650
int getX() const
Definition: Tileson.hpp:4657
const std::string & getDrawOrder() const
Definition: Tileson.hpp:4557
std::map< std::tuple< int, int >, tson::TileObject > m_tileObjects
Definition: Tileson.hpp:4416
std::vector< tson::Object > getObjectsByName(const std::string &name)
Definition: Tileson.hpp:4459
int getY() const
Definition: Tileson.hpp:4666
tson::Colori m_transparentColor
Definition: Tileson.hpp:4395
Definition: Tileson.hpp:6889
Vector2i m_tileSize
Definition: Tileson.hpp:6976
const Vector2i & getSize() const
Definition: Tileson.hpp:7170
std::string m_staggerAxis
Definition: Tileson.hpp:6973
std::string m_renderOrder
Definition: Tileson.hpp:6972
std::string m_type
Definition: Tileson.hpp:6978
int m_nextObjectId
Definition: Tileson.hpp:6969
tson::Vector2f m_parallaxOrigin
Definition: Tileson.hpp:6979
std::string m_tiledVersion
Definition: Tileson.hpp:6975
Vector2i m_size
Definition: Tileson.hpp:6964
const std::string & getType() const
Definition: Tileson.hpp:7269
std::vector< tson::Layer > & getLayers()
Definition: Tileson.hpp:7287
void processData()
Definition: Tileson.hpp:7126
const Vector2i & getTileSize() const
Definition: Tileson.hpp:7260
std::string m_orientation
Definition: Tileson.hpp:6970
const std::string & getRenderOrder() const
Definition: Tileson.hpp:7224
const std::string & getOrientation() const
Definition: Tileson.hpp:7215
int getCompressionLevel() const
Definition: Tileson.hpp:7391
std::vector< tson::Tileset > & getTilesets()
Definition: Tileson.hpp:7305
const std::string & getStaggerAxis() const
Definition: Tileson.hpp:7233
tson::PropertyCollection m_properties
Definition: Tileson.hpp:6971
Tileset * getTileset(const std::string &name)
Definition: Tileson.hpp:7324
const std::string & getStaggerIndex() const
Definition: Tileson.hpp:7242
std::shared_ptr< tson::TiledClass > m_class
Definition: Tileson.hpp:6996
std::vector< tson::Tileset > m_tilesets
Definition: Tileson.hpp:6977
T get(const std::string &name)
Definition: Tileson.hpp:7006
tson::Property * getProp(const std::string &name)
Definition: Tileson.hpp:7356
const Vector2f & getParallaxOrigin() const
Definition: Tileson.hpp:7401
int getNextObjectId() const
Definition: Tileson.hpp:7206
int m_nextLayerId
Definition: Tileson.hpp:6968
std::vector< tson::Layer > m_layers
Definition: Tileson.hpp:6967
int m_hexsideLength
Definition: Tileson.hpp:6965
bool parse(IJson &json, tson::DecompressorContainer *decompressors, tson::Project *project)
Definition: Tileson.hpp:7034
Tileset * getTilesetByGid(uint32_t gid)
Definition: Tileson.hpp:7338
ParseStatus m_status
Definition: Tileson.hpp:6982
int m_compressionLevel
Definition: Tileson.hpp:6988
std::string m_staggerIndex
Definition: Tileson.hpp:6974
PropertyCollection & getProperties()
Definition: Tileson.hpp:7296
const std::string & getTiledVersion() const
Definition: Tileson.hpp:7251
const std::map< uint32_t, tson::Tile * > & getTileMap() const
Definition: Tileson.hpp:7376
tson::DecompressorContainer * m_decompressors
Definition: Tileson.hpp:6991
const Colori & getBackgroundColor() const
Definition: Tileson.hpp:7161
std::string m_classType
Definition: Tileson.hpp:6995
int getNextLayerId() const
Definition: Tileson.hpp:7197
bool createTilesetData(IJson &json)
Definition: Tileson.hpp:7103
tson::TiledClass * getClass()
Definition: Tileson.hpp:8513
int getHexsideLength() const
Definition: Tileson.hpp:7179
bool m_isInfinite
Definition: Tileson.hpp:6966
bool isInfinite() const
Definition: Tileson.hpp:7188
Definition: Tileson.hpp:1601
Definition: Tileson.hpp:1612
Definition: Tileson.hpp:3709
const std::string & getTemplate() const
Definition: Tileson.hpp:4023
const std::string & getClassType() const
Definition: Tileson.hpp:4043
std::string m_type
Definition: Tileson.hpp:3791
tson::TileFlipFlags m_flipFlags
Definition: Tileson.hpp:3796
bool hasFlipFlags(TileFlipFlags flags)
Definition: Tileson.hpp:4132
T get(const std::string &name)
Definition: Tileson.hpp:3809
const std::string & getName() const
Definition: Tileson.hpp:3996
TileFlipFlags getFlipFlags() const
Definition: Tileson.hpp:4119
const std::vector< tson::Vector2i > & getPolygons() const
Definition: Tileson.hpp:4071
float m_rotation
Definition: Tileson.hpp:3788
int m_id
Definition: Tileson.hpp:3782
tson::Vector2i m_position
Definition: Tileson.hpp:3793
tson::Property * getProp(const std::string &name)
Definition: Tileson.hpp:4109
const std::string & getType() const
Definition: Tileson.hpp:4033
std::string m_name
Definition: Tileson.hpp:3783
uint32_t m_gid
Definition: Tileson.hpp:3780
float getRotation() const
Definition: Tileson.hpp:4014
const std::vector< tson::Vector2i > & getPolylines() const
Definition: Tileson.hpp:4081
const Vector2i & getPosition() const
Definition: Tileson.hpp:4061
bool m_ellipse
Definition: Tileson.hpp:3779
bool parse(IJson &json, tson::Map *map)
Definition: Tileson.hpp:3830
std::string m_template
Definition: Tileson.hpp:3789
tson::Text m_text
Definition: Tileson.hpp:3790
const Vector2i & getSize() const
Definition: Tileson.hpp:3978
std::vector< tson::Vector2i > m_polyline
Definition: Tileson.hpp:3786
ObjectType getObjectType() const
Definition: Tileson.hpp:3951
bool isVisible() const
Definition: Tileson.hpp:4052
uint32_t getGid() const
Definition: Tileson.hpp:3969
tson::TiledClass * getClass()
Definition: Tileson.hpp:8811
tson::PropertyCollection m_properties
Definition: Tileson.hpp:3787
tson::Map * m_map
Definition: Tileson.hpp:3798
std::vector< tson::Vector2i > m_polygon
Definition: Tileson.hpp:3785
const Text & getText() const
Definition: Tileson.hpp:4099
bool isEllipse() const
Definition: Tileson.hpp:3960
bool m_point
Definition: Tileson.hpp:3784
int getId() const
Definition: Tileson.hpp:3987
bool m_visible
Definition: Tileson.hpp:3792
tson::Vector2i m_size
Definition: Tileson.hpp:3781
PropertyCollection & getProperties()
Definition: Tileson.hpp:4090
void setObjectTypeByJson(IJson &json)
Definition: Tileson.hpp:3925
bool isPoint() const
Definition: Tileson.hpp:4005
Definition: Tileson.hpp:8225
Definition: Tileson.hpp:8129
const World & getWorld() const
Definition: Tileson.hpp:8207
Definition: Tileson.hpp:8245
void parse()
Definition: Tileson.hpp:8359
Definition: Tileson.hpp:8033
Definition: Tileson.hpp:3491
void setProperty(const std::string &name, const tson::Property &value)
Definition: Tileson.hpp:3574
std::vector< Property * > get()
Definition: Tileson.hpp:3603
void setValue(const std::string &name, const std::any &value)
Definition: Tileson.hpp:3564
Definition: Tileson.hpp:3316
std::string getValueTypeInfo()
Definition: Tileson.hpp:3446
const std::type_info & getValueType() const
Definition: Tileson.hpp:3433
void setStrValue(const std::string &value)
Definition: Tileson.hpp:3406
Definition: Tileson.hpp:4158
Definition: Tileson.hpp:6120
PropertyCollection & getProperties()
Definition: Tileson.hpp:6208
tson::Property * getProp(const std::string &name)
Definition: Tileson.hpp:6218
int m_tile
Definition: Tileson.hpp:6141
T get(const std::string &name)
Definition: Tileson.hpp:6152
tson::PropertyCollection m_properties
Definition: Tileson.hpp:6142
const std::string & getName() const
Definition: Tileson.hpp:6190
int getTile() const
Definition: Tileson.hpp:6199
Definition: Tileson.hpp:3637
Text(IJson &json)
Definition: Tileson.hpp:3647
Definition: Tileson.hpp:5731
const fs::path & getImage() const
Definition: Tileson.hpp:5935
uint32_t m_gid
Definition: Tileson.hpp:5805
TileFlipFlags getFlipFlags() const
Definition: Tileson.hpp:6068
const Rect & getSubRectangle() const
Definition: Tileson.hpp:6100
tson::Vector2i m_imageSize
Definition: Tileson.hpp:5798
fs::path m_image
Definition: Tileson.hpp:5796
tson::Map * m_map
Definition: Tileson.hpp:5807
const tson::Vector2f getPosition(const std::tuple< int, int > &tileDataPos)
Definition: Tileson.hpp:8586
uint32_t m_id
Definition: Tileson.hpp:5794
const std::string & getType() const
Definition: Tileson.hpp:5954
std::vector< int > m_terrain
Definition: Tileson.hpp:5801
tson::Rect m_subRect
Definition: Tileson.hpp:5809
const std::vector< int > & getTerrain() const
Definition: Tileson.hpp:6000
PropertyCollection & getProperties()
Definition: Tileson.hpp:5991
const tson::Vector2i getTileSize() const
Definition: Tileson.hpp:8532
tson::Property * getProp(const std::string &name)
Definition: Tileson.hpp:6010
bool hasFlipFlags(TileFlipFlags flags)
Definition: Tileson.hpp:6081
const Vector2i & getImageSize() const
Definition: Tileson.hpp:5944
tson::PropertyCollection m_properties
Definition: Tileson.hpp:5800
void performDataCalculations()
Definition: Tileson.hpp:8558
bool parse(IJson &json, tson::Tileset *tileset, tson::Map *map)
Definition: Tileson.hpp:5872
Layer & getObjectgroup()
Definition: Tileson.hpp:5982
tson::Rect m_drawingRect
Definition: Tileson.hpp:5808
const std::string & getClassType() const
Definition: Tileson.hpp:5964
tson::Layer m_objectgroup
Definition: Tileson.hpp:5799
tson::Tileset * getTileset() const
Definition: Tileson.hpp:6021
const tson::Vector2i getPositionInTileUnits(const std::tuple< int, int > &tileDataPos)
Definition: Tileson.hpp:6054
tson::Animation & getAnimation()
Definition: Tileson.hpp:5973
std::string m_type
Definition: Tileson.hpp:5802
void addTilesetAndPerformCalculations(tson::Tileset *tileset)
Definition: Tileson.hpp:5861
tson::Map * getMap() const
Definition: Tileson.hpp:6030
void manageFlipFlagsByIdThenRemoveFlags(uint32_t &id)
Definition: Tileson.hpp:6059
tson::TileFlipFlags m_flipFlags
Definition: Tileson.hpp:5810
uint32_t getId() const
Definition: Tileson.hpp:5925
tson::Tileset * m_tileset
Definition: Tileson.hpp:5806
tson::TiledClass * getClass()
Definition: Tileson.hpp:8596
T get(const std::string &name)
Definition: Tileson.hpp:5824
const tson::Rect & getDrawingRect() const
Definition: Tileson.hpp:6039
Definition: Tileson.hpp:4198
const Vector2i & getPositionInTileUnits() const
Definition: Tileson.hpp:4234
Tile * getTile()
Definition: Tileson.hpp:4225
void initialize(const std::tuple< int, int > &posInTileUnits, tson::Tile *tile)
Definition: Tileson.hpp:8632
const Vector2f & getPosition() const
Definition: Tileson.hpp:4243
Definition: Tileson.hpp:7717
void update(IJson &json)
Definition: Tileson.hpp:7793
Definition: Tileson.hpp:6314
const std::string & getType() const
Definition: Tileson.hpp:6660
const std::vector< tson::Terrain > & getTerrains() const
Definition: Tileson.hpp:6706
int m_tileCount
Definition: Tileson.hpp:6400
const Vector2i & getImageSize() const
Definition: Tileson.hpp:6597
FillMode m_fillMode
Definition: Tileson.hpp:6428
tson::Vector2i m_tileSize
Definition: Tileson.hpp:6401
static tson::ObjectAlignment StringToAlignment(std::string_view str)
Definition: Tileson.hpp:6799
Transformations m_transformations
Definition: Tileson.hpp:6421
fs::path m_path
Definition: Tileson.hpp:6420
std::string m_type
Definition: Tileson.hpp:6403
std::string m_classType
Definition: Tileson.hpp:6432
const fs::path & getImage() const
Definition: Tileson.hpp:6670
int getSpacing() const
Definition: Tileson.hpp:6624
const Grid & getGrid() const
Definition: Tileson.hpp:6725
const Vector2i & getTileOffset() const
Definition: Tileson.hpp:6715
int getMargin() const
Definition: Tileson.hpp:6606
tson::Map * m_map
Definition: Tileson.hpp:6416
tson::Vector2i m_tileOffset
Definition: Tileson.hpp:6410
const fs::path & getImagePath() const
Definition: Tileson.hpp:6588
T get(const std::string &name)
Definition: Tileson.hpp:6443
tson::Colori m_transparentColor
Definition: Tileson.hpp:6402
std::vector< tson::Terrain > m_terrains
Definition: Tileson.hpp:6409
std::string m_name
Definition: Tileson.hpp:6398
const Vector2i & getTileSize() const
Definition: Tileson.hpp:6642
tson::Vector2i m_imageSize
Definition: Tileson.hpp:6396
tson::Property * getProp(const std::string &name)
Definition: Tileson.hpp:6762
tson::Map * getMap() const
Definition: Tileson.hpp:6789
const Transformations & getTransformations() const
Definition: Tileson.hpp:6865
std::vector< tson::Tile > m_tiles
Definition: Tileson.hpp:6405
int getFirstgid() const
Definition: Tileson.hpp:6578
tson::Grid m_grid
Definition: Tileson.hpp:6411
fs::path m_image
Definition: Tileson.hpp:6394
int getTileCount() const
Definition: Tileson.hpp:6633
TileRenderSize m_tileRenderSize
Definition: Tileson.hpp:6426
void generateMissingTiles()
Definition: Tileson.hpp:6772
tson::Tile * getTile(uint32_t id)
Definition: Tileson.hpp:6736
tson::PropertyCollection m_properties
Definition: Tileson.hpp:6407
std::vector< tson::WangSet > m_wangsets
Definition: Tileson.hpp:6406
fs::path m_source
Definition: Tileson.hpp:6419
PropertyCollection & getProperties()
Definition: Tileson.hpp:6697
const std::vector< tson::WangSet > & getWangsets() const
Definition: Tileson.hpp:6688
int getColumns() const
Definition: Tileson.hpp:6569
int m_spacing
Definition: Tileson.hpp:6399
int m_firstgid
Definition: Tileson.hpp:6392
const Colori & getTransparentColor() const
Definition: Tileson.hpp:6651
tson::ObjectAlignment m_objectAlignment
Definition: Tileson.hpp:6415
const std::string & getName() const
Definition: Tileson.hpp:6615
std::vector< tson::Tile > & getTiles()
Definition: Tileson.hpp:6679
std::shared_ptr< tson::TiledClass > m_class
Definition: Tileson.hpp:6433
tson::Terrain * getTerrain(const std::string &name)
Definition: Tileson.hpp:6749
int m_margin
Definition: Tileson.hpp:6397
tson::WangSet * getWangset(const std::string &name)
Definition: Tileson.hpp:6850
tson::Vector2i getMarginSpacingOffset(const tson::Vector2i &posInTileUnits)
Definition: Tileson.hpp:6837
Definition: Tileson.hpp:8371
Tileson(std::unique_ptr< tson::IJson > jsonParser=std::make_unique< tson::Json11 >(), bool includeBase64Decoder=true)
Definition: Tileson.hpp:8401
tson::DecompressorContainer * decompressors()
Definition: Tileson.hpp:8483
std::unique_ptr< tson::Map > parseJson()
Definition: Tileson.hpp:8467
std::unique_ptr< tson::Map > parse(const fs::path &path, std::unique_ptr< IDecompressor< std::vector< uint8_t >, std::vector< uint8_t > > > decompressor=nullptr)
Definition: Tileson.hpp:8417
Definition: Tileson.hpp:1799
Vector2(T xPos, T yPos)
Definition: Tileson.hpp:1819
Definition: Tileson.hpp:4999
tson::Property * getProp(const std::string &name)
Definition: Tileson.hpp:5137
float getProbability() const
Definition: Tileson.hpp:5096
T get(const std::string &name)
Definition: Tileson.hpp:5127
std::shared_ptr< tson::TiledClass > m_class
Definition: Tileson.hpp:5034
tson::Map * m_map
Definition: Tileson.hpp:5032
const std::string & getName() const
Definition: Tileson.hpp:5087
float m_probability
Definition: Tileson.hpp:5027
int m_tile
Definition: Tileson.hpp:5028
std::string m_name
Definition: Tileson.hpp:5026
tson::Colori m_color
Definition: Tileson.hpp:5025
PropertyCollection & getProperties()
Definition: Tileson.hpp:5115
const Colori & getColor() const
Definition: Tileson.hpp:5078
int getTile() const
Definition: Tileson.hpp:5105
tson::PropertyCollection m_properties
Definition: Tileson.hpp:5031
Definition: Tileson.hpp:5277
const std::vector< tson::WangColor > & getColors() const
Definition: Tileson.hpp:5468
int getTile() const
Definition: Tileson.hpp:5411
tson::Map * m_map
Definition: Tileson.hpp:5321
bool parseTiled15Props(IJson &json)
Definition: Tileson.hpp:5389
std::vector< tson::WangColor > m_edgeColors
Definition: Tileson.hpp:5315
std::vector< tson::WangTile > m_wangTiles
Definition: Tileson.hpp:5313
std::vector< tson::WangColor > m_colors
Definition: Tileson.hpp:5319
PropertyCollection & getProperties()
Definition: Tileson.hpp:5447
std::vector< tson::WangColor > m_cornerColors
Definition: Tileson.hpp:5314
const std::vector< tson::WangTile > & getWangTiles() const
Definition: Tileson.hpp:5420
const std::string & getName() const
Definition: Tileson.hpp:5402
const std::vector< tson::WangColor > & getEdgeColors() const
Definition: Tileson.hpp:5438
tson::WangColor * getColor(const std::string &name)
Definition: Tileson.hpp:5480
std::shared_ptr< tson::TiledClass > m_class
Definition: Tileson.hpp:5323
int m_tile
Definition: Tileson.hpp:5312
tson::PropertyCollection m_properties
Definition: Tileson.hpp:5316
const std::vector< tson::WangColor > & getCornerColors() const
Definition: Tileson.hpp:5429
tson::Property * getProp(const std::string &name)
Definition: Tileson.hpp:5457
T get(const std::string &name)
Definition: Tileson.hpp:5333
Definition: Tileson.hpp:5164
std::vector< uint32_t > m_wangId
Definition: Tileson.hpp:5187
bool hasHFlip() const
Definition: Tileson.hpp:5238
uint32_t m_tileid
Definition: Tileson.hpp:5185
bool hasDFlip() const
Definition: Tileson.hpp:5227
bool m_hflip
Definition: Tileson.hpp:5184
uint32_t getTileid() const
Definition: Tileson.hpp:5247
bool parse(IJson &json)
Definition: Tileson.hpp:5201
bool hasVFlip() const
Definition: Tileson.hpp:5258
const std::vector< uint32_t > & getWangIds() const
Definition: Tileson.hpp:5267
bool m_vflip
Definition: Tileson.hpp:5186
Definition: Tileson.hpp:7891
const WorldMapData * get(std::string_view filename) const
Definition: Tileson.hpp:8001
std::size_t loadMaps(tson::Tileson *parser)
Definition: Tileson.hpp:8832
const std::vector< std::unique_ptr< tson::Map > > & getMaps() const
Definition: Tileson.hpp:8013
bool contains(std::string_view filename)
Definition: Tileson.hpp:7990
Definition: Tileson.hpp:7851
Definition: Tileson.hpp:278
Definition: Tileson.hpp:480
Definition: Tileson.hpp:684
Definition: Tileson.hpp:3092