Tileson  1.3.0
A helpful json parser for Tiled maps
Layer.hpp
Go to the documentation of this file.
1 //
2 // Created by robin on 22.03.2020.
3 //
4 
5 #ifndef TILESON_LAYER_HPP
6 #define TILESON_LAYER_HPP
7 
8 #include <set>
9 //#include "../external/json.hpp"
10 #include "../objects/Vector2.hpp"
11 #include "../objects/Color.hpp"
12 #include "Chunk.hpp"
13 #include "Object.hpp"
14 #include "../objects/TileObject.hpp"
15 #include "../objects/Property.hpp"
16 #include "../objects/PropertyCollection.hpp"
17 #include "../common/Enums.hpp"
18 #include "../objects/FlaggedTile.hpp"
19 
20 namespace tson
21 {
22  class Tile;
23  class Map;
24 
25  class Layer
26  {
27  public:
28  inline Layer() = default;
29  inline Layer(IJson &json, tson::Map *map);
30  inline bool parse(IJson &json, tson::Map *map);
31 
32  [[nodiscard]] inline const std::string &getCompression() const;
33  [[nodiscard]] inline const std::vector<uint32_t> &getData() const;
34  [[nodiscard]] inline const std::string &getBase64Data() const;
35  [[nodiscard]] inline const std::string &getDrawOrder() const;
36  [[nodiscard]] inline const std::string &getEncoding() const;
37  [[nodiscard]] inline int getId() const;
38  [[nodiscard]] inline const std::string &getImage() const;
39  [[nodiscard]] inline const std::string &getName() const;
40  [[nodiscard]] inline const Vector2f &getOffset() const;
41  [[nodiscard]] inline float getOpacity() const;
42  [[nodiscard]] inline const Vector2i &getSize() const;
43  [[nodiscard]] inline const Colori &getTransparentColor() const;
44  [[nodiscard]] inline const Vector2f &getParallax() const;
45 
46  [[nodiscard]] inline LayerType getType() const;
47 
48  [[nodiscard]] inline const std::string &getTypeStr() const;
49  [[nodiscard]] inline bool isVisible() const;
50  [[nodiscard]] inline int getX() const;
51  [[nodiscard]] inline int getY() const;
52 
53  [[nodiscard]] inline std::vector<tson::Chunk> &getChunks();
54  [[nodiscard]] inline std::vector<tson::Layer> &getLayers();
55  [[nodiscard]] inline std::vector<tson::Object> &getObjects();
56  [[nodiscard]] inline PropertyCollection &getProperties();
57 
58  inline tson::Object *getObj(int id);
59  inline tson::Object *firstObj(const std::string &name);
60  inline std::vector<tson::Object> getObjectsByName(const std::string &name);
61  inline std::vector<tson::Object> getObjectsByType(tson::ObjectType type);
62 
63  template <typename T>
64  inline T get(const std::string &name);
65  inline tson::Property * getProp(const std::string &name);
66 
67  inline void assignTileMap(std::map<uint32_t, tson::Tile*> *tileMap);
68  inline void createTileData(const Vector2i &mapSize, bool isInfiniteMap);
69 
70  [[nodiscard]] inline const std::map<std::tuple<int, int>, tson::Tile *> &getTileData() const;
71  inline tson::Tile * getTileData(int x, int y);
72 
73  //v1.2.0-stuff
74  [[nodiscard]] inline const Colori &getTintColor() const;
75  [[nodiscard]] inline tson::Map *getMap() const;
76 
77  [[nodiscard]] inline std::map<std::tuple<int, int>, tson::TileObject> &getTileObjects();
78  inline tson::TileObject * getTileObject(int x, int y);
79  [[nodiscard]] inline const std::set<uint32_t> &getUniqueFlaggedTiles() const;
80  inline void resolveFlaggedTiles();
81 
82  private:
83  inline void setTypeByString();
84 
85  std::vector<tson::Chunk> m_chunks;
86  std::string m_compression;
87  std::vector<uint32_t> m_data;
89  std::string m_base64Data;
91  std::string m_drawOrder;
92  std::string m_encoding;
93  int m_id{};
94  std::string m_image;
95  std::vector<tson::Layer> m_layers;
96  std::string m_name;
97  std::vector<tson::Object> m_objects;
98  tson::Vector2f m_offset;
100  float m_opacity{};
101  tson::PropertyCollection m_properties;
102  tson::Vector2i m_size;
104  tson::Colori m_transparentcolor;
105  std::string m_typeStr;
107  bool m_visible{};
108  int m_x{};
109  int m_y{};
110  tson::Vector2f m_parallax{1.f, 1.f};
113  std::map<uint32_t, tson::Tile*> *m_tileMap;
114  std::map<std::tuple<int, int>, tson::Tile*> m_tileData;
116  //v1.2.0-stuff
117  tson::Colori m_tintcolor;
119  inline void decompressData();
120  inline void queueFlaggedTile(size_t x, size_t y, uint32_t id);
122  tson::Map * m_map;
123  std::map<std::tuple<int, int>, tson::TileObject> m_tileObjects;
124  std::set<uint32_t> m_uniqueFlaggedTiles;
125  std::vector<tson::FlaggedTile> m_flaggedTiles;
126 
127  };
128 
135  template<typename T>
136  T Layer::get(const std::string &name)
137  {
138  return m_properties.getValue<T>(name);
139  }
140 }
141 
147 {
148  parse(json, map);
149 }
150 
151 void tson::Layer::queueFlaggedTile(size_t x, size_t y, uint32_t id)
152 {
153  uint32_t tileId = id;
154  tileId &= ~(FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG);
155  m_uniqueFlaggedTiles.insert(id);
156  m_flaggedTiles.emplace_back(x, y, id, tileId);
157 }
158 
165 {
166  m_map = map;
167 
168  bool allFound = true;
169  if(json.count("tintcolor") > 0) m_tintcolor = tson::Colori(json["tintcolor"].get<std::string>()); //Optional
170  if(json.count("compression") > 0) m_compression = json["compression"].get<std::string>(); //Optional
171  if(json.count("draworder") > 0) m_drawOrder = json["draworder"].get<std::string>(); //Optional
172  if(json.count("encoding") > 0) m_encoding = json["encoding"].get<std::string>(); //Optional
173  if(json.count("id") > 0) m_id = json["id"].get<int>(); //Optional
174  if(json.count("image") > 0) m_image = json["image"].get<std::string>(); //Optional
175  if(json.count("name") > 0) m_name = json["name"].get<std::string>(); else allFound = false;
176  if(json.count("offsetx") > 0 && json.count("offsety") > 0)
177  m_offset = {json["offsetx"].get<float>(), json["offsety"].get<float>()}; //Optional
178  if(json.count("opacity") > 0) m_opacity = json["opacity"].get<float>(); else allFound = false;
179  if(json.count("width") > 0 && json.count("height") > 0)
180  m_size = {json["width"].get<int>(), json["height"].get<int>()}; //else allFound = false; - Not mandatory for all layers!
181  if(json.count("transparentcolor") > 0) m_transparentcolor = tson::Colori(json["transparentcolor"].get<std::string>()); //Optional
182  if(json.count("type") > 0) m_typeStr = json["type"].get<std::string>(); else allFound = false;
183  if(json.count("visible") > 0) m_visible = json["visible"].get<bool>(); else allFound = false;
184  if(json.count("x") > 0) m_x = json["x"].get<int>(); else allFound = false;
185  if(json.count("y") > 0) m_y = json["y"].get<int>(); else allFound = false;
186 
187  tson::Vector2f parallax {1.f, 1.f};
188  if(json.count("parallaxx") > 0)
189  parallax.x = json["parallaxx"].get<float>();
190  if(json.count("parallaxy") > 0)
191  parallax.y = json["parallaxy"].get<float>();
192 
193  m_parallax = parallax;
194 
195  //Handle DATA (Optional)
196  if(json.count("data") > 0)
197  {
198  if(json["data"].isArray())
199  {
200  auto &array = json.array("data");
201  std::for_each(array.begin(), array.end(), [&](std::unique_ptr<IJson> &item) { m_data.push_back(item->get<uint32_t>()); });
202  }
203  else
204  {
205  m_base64Data = json["data"].get<std::string>();
206  decompressData();
207  }
208  }
209 
210  //More advanced data
211  if(json.count("chunks") > 0 && json["chunks"].isArray())
212  {
213  auto &chunks = json.array("chunks");
214  std::for_each(chunks.begin(), chunks.end(), [&](std::unique_ptr<IJson> &item) { m_chunks.emplace_back(*item); });
215  }
216  if(json.count("layers") > 0 && json["layers"].isArray())
217  {
218  auto &layers = json.array("layers");
219  std::for_each(layers.begin(), layers.end(), [&](std::unique_ptr<IJson> &item) { m_layers.emplace_back(*item, m_map); });
220  }
221  if(json.count("objects") > 0 && json["objects"].isArray())
222  {
223  auto &objects = json.array("objects");
224  std::for_each(objects.begin(), objects.end(), [&](std::unique_ptr<IJson> &item) { m_objects.emplace_back(*item); });
225  }
226  if(json.count("properties") > 0 && json["properties"].isArray())
227  {
228  auto &properties = json.array("properties");
229  std::for_each(properties.begin(), properties.end(), [&](std::unique_ptr<IJson> &item) { m_properties.add(*item); });
230  }
231 
232  setTypeByString();
233 
234  return allFound;
235 }
236 
242 std::vector<tson::Object> tson::Layer::getObjectsByName(const std::string &name)
243 {
244  std::vector<tson::Object> found;
245 
246  std::copy_if(m_objects.begin(), m_objects.end(), std::back_inserter(found), [&](const tson::Object &item)
247  {
248  return item.getName() == name;
249  });
250 
251  return found;
252 }
253 
254 
255 
261 std::vector<tson::Object> tson::Layer::getObjectsByType(tson::ObjectType type)
262 {
263  std::vector<tson::Object> found;
264 
265  std::copy_if(m_objects.begin(), m_objects.end(), std::back_inserter(found), [&](const tson::Object &item)
266  {
267  return item.getObjectType() == type;
268  });
269 
270  return found;
271 }
272 
278 tson::Object *tson::Layer::firstObj(const std::string &name)
279 {
280  auto result = std::find_if(m_objects.begin(), m_objects.end(), [&](const tson::Object &obj){return obj.getName() == name; });
281  if(result == m_objects.end())
282  return nullptr;
283 
284  return &result.operator*();
285 }
286 
293 {
294  auto result = std::find_if(m_objects.begin(), m_objects.end(), [&](const tson::Object &obj){return obj.getId() == id; });
295  if(result == m_objects.end())
296  return nullptr;
297 
298  return &result.operator*();
299 }
300 
305 void tson::Layer::setTypeByString()
306 {
307  if(m_typeStr == "tilelayer") m_type = LayerType::TileLayer;
308  else if(m_typeStr == "objectgroup") m_type = LayerType::ObjectGroup;
309  else if(m_typeStr == "imagelayer") m_type = LayerType::ImageLayer;
310  else if(m_typeStr == "group") m_type = LayerType::Group;
311  else m_type = LayerType::Undefined;
312 }
313 
318 const std::string &tson::Layer::getCompression() const
319 {
320  return m_compression;
321 }
322 
327 const std::vector<uint32_t> &tson::Layer::getData() const
328 {
329  return m_data;
330 }
331 
336 const std::string &tson::Layer::getBase64Data() const
337 {
338  return m_base64Data;
339 }
340 
345 const std::string &tson::Layer::getDrawOrder() const
346 {
347  return m_drawOrder;
348 }
349 
354 const std::string &tson::Layer::getEncoding() const
355 {
356  return m_encoding;
357 }
358 
364 {
365  return m_id;
366 }
367 
372 const std::string &tson::Layer::getImage() const
373 {
374  return m_image;
375 }
376 
381 const std::string &tson::Layer::getName() const
382 {
383  return m_name;
384 }
385 
391 {
392  return m_offset;
393 }
394 
400 {
401  return m_opacity;
402 }
403 
410 {
411  return m_size;
412 }
413 
419 {
420  return m_transparentcolor;
421 }
422 
427 const std::string &tson::Layer::getTypeStr() const
428 {
429  return m_typeStr;
430 }
431 
437 {
438  return m_visible;
439 }
440 
445 int tson::Layer::getX() const
446 {
447  return m_x;
448 }
449 
454 int tson::Layer::getY() const
455 {
456  return m_y;
457 }
458 
463 std::vector<tson::Chunk> &tson::Layer::getChunks()
464 {
465  return m_chunks;
466 }
467 
472 std::vector<tson::Layer> &tson::Layer::getLayers()
473 {
474  return m_layers;
475 }
476 
481 std::vector<tson::Object> &tson::Layer::getObjects()
482 {
483  return m_objects;
484 }
485 
491 {
492  return m_properties;
493 }
494 
500 tson::Property *tson::Layer::getProp(const std::string &name)
501 {
502  if(m_properties.hasProperty(name))
503  return m_properties.getProperty(name);
504  return nullptr;
505 }
506 
512 {
513  return m_type;
514 }
515 
520 void tson::Layer::assignTileMap(std::map<uint32_t, tson::Tile *> *tileMap)
521 {
522  m_tileMap = tileMap;
523 }
524 
535 const std::map<std::tuple<int, int>, tson::Tile *> &tson::Layer::getTileData() const
536 {
537  return m_tileData;
538 }
539 
553 {
554  return (m_tileData.count({x, y}) > 0) ? m_tileData[{x,y}] : nullptr;
555 }
556 
562 {
563  return m_map;
564 }
565 
573 void tson::Layer::createTileData(const Vector2i &mapSize, bool isInfiniteMap)
574 {
575  size_t x = 0;
576  size_t y = 0;
577  if(!isInfiniteMap)
578  {
579  std::for_each(m_data.begin(), m_data.end(), [&](uint32_t tileId)
580  {
581  if (x == mapSize.x)
582  {
583  ++y;
584  x = 0;
585  }
586 
587  if (tileId > 0 && m_tileMap->count(tileId) > 0)
588  {
589  m_tileData[{x, y}] = m_tileMap->at(tileId);
590  m_tileObjects[{x, y}] = {{x, y}, m_tileData[{x, y}]};
591  }
592  else if(tileId > 0 && m_tileMap->count(tileId) == 0) //Tile with flip flags!
593  {
594  queueFlaggedTile(x, y, tileId);
595  }
596  x++;
597  });
598 
599  }
600 }
601 
602 std::map<std::tuple<int, int>, tson::TileObject> &tson::Layer::getTileObjects()
603 {
604  return m_tileObjects;
605 }
606 
608 {
609  return (m_tileObjects.count({x, y}) > 0) ? &m_tileObjects[{x,y}] : nullptr;
610 }
611 
612 const std::set<uint32_t> &tson::Layer::getUniqueFlaggedTiles() const
613 {
614  return m_uniqueFlaggedTiles;
615 }
616 
618 {
619  std::for_each(m_flaggedTiles.begin(), m_flaggedTiles.end(), [&](const tson::FlaggedTile &tile)
620  {
621  if (tile.id > 0 && m_tileMap->count(tile.id) > 0)
622  {
623  m_tileData[{tile.x, tile.y}] = m_tileMap->at(tile.id);
624  m_tileObjects[{tile.x, tile.y}] = {{tile.x, tile.y}, m_tileData[{tile.x, tile.y}]};
625  }
626  });
627 }
628 
635 {
636  return m_tintcolor;
637 }
638 
645 {
646  return m_parallax;
647 }
648 
649 
650 #endif //TILESON_LAYER_HPP
Definition: FlaggedTile.hpp:11
Definition: IJson.hpp:11
T get(std::string_view key)
Definition: IJson.hpp:72
virtual bool isArray() const =0
virtual size_t count(std::string_view key) const =0
virtual std::vector< std::unique_ptr< IJson > > array()=0
Definition: Layer.hpp:26
std::vector< tson::Object > getObjectsByType(tson::ObjectType type)
Definition: Layer.hpp:261
const std::map< std::tuple< int, int >, tson::Tile * > & getTileData() const
Definition: Layer.hpp:535
std::vector< tson::Layer > & getLayers()
Definition: Layer.hpp:472
void createTileData(const Vector2i &mapSize, bool isInfiniteMap)
Definition: Layer.hpp:573
const std::string & getBase64Data() const
Definition: Layer.hpp:336
PropertyCollection & getProperties()
Definition: Layer.hpp:490
tson::Object * firstObj(const std::string &name)
Definition: Layer.hpp:278
void assignTileMap(std::map< uint32_t, tson::Tile * > *tileMap)
Definition: Layer.hpp:520
int getId() const
Definition: Layer.hpp:363
tson::Object * getObj(int id)
Definition: Layer.hpp:292
const std::string & getName() const
Definition: Layer.hpp:381
bool parse(IJson &json, tson::Map *map)
Definition: Layer.hpp:164
std::map< std::tuple< int, int >, tson::TileObject > & getTileObjects()
Definition: Layer.hpp:602
LayerType getType() const
Definition: Layer.hpp:511
const Vector2i & getSize() const
Definition: Layer.hpp:409
T get(const std::string &name)
Definition: Layer.hpp:136
std::vector< tson::Chunk > & getChunks()
Definition: Layer.hpp:463
tson::Map * getMap() const
Definition: Layer.hpp:561
void resolveFlaggedTiles()
Definition: Layer.hpp:617
const std::string & getEncoding() const
Definition: Layer.hpp:354
float getOpacity() const
Definition: Layer.hpp:399
const std::vector< uint32_t > & getData() const
Definition: Layer.hpp:327
const std::string & getCompression() const
Definition: Layer.hpp:318
const std::set< uint32_t > & getUniqueFlaggedTiles() const
Definition: Layer.hpp:612
const Vector2f & getOffset() const
Definition: Layer.hpp:390
tson::Property * getProp(const std::string &name)
Definition: Layer.hpp:500
bool isVisible() const
Definition: Layer.hpp:436
const std::string & getTypeStr() const
Definition: Layer.hpp:427
const Colori & getTransparentColor() const
Definition: Layer.hpp:418
tson::TileObject * getTileObject(int x, int y)
Definition: Layer.hpp:607
const Colori & getTintColor() const
Definition: Layer.hpp:634
Layer()=default
const std::string & getImage() const
Definition: Layer.hpp:372
const Vector2f & getParallax() const
Definition: Layer.hpp:644
std::vector< tson::Object > & getObjects()
Definition: Layer.hpp:481
int getX() const
Definition: Layer.hpp:445
const std::string & getDrawOrder() const
Definition: Layer.hpp:345
std::vector< tson::Object > getObjectsByName(const std::string &name)
Definition: Layer.hpp:242
int getY() const
Definition: Layer.hpp:454
Definition: Map.hpp:25
Definition: Object.hpp:18
Definition: PropertyCollection.hpp:15
T getValue(const std::string &name)
Definition: PropertyCollection.hpp:46
Definition: Property.hpp:21
Definition: TileObject.hpp:14
Definition: Tile.hpp:22
T x
Definition: Vector2.hpp:21
Definition: Base64.hpp:12
ObjectType
Definition: Enums.hpp:55
LayerType
Definition: Enums.hpp:31
Color< uint8_t > Colori
Definition: Color.hpp:89