Skip to content

Commit

Permalink
Add TMJ format map parser
Browse files Browse the repository at this point in the history
  • Loading branch information
albin-johansson committed Jul 22, 2024
1 parent 47d51a6 commit a4ae976
Show file tree
Hide file tree
Showing 6 changed files with 455 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ enum class SaveFormatParseError : uint8

kNoAnimationFrameTileIndex,
kNoAnimationFrameDuration,

kNoMapOrientation,
kBadMapOrientation,
kNoMapWidth,
kNoMapHeight,
kNoMapTileWidth,
kNoMapTileHeight,
kNoMapNextLayerId,
kNoMapNextObjectId,
};

} // namespace tactile
2 changes: 2 additions & 0 deletions source/tiled_tmj_format/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ target_sources(tactile-tiled-tmj-format
"src/tactile/tiled_tmj_format/tiled_tmj_format_save_visitor.cpp"
"src/tmj_format_attribute_parser.cpp"
"src/tmj_format_layer_parser.cpp"
"src/tmj_format_map_parser.cpp"
"src/tmj_format_object_parser.cpp"
"src/tmj_format_tileset_parser.cpp"

Expand All @@ -20,6 +21,7 @@ target_sources(tactile-tiled-tmj-format
"inc/tactile/tiled_tmj_format/tiled_tmj_format_save_visitor.hpp"
"inc/tactile/tiled_tmj_format/tmj_format_attribute_parser.hpp"
"inc/tactile/tiled_tmj_format/tmj_format_layer_parser.hpp"
"inc/tactile/tiled_tmj_format/tmj_format_map_parser.hpp"
"inc/tactile/tiled_tmj_format/tmj_format_object_parser.hpp"
"inc/tactile/tiled_tmj_format/tmj_format_tileset_parser.hpp"
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (C) 2024 Albin Johansson (GNU General Public License v3.0)

#pragma once

#include <nlohmann/json.hpp>

#include "tactile/base/io/save/ir.hpp"
#include "tactile/base/io/save/save_format.hpp"
#include "tactile/base/io/save/save_format_parse_result.hpp"
#include "tactile/base/prelude.hpp"
#include "tactile/tiled_tmj_format/api.hpp"

namespace tactile {

class IRuntime;

/**
* Attempts to parse a single Tiled TMJ map.
*
* \param runtime The associated runtime.
* \param map_json The map JSON node.
* \param options The configured read options.
*
* \return
* The parsed map if successful; an error code otherwise.
*
* \see https://doc.mapeditor.org/en/stable/reference/json-map-format/#map
*/
[[nodiscard]]
TACTILE_TMJ_FORMAT_API auto parse_tiled_tmj_map(const IRuntime& runtime,
const nlohmann::json& map_json,
const SaveFormatReadOptions& options)
-> SaveFormatParseResult<ir::Map>;

} // namespace tactile
113 changes: 113 additions & 0 deletions source/tiled_tmj_format/lib/src/tmj_format_map_parser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Copyright (C) 2024 Albin Johansson (GNU General Public License v3.0)

#include "tactile/tiled_tmj_format/tmj_format_map_parser.hpp"

#include <utility> // move

#include "tactile/tiled_tmj_format/tmj_format_attribute_parser.hpp"
#include "tactile/tiled_tmj_format/tmj_format_layer_parser.hpp"
#include "tactile/tiled_tmj_format/tmj_format_tileset_parser.hpp"

namespace tactile {

auto parse_tiled_tmj_map(const IRuntime& runtime,
const nlohmann::json& map_json,
const SaveFormatReadOptions& options)
-> SaveFormatParseResult<ir::Map>
{
ir::Map map {};

if (const auto orientation_iter = map_json.find("orientation");
orientation_iter != map_json.end()) {
const auto& orientation = orientation_iter->get_ref<const String&>();
if (orientation != "orthogonal") {
return unexpected(SaveFormatParseError::kBadMapOrientation);
}
}
else {
return unexpected(SaveFormatParseError::kNoMapOrientation);
}

if (auto metadata = parse_tiled_tmj_metadata(map_json)) {
map.meta = std::move(*metadata);
}
else {
return propagate_unexpected(metadata);
}

if (const auto width_iter = map_json.find("width"); width_iter != map_json.end()) {
width_iter->get_to(map.extent.cols);
}
else {
return unexpected(SaveFormatParseError::kNoMapWidth);
}

if (const auto height_iter = map_json.find("height"); height_iter != map_json.end()) {
height_iter->get_to(map.extent.rows);
}
else {
return unexpected(SaveFormatParseError::kNoMapHeight);
}

if (const auto tile_width_iter = map_json.find("tilewidth");
tile_width_iter != map_json.end()) {
tile_width_iter->get_to(map.tile_size[0]);
}
else {
return unexpected(SaveFormatParseError::kNoMapTileWidth);
}

if (const auto tile_height_iter = map_json.find("tileheight");
tile_height_iter != map_json.end()) {
tile_height_iter->get_to(map.tile_size[1]);
}
else {
return unexpected(SaveFormatParseError::kNoMapTileHeight);
}

if (const auto next_layer_id_iter = map_json.find("nextlayerid");
next_layer_id_iter != map_json.end()) {
next_layer_id_iter->get_to(map.next_layer_id);
}
else {
return unexpected(SaveFormatParseError::kNoMapNextLayerId);
}

if (const auto next_object_id_iter = map_json.find("nextobjectid");
next_object_id_iter != map_json.end()) {
next_object_id_iter->get_to(map.next_object_id);
}
else {
return unexpected(SaveFormatParseError::kNoMapNextObjectId);
}

if (const auto tilesets_iter = map_json.find("tilesets"); tilesets_iter != map_json.end()) {
map.tilesets.reserve(tilesets_iter->size());

for (const auto& [_, tileset_json] : tilesets_iter->items()) {
if (auto tileset = parse_tiled_tmj_tileset(tileset_json, options)) {
map.tilesets.push_back(std::move(*tileset));
}
else {
return propagate_unexpected(tileset);
}
}
}

if (const auto layers_iter = map_json.find("layers"); layers_iter != map_json.end()) {
map.layers.reserve(layers_iter->size());

for (const auto& [_, layer_json] : layers_iter->items()) {
if (auto layer = parse_tiled_tmj_layer(runtime, layer_json)) {
map.layers.push_back(std::move(*layer));
}
else {
return propagate_unexpected(layer);
}
}
}

return map;
}

} // namespace tactile
1 change: 1 addition & 0 deletions source/tiled_tmj_format/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ target_sources(tactile-tmj-format-test
"src/main.cpp"
"src/tmj_format_attribute_parser_test.cpp"
"src/tmj_format_layer_parser_test.cpp"
"src/tmj_format_map_parser_test.cpp"
"src/tmj_format_object_parser_test.cpp"
"src/tmj_format_tileset_parser_test.cpp"
)
Expand Down
Loading

0 comments on commit a4ae976

Please sign in to comment.