Tileson 1.4.0
A helpful json parser for Tiled maps
Loading...
Searching...
No Matches
Tileset.hpp
Go to the documentation of this file.
1//
2// Created by robin on 22.03.2020.
3//
4
5#ifndef TILESON_TILESET_HPP
6#define TILESON_TILESET_HPP
7
8//#include "../external/json.hpp"
9
10#include "../objects/Vector2.hpp"
11#include "../objects/Color.hpp"
12#include "../objects/PropertyCollection.hpp"
13#include "Transformations.hpp"
14#include "WangSet.hpp"
15#include "Tile.hpp"
16#include "Terrain.hpp"
17#include "Grid.hpp"
18#include <functional>
19
20namespace tson
21{
22 class Map;
23 class Tileset
24 {
25 public:
26 inline Tileset() = default;
27 inline explicit Tileset(IJson &json, tson::Map *map);
28 inline bool parse(IJson &json, tson::Map *map);
29
30 [[nodiscard]] inline int getColumns() const;
31 [[nodiscard]] inline int getFirstgid() const;
32
33 [[nodiscard]] inline const fs::path &getImagePath() const;
34 [[nodiscard]] inline const fs::path &getImage() const;
35 [[nodiscard]] inline const Vector2i &getImageSize() const;
36 [[nodiscard]] inline int getMargin() const;
37 [[nodiscard]] inline const std::string &getName() const;
38 [[nodiscard]] inline int getSpacing() const;
39 [[nodiscard]] inline int getTileCount() const;
40 [[nodiscard]] inline const Vector2i &getTileSize() const;
41 [[nodiscard]] inline const Colori &getTransparentColor() const;
42 [[nodiscard]] inline const std::string &getType() const;
43 [[nodiscard]] inline const std::string &getClassType() const;
44 [[nodiscard]] inline tson::TiledClass *getClass();
45 [[nodiscard]] inline std::vector<tson::Tile> &getTiles();
46 [[nodiscard]] inline const std::vector<tson::WangSet> &getWangsets() const;
47 [[nodiscard]] inline PropertyCollection &getProperties();
48 [[nodiscard]] inline const std::vector<tson::Terrain> &getTerrains() const;
49 [[nodiscard]] inline const Vector2i &getTileOffset() const;
50 [[nodiscard]] inline const Grid &getGrid() const;
51 [[nodiscard]] inline TileRenderSize getTileRenderSize() const;
52 [[nodiscard]] inline FillMode getFillMode() const;
53
54 inline tson::Tile * getTile(uint32_t id);
55 inline tson::Terrain * getTerrain(const std::string &name);
56
57 template <typename T>
58 inline T get(const std::string &name);
59 inline tson::Property * getProp(const std::string &name);
60
61 //v1.2.0-stuff
62 [[nodiscard]] inline tson::Map *getMap() const;
63 [[nodiscard]] inline ObjectAlignment getObjectAlignment() const;
64
65 inline static tson::ObjectAlignment StringToAlignment(std::string_view str);
66
67 //v1.3.0
68 inline tson::Vector2i getMarginSpacingOffset(const tson::Vector2i &posInTileUnits);
69 inline tson::WangSet * getWangset(const std::string &name);
70 inline const Transformations &getTransformations() const;
71
72
73 #ifndef TSON_TEST_ENABLED
74 private:
75 #endif
76 inline void generateMissingTiles();
77
78 int m_columns {};
79 int m_firstgid {};
81 fs::path m_image;
83 tson::Vector2i m_imageSize;
84 int m_margin {};
85 std::string m_name;
86 int m_spacing {};
87 int m_tileCount {};
88 tson::Vector2i m_tileSize;
89 tson::Colori m_transparentColor;
90 std::string m_type;
92 std::vector<tson::Tile> m_tiles;
93 std::vector<tson::WangSet> m_wangsets;
94 tson::PropertyCollection m_properties;
96 std::vector<tson::Terrain> m_terrains;
97 tson::Vector2i m_tileOffset;
98 tson::Grid m_grid;
101 //v1.2.0-stuff
103 tson::Map * m_map;
105 //v1.3.0-stuff
106 fs::path m_source {};
107 fs::path m_path {};
108 Transformations m_transformations {};
111 //v1.4.0-stuff
112 TileRenderSize m_tileRenderSize {};
114 FillMode m_fillMode {};
117 std::string m_classType {};
118 std::shared_ptr<tson::TiledClass> m_class {};
119 };
120
127 template<typename T>
128 T tson::Tileset::get(const std::string &name)
129 {
130 return m_properties.getValue<T>(name);
131 }
132}
133
135{
136 parse(json, map);
137}
138
140{
141 m_map = map;
142 bool allFound = true;
143
144 if(json.count("firstgid") > 0) m_firstgid = json["firstgid"].get<int>(); else allFound = false;
145
146 //Tileset is stored in external file if 'source' exists
147 if(json.count("source") > 0)
148 {
149 if(!allFound)
150 return allFound;
151
152 std::string sourceStr = json["source"].get<std::string>();
153 m_source = fs::path(sourceStr);
154 m_path = json.directory() / m_source;
155
156 if(!json.parse(m_path))
157 return false;
158 }
159
160
161 if(json.count("columns") > 0) m_columns = json["columns"].get<int>(); else allFound = false;
162
163 if(json.count("image") > 0) m_image = fs::path(json["image"].get<std::string>()); else allFound = false;
164
165 if(json.count("margin") > 0) m_margin = json["margin"].get<int>(); else allFound = false;
166 if(json.count("name") > 0) m_name = json["name"].get<std::string>(); else allFound = false;
167 if(json.count("spacing") > 0) m_spacing = json["spacing"].get<int>(); else allFound = false;
168 if(json.count("tilecount") > 0) m_tileCount = json["tilecount"].get<int>(); else allFound = false;
169 if(json.count("transparentcolor") > 0) m_transparentColor = tson::Colori(json["transparentcolor"].get<std::string>()); //Optional
170 if(json.count("type") > 0) m_type = json["type"].get<std::string>();
171 if(json.count("grid") > 0) m_grid = tson::Grid(json["grid"]);
172 if(json.count("class") > 0) m_classType = json["class"].get<std::string>(); //Optional
173
174 if(json.count("imagewidth") > 0 && json.count("imageheight") > 0)
175 m_imageSize = {json["imagewidth"].get<int>(), json["imageheight"].get<int>()}; else allFound = false;
176 if(json.count("tilewidth") > 0 && json.count("tileheight") > 0)
177 m_tileSize = {json["tilewidth"].get<int>(), json["tileheight"].get<int>()}; else allFound = false;
178 if(json.count("tileoffset") > 0)
179 m_tileOffset = {json["tileoffset"]["x"].get<int>(), json["tileoffset"]["y"].get<int>()};
180
181 if(json.count("tilerendersize") > 0)
182 {
183 std::string tileRenderStr = json["tilerendersize"].get<std::string>();
184 if(tileRenderStr == "tile") m_tileRenderSize = TileRenderSize::Tile;
185 else if(tileRenderStr == "grid") m_tileRenderSize = TileRenderSize::Grid;
186 }
187
188 if(json.count("fillmode") > 0)
189 {
190 std::string fillmode = json["fillmode"].get<std::string>();
191 if(fillmode == "stretch") m_fillMode = FillMode::Stretch;
192 else if(fillmode == "preserve-aspect-fit") m_fillMode = FillMode::PreserveAspectFit;
193 }
194
195 //More advanced data
196 if(json.count("wangsets") > 0 && json["wangsets"].isArray())
197 {
198 auto &wangsets = json.array("wangsets");
199 std::for_each(wangsets.begin(), wangsets.end(), [&](std::unique_ptr<IJson> &item) { m_wangsets.emplace_back(*item, m_map); });
200 }
201 if(json.count("tiles") > 0 && json["tiles"].isArray())
202 {
203 auto &tiles = json.array("tiles");
204 std::for_each(tiles.begin(), tiles.end(), [&](std::unique_ptr<IJson> &item) { m_tiles.emplace_back(*item, this, m_map); });
205 }
206 if(json.count("terrains") > 0 && json["terrains"].isArray())
207 {
208 auto &terrains = json.array("terrains");
209 std::for_each(terrains.begin(), terrains.end(), [&](std::unique_ptr<IJson> &item) { m_terrains.emplace_back(*item); });
210 }
211
212 if(json.count("properties") > 0 && json["properties"].isArray())
213 {
214 auto &properties = json.array("properties");
215 std::for_each(properties.begin(), properties.end(), [&](std::unique_ptr<IJson> &item) { m_properties.add(*item); });
216 }
217
218 if(json.count("objectalignment") > 0)
219 {
220 std::string alignment = json["objectalignment"].get<std::string>();
221 m_objectAlignment = StringToAlignment(alignment);
222 }
223
224 if(json.count("transformations") > 0)
225 {
226 m_transformations.parse(json["transformations"]);
227 }
228
229 generateMissingTiles();
230
231 return allFound;
232}
233
239{
240 return m_columns;
241}
242
248{
249 return m_firstgid;
250}
251
257const fs::path &tson::Tileset::getImagePath() const { return m_image; }
258
264{
265 return m_imageSize;
266}
267
273{
274 return m_margin;
275}
276
281const std::string &tson::Tileset::getName() const
282{
283 return m_name;
284}
285
291{
292 return m_spacing;
293}
294
300{
301 return m_tileCount;
302}
303
309{
310 return m_tileSize;
311}
312
318{
319 return m_transparentColor;
320}
321
326const std::string &tson::Tileset::getType() const
327{
328 return m_type;
329}
330
336const fs::path &tson::Tileset::getImage() const { return m_image; }
337
342std::vector<tson::Tile> &tson::Tileset::getTiles()
343{
344 return m_tiles;
345}
346
351const std::vector<tson::WangSet> &tson::Tileset::getWangsets() const
352{
353 return m_wangsets;
354}
355
361{
362 return m_properties;
363}
364
369const std::vector<tson::Terrain> &tson::Tileset::getTerrains() const
370{
371 return m_terrains;
372}
373
379{
380 return m_tileOffset;
381}
382
389{
390 return m_grid;
391}
392
400{
401 auto result = std::find_if(m_tiles.begin(), m_tiles.end(), [&](const tson::Tile & item) { return item.getId() == id;});
402 if(result == m_tiles.end())
403 return nullptr;
404
405 return &result.operator*();
406}
407
414{
415 auto result = std::find_if(m_terrains.begin(), m_terrains.end(), [&](const tson::Terrain & item) { return item.getName() == name;});
416 if(result == m_terrains.end())
417 return nullptr;
418
419 return &result.operator*();
420}
421
427tson::Property *tson::Tileset::getProp(const std::string &name)
428{
429 if(m_properties.hasProperty(name))
430 return m_properties.getProperty(name);
431
432 return nullptr;
433}
434
438void tson::Tileset::generateMissingTiles()
439{
440 std::vector<uint32_t> tileIds;
441 for(auto &tile : m_tiles)
442 tileIds.push_back(tile.getId());
443
444 for(uint32_t i = m_firstgid; i < m_firstgid + (uint32_t) m_tileCount; ++i)
445 {
446 if(std::count(tileIds.begin(), tileIds.end(), i) == 0)
447 {
448 m_tiles.emplace_back(Tile(i, this, m_map));
449 }
450 }
451}
452
458{
459 return m_map;
460}
461
468{
469 if(str == "unspecified") return tson::ObjectAlignment::Unspecified;
470 else if(str == "topleft") return tson::ObjectAlignment::TopLeft;
471 else if(str == "top") return tson::ObjectAlignment::Top;
472 else if(str == "topright") return tson::ObjectAlignment::TopRight;
473 else if(str == "left") return tson::ObjectAlignment::Left;
474 else if(str == "center") return tson::ObjectAlignment::Center;
475 else if(str == "right") return tson::ObjectAlignment::Right;
476 else if(str == "bottomleft") return tson::ObjectAlignment::BottomLeft;
477 else if(str == "bottom") return tson::ObjectAlignment::Bottom;
478 else if(str == "bottomright") return tson::ObjectAlignment::BottomRight;
479 else
481}
482
484{
485 return m_objectAlignment;
486}
487
496{
497 if(m_margin == 0 && m_spacing == 0)
498 return {0,0};
499
500 tson::Vector2i offset {(posInTileUnits.x * m_spacing) + m_margin, (posInTileUnits.y * m_spacing) + m_margin};
501 return offset;
502}
503
510{
511 auto wangset = std::find_if(m_wangsets.begin(), m_wangsets.end(), [&](const auto &w) { return w.getName() == name; });
512
513 if(wangset != m_wangsets.end())
514 return &wangset.operator*();
515
516 return nullptr;
517}
518
526{
527 return m_transformations;
528}
529
531{
532 return m_tileRenderSize;
533}
534
536{
537 return m_fillMode;
538}
539
540const std::string &tson::Tileset::getClassType() const
541{
542 return m_classType;
543}
544
545
546#endif //TILESON_TILESET_HPP
Definition Grid.hpp:15
Definition IJson.hpp:11
virtual bool parse(const fs::path &path)=0
T get(std::string_view key)
Definition IJson.hpp:82
virtual bool isArray() const =0
virtual fs::path directory() const =0
virtual size_t count(std::string_view key) const =0
virtual std::vector< std::unique_ptr< IJson > > array()=0
Definition Map.hpp:29
Definition PropertyCollection.hpp:15
Definition Property.hpp:23
Definition Terrain.hpp:14
Definition Tile.hpp:23
Definition TiledClass.hpp:11
Definition Tileset.hpp:24
const std::string & getType() const
Definition Tileset.hpp:326
const std::vector< tson::Terrain > & getTerrains() const
Definition Tileset.hpp:369
const Vector2i & getImageSize() const
Definition Tileset.hpp:263
tson::TiledClass * getClass()
Definition tileson_forward.hpp:183
static tson::ObjectAlignment StringToAlignment(std::string_view str)
Definition Tileset.hpp:467
ObjectAlignment getObjectAlignment() const
Definition Tileset.hpp:483
TileRenderSize getTileRenderSize() const
Definition Tileset.hpp:530
const std::string & getClassType() const
Definition Tileset.hpp:540
const fs::path & getImage() const
Definition Tileset.hpp:336
int getSpacing() const
Definition Tileset.hpp:290
const Grid & getGrid() const
Definition Tileset.hpp:388
const Vector2i & getTileOffset() const
Definition Tileset.hpp:378
int getMargin() const
Definition Tileset.hpp:272
const fs::path & getImagePath() const
Definition Tileset.hpp:257
T get(const std::string &name)
Definition Tileset.hpp:128
FillMode getFillMode() const
Definition Tileset.hpp:535
const Vector2i & getTileSize() const
Definition Tileset.hpp:308
bool parse(IJson &json, tson::Map *map)
Definition Tileset.hpp:139
tson::Property * getProp(const std::string &name)
Definition Tileset.hpp:427
tson::Map * getMap() const
Definition Tileset.hpp:457
const Transformations & getTransformations() const
Definition Tileset.hpp:525
int getFirstgid() const
Definition Tileset.hpp:247
int getTileCount() const
Definition Tileset.hpp:299
tson::Tile * getTile(uint32_t id)
Definition Tileset.hpp:399
PropertyCollection & getProperties()
Definition Tileset.hpp:360
const std::vector< tson::WangSet > & getWangsets() const
Definition Tileset.hpp:351
int getColumns() const
Definition Tileset.hpp:238
const Colori & getTransparentColor() const
Definition Tileset.hpp:317
Tileset()=default
const std::string & getName() const
Definition Tileset.hpp:281
std::vector< tson::Tile > & getTiles()
Definition Tileset.hpp:342
tson::Terrain * getTerrain(const std::string &name)
Definition Tileset.hpp:413
tson::WangSet * getWangset(const std::string &name)
Definition Tileset.hpp:509
tson::Vector2i getMarginSpacingOffset(const tson::Vector2i &posInTileUnits)
Definition Tileset.hpp:495
Definition Transformations.hpp:11
T y
Definition Vector2.hpp:22
T x
Definition Vector2.hpp:21
Definition WangSet.hpp:16
Definition Base64.hpp:12
TileRenderSize
Definition Enums.hpp:119
FillMode
Definition Enums.hpp:129
ObjectAlignment
Definition Enums.hpp:88