Tileson  1.3.0
A helpful json parser for Tiled maps
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 
20 namespace 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 
36  [[nodiscard]] inline const Vector2i &getImageSize() const;
37  [[nodiscard]] inline int getMargin() const;
38  [[nodiscard]] inline const std::string &getName() const;
39  [[nodiscard]] inline int getSpacing() const;
40  [[nodiscard]] inline int getTileCount() const;
41  [[nodiscard]] inline const Vector2i &getTileSize() const;
42  [[nodiscard]] inline const Colori &getTransparentColor() const;
43 
44  [[nodiscard]] inline const std::string &getType() const;
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 
52  inline tson::Tile * getTile(uint32_t id);
53  inline tson::Terrain * getTerrain(const std::string &name);
54 
55  template <typename T>
56  inline T get(const std::string &name);
57  inline tson::Property * getProp(const std::string &name);
58 
59  //v1.2.0-stuff
60  [[nodiscard]] inline tson::Map *getMap() const;
61  [[nodiscard]] inline ObjectAlignment getObjectAlignment() const;
62 
63  inline static tson::ObjectAlignment StringToAlignment(std::string_view str);
64 
65  //v1.3.0
66  inline tson::Vector2i getMarginSpacingOffset(const tson::Vector2i &posInTileUnits);
67  inline tson::WangSet * getWangset(const std::string &name);
68  inline const Transformations &getTransformations() const;
69 
70 
71  #ifndef TSON_TEST_ENABLED
72  private:
73  #endif
74  inline void generateMissingTiles();
75 
76  int m_columns {};
77  int m_firstgid {};
79  fs::path m_image;
81  tson::Vector2i m_imageSize;
82  int m_margin {};
83  std::string m_name;
84  int m_spacing {};
85  int m_tileCount {};
86  tson::Vector2i m_tileSize;
87  tson::Colori m_transparentColor;
88  std::string m_type;
90  std::vector<tson::Tile> m_tiles;
91  std::vector<tson::WangSet> m_wangsets;
92  tson::PropertyCollection m_properties;
94  std::vector<tson::Terrain> m_terrains;
95  tson::Vector2i m_tileOffset;
96  tson::Grid m_grid;
99  //v1.2.0-stuff
101  tson::Map * m_map;
103  //v1.3.0-stuff
104  fs::path m_source {};
105  fs::path m_path {};
106  Transformations m_transformations {};
108  };
109 
116  template<typename T>
117  T tson::Tileset::get(const std::string &name)
118  {
119  return m_properties.getValue<T>(name);
120  }
121 }
122 
124 {
125  parse(json, map);
126 }
127 
129 {
130  m_map = map;
131  bool allFound = true;
132 
133  if(json.count("firstgid") > 0) m_firstgid = json["firstgid"].get<int>(); else allFound = false;
134 
135  //Tileset is stored in external file if 'source' exists
136  if(json.count("source") > 0)
137  {
138  if(!allFound)
139  return allFound;
140 
141  std::string sourceStr = json["source"].get<std::string>();
142  m_source = fs::path(sourceStr);
143  m_path = json.directory() / m_source;
144 
145  if(!json.parse(m_path))
146  return false;
147  }
148 
149 
150  if(json.count("columns") > 0) m_columns = json["columns"].get<int>(); else allFound = false;
151 
152  if(json.count("image") > 0) m_image = fs::path(json["image"].get<std::string>()); else allFound = false;
153 
154  if(json.count("margin") > 0) m_margin = json["margin"].get<int>(); else allFound = false;
155  if(json.count("name") > 0) m_name = json["name"].get<std::string>(); else allFound = false;
156  if(json.count("spacing") > 0) m_spacing = json["spacing"].get<int>(); else allFound = false;
157  if(json.count("tilecount") > 0) m_tileCount = json["tilecount"].get<int>(); else allFound = false;
158  if(json.count("transparentcolor") > 0) m_transparentColor = tson::Colori(json["transparentcolor"].get<std::string>()); //Optional
159  if(json.count("type") > 0) m_type = json["type"].get<std::string>();
160  if(json.count("grid") > 0) m_grid = tson::Grid(json["grid"]);
161 
162  if(json.count("imagewidth") > 0 && json.count("imageheight") > 0)
163  m_imageSize = {json["imagewidth"].get<int>(), json["imageheight"].get<int>()}; else allFound = false;
164  if(json.count("tilewidth") > 0 && json.count("tileheight") > 0)
165  m_tileSize = {json["tilewidth"].get<int>(), json["tileheight"].get<int>()}; else allFound = false;
166  if(json.count("tileoffset") > 0)
167  m_tileOffset = {json["tileoffset"]["x"].get<int>(), json["tileoffset"]["y"].get<int>()};
168 
169  //More advanced data
170  if(json.count("wangsets") > 0 && json["wangsets"].isArray())
171  {
172  auto &wangsets = json.array("wangsets");
173  std::for_each(wangsets.begin(), wangsets.end(), [&](std::unique_ptr<IJson> &item) { m_wangsets.emplace_back(*item); });
174  }
175  if(json.count("tiles") > 0 && json["tiles"].isArray())
176  {
177  auto &tiles = json.array("tiles");
178  std::for_each(tiles.begin(), tiles.end(), [&](std::unique_ptr<IJson> &item) { m_tiles.emplace_back(*item, this, m_map); });
179  }
180  if(json.count("terrains") > 0 && json["terrains"].isArray())
181  {
182  auto &terrains = json.array("terrains");
183  std::for_each(terrains.begin(), terrains.end(), [&](std::unique_ptr<IJson> &item) { m_terrains.emplace_back(*item); });
184  }
185 
186  if(json.count("properties") > 0 && json["properties"].isArray())
187  {
188  auto &properties = json.array("properties");
189  std::for_each(properties.begin(), properties.end(), [&](std::unique_ptr<IJson> &item) { m_properties.add(*item); });
190  }
191 
192  if(json.count("objectalignment") > 0)
193  {
194  std::string alignment = json["objectalignment"].get<std::string>();
195  m_objectAlignment = StringToAlignment(alignment);
196  }
197 
198  if(json.count("transformations") > 0)
199  {
200  m_transformations.parse(json["transformations"]);
201  }
202 
203  generateMissingTiles();
204 
205  return allFound;
206 }
207 
213 {
214  return m_columns;
215 }
216 
222 {
223  return m_firstgid;
224 }
225 
231 const fs::path &tson::Tileset::getImagePath() const { return m_image; }
232 
238 {
239  return m_imageSize;
240 }
241 
247 {
248  return m_margin;
249 }
250 
255 const std::string &tson::Tileset::getName() const
256 {
257  return m_name;
258 }
259 
265 {
266  return m_spacing;
267 }
268 
274 {
275  return m_tileCount;
276 }
277 
283 {
284  return m_tileSize;
285 }
286 
292 {
293  return m_transparentColor;
294 }
295 
300 const std::string &tson::Tileset::getType() const
301 {
302  return m_type;
303 }
304 
310 const fs::path &tson::Tileset::getImage() const { return m_image; }
311 
316 std::vector<tson::Tile> &tson::Tileset::getTiles()
317 {
318  return m_tiles;
319 }
320 
325 const std::vector<tson::WangSet> &tson::Tileset::getWangsets() const
326 {
327  return m_wangsets;
328 }
329 
335 {
336  return m_properties;
337 }
338 
343 const std::vector<tson::Terrain> &tson::Tileset::getTerrains() const
344 {
345  return m_terrains;
346 }
347 
353 {
354  return m_tileOffset;
355 }
356 
363 {
364  return m_grid;
365 }
366 
374 {
375  auto result = std::find_if(m_tiles.begin(), m_tiles.end(), [&](const tson::Tile & item) { return item.getId() == id;});
376  if(result == m_tiles.end())
377  return nullptr;
378 
379  return &result.operator*();
380 }
381 
387 tson::Terrain *tson::Tileset::getTerrain(const std::string &name)
388 {
389  auto result = std::find_if(m_terrains.begin(), m_terrains.end(), [&](const tson::Terrain & item) { return item.getName() == name;});
390  if(result == m_terrains.end())
391  return nullptr;
392 
393  return &result.operator*();
394 }
395 
401 tson::Property *tson::Tileset::getProp(const std::string &name)
402 {
403  if(m_properties.hasProperty(name))
404  return m_properties.getProperty(name);
405 
406  return nullptr;
407 }
408 
412 void tson::Tileset::generateMissingTiles()
413 {
414  std::vector<uint32_t> tileIds;
415  for(auto &tile : m_tiles)
416  tileIds.push_back(tile.getId());
417 
418  for(uint32_t i = m_firstgid; i < m_firstgid + (uint32_t) m_tileCount; ++i)
419  {
420  if(std::count(tileIds.begin(), tileIds.end(), i) == 0)
421  {
422  m_tiles.emplace_back(Tile(i, this, m_map));
423  }
424  }
425 }
426 
432 {
433  return m_map;
434 }
435 
442 {
443  if(str == "unspecified") return tson::ObjectAlignment::Unspecified;
444  else if(str == "topleft") return tson::ObjectAlignment::TopLeft;
445  else if(str == "top") return tson::ObjectAlignment::Top;
446  else if(str == "topright") return tson::ObjectAlignment::TopRight;
447  else if(str == "left") return tson::ObjectAlignment::Left;
448  else if(str == "center") return tson::ObjectAlignment::Center;
449  else if(str == "right") return tson::ObjectAlignment::Right;
450  else if(str == "bottomleft") return tson::ObjectAlignment::BottomLeft;
451  else if(str == "bottom") return tson::ObjectAlignment::Bottom;
452  else if(str == "bottomright") return tson::ObjectAlignment::BottomRight;
453  else
455 }
456 
458 {
459  return m_objectAlignment;
460 }
461 
470 {
471  if(m_margin == 0 && m_spacing == 0)
472  return {0,0};
473 
474  tson::Vector2i offset {(posInTileUnits.x * m_spacing) + m_margin, (posInTileUnits.y * m_spacing) + m_margin};
475  return offset;
476 }
477 
483 tson::WangSet *tson::Tileset::getWangset(const std::string &name)
484 {
485  auto wangset = std::find_if(m_wangsets.begin(), m_wangsets.end(), [&](const auto &w) { return w.getName() == name; });
486 
487  if(wangset != m_wangsets.end())
488  return &wangset.operator*();
489 
490  return nullptr;
491 }
492 
500 {
501  return m_transformations;
502 }
503 
504 
505 #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:72
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:25
Definition: PropertyCollection.hpp:15
Definition: Property.hpp:21
Definition: Terrain.hpp:14
Definition: Tile.hpp:22
Definition: Tileset.hpp:24
const std::string & getType() const
Definition: Tileset.hpp:300
const std::vector< tson::Terrain > & getTerrains() const
Definition: Tileset.hpp:343
const Vector2i & getImageSize() const
Definition: Tileset.hpp:237
static tson::ObjectAlignment StringToAlignment(std::string_view str)
Definition: Tileset.hpp:441
ObjectAlignment getObjectAlignment() const
Definition: Tileset.hpp:457
const fs::path & getImage() const
Definition: Tileset.hpp:310
int getSpacing() const
Definition: Tileset.hpp:264
const Grid & getGrid() const
Definition: Tileset.hpp:362
const Vector2i & getTileOffset() const
Definition: Tileset.hpp:352
int getMargin() const
Definition: Tileset.hpp:246
const fs::path & getImagePath() const
Definition: Tileset.hpp:231
T get(const std::string &name)
Definition: Tileset.hpp:117
const Vector2i & getTileSize() const
Definition: Tileset.hpp:282
bool parse(IJson &json, tson::Map *map)
Definition: Tileset.hpp:128
tson::Property * getProp(const std::string &name)
Definition: Tileset.hpp:401
tson::Map * getMap() const
Definition: Tileset.hpp:431
const Transformations & getTransformations() const
Definition: Tileset.hpp:499
int getFirstgid() const
Definition: Tileset.hpp:221
int getTileCount() const
Definition: Tileset.hpp:273
tson::Tile * getTile(uint32_t id)
Definition: Tileset.hpp:373
PropertyCollection & getProperties()
Definition: Tileset.hpp:334
const std::vector< tson::WangSet > & getWangsets() const
Definition: Tileset.hpp:325
int getColumns() const
Definition: Tileset.hpp:212
const Colori & getTransparentColor() const
Definition: Tileset.hpp:291
Tileset()=default
const std::string & getName() const
Definition: Tileset.hpp:255
std::vector< tson::Tile > & getTiles()
Definition: Tileset.hpp:316
tson::Terrain * getTerrain(const std::string &name)
Definition: Tileset.hpp:387
tson::WangSet * getWangset(const std::string &name)
Definition: Tileset.hpp:483
tson::Vector2i getMarginSpacingOffset(const tson::Vector2i &posInTileUnits)
Definition: Tileset.hpp:469
Definition: Transformations.hpp:11
T y
Definition: Vector2.hpp:22
T x
Definition: Vector2.hpp:21
Definition: WangSet.hpp:16
Definition: Base64.hpp:12
ObjectAlignment
Definition: Enums.hpp:85