-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9c7e3c7
commit a3a2afd
Showing
6 changed files
with
214 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
modules/tmj-format/inc/tactile/tmj-format/emit/tmj_tile_emitter.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright (C) 2023 Albin Johansson (GNU General Public License v3.0) | ||
|
||
#pragma once | ||
|
||
#include "tactile/core/io/ir.hpp" | ||
#include "tactile/core/prelude.hpp" | ||
#include "tactile/tmj-format/api.hpp" | ||
#include "tactile/tmj-format/common/json.hpp" | ||
|
||
namespace tactile::tmj { | ||
|
||
/** | ||
* \brief Converts a tile definition to a TMJ JSON object. | ||
* | ||
* \param tile the tile definition. | ||
* \param tile_index the index of the tile in the associated tileset. | ||
* | ||
* \return a JSON object. | ||
*/ | ||
[[nodiscard]] | ||
TACTILE_TMJ_API auto emit_tile_definition(const ir::Tile& tile, TileIndex tile_index) | ||
-> JSON; | ||
|
||
/** | ||
* \brief Converts a collection of tile definitions to a TMJ JSON array. | ||
* | ||
* \param tiles the tile definitions. | ||
* | ||
* \return a JSON array. | ||
*/ | ||
[[nodiscard]] | ||
TACTILE_TMJ_API auto emit_tile_definition_array(const Vector<ir::Tile>& tiles) -> JSON; | ||
|
||
} // namespace tactile::tmj |
82 changes: 82 additions & 0 deletions
82
modules/tmj-format/src/tactile/tmj-format/emit/tmj_tile_emitter.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// Copyright (C) 2023 Albin Johansson (GNU General Public License v3.0) | ||
|
||
#include "tactile/tmj-format/emit/tmj_tile_emitter.hpp" | ||
|
||
#include <utility> // move | ||
|
||
#include "tactile/tmj-format/emit/tmj_meta_emitter.hpp" | ||
#include "tactile/tmj-format/emit/tmj_object_emitter.hpp" | ||
|
||
namespace tactile::tmj { | ||
namespace { | ||
|
||
[[nodiscard]] | ||
auto _emit_tile_nested_object_layer(const ir::Tile& tile) -> JSON | ||
{ | ||
auto object_layer_json = JSON::object(); | ||
|
||
object_layer_json["type"] = "objectgroup"; | ||
object_layer_json["draworder"] = "index"; | ||
object_layer_json["name"] = ""; | ||
object_layer_json["opacity"] = 1; | ||
object_layer_json["visible"] = true; | ||
object_layer_json["x"] = 0; | ||
object_layer_json["y"] = 0; | ||
object_layer_json["objects"] = emit_object_array(tile.objects); | ||
|
||
return object_layer_json; | ||
} | ||
|
||
[[nodiscard]] | ||
auto _emit_tile_animation_array(const ir::Tile& tile) -> JSON | ||
{ | ||
auto animation_json_array = JSON::array(); | ||
|
||
for (const auto& animation_frame : tile.animation) { | ||
auto animation_frame_json = JSON::object(); | ||
|
||
animation_frame_json["tileid"] = animation_frame.tile_index; | ||
animation_frame_json["duration"] = animation_frame.duration_ms; | ||
|
||
animation_json_array += std::move(animation_frame_json); | ||
} | ||
|
||
return animation_json_array; | ||
} | ||
|
||
} // namespace | ||
|
||
auto emit_tile_definition(const ir::Tile& tile, const TileIndex tile_index) -> JSON | ||
{ | ||
auto tile_json = JSON::object(); | ||
tile_json["id"] = tile_index; | ||
|
||
if (!tile.meta.properties.empty()) { | ||
tile_json["properties"] = emit_property_array(tile.meta); | ||
} | ||
|
||
if (!tile.animation.empty()) { | ||
tile_json["animation"] = _emit_tile_animation_array(tile); | ||
} | ||
|
||
if (!tile.objects.empty()) { | ||
tile_json["objectgroup"] = _emit_tile_nested_object_layer(tile); | ||
} | ||
|
||
return tile_json; | ||
} | ||
|
||
auto emit_tile_definition_array(const Vector<ir::Tile>& tiles) -> JSON | ||
{ | ||
auto tile_json_array = JSON::array(); | ||
|
||
TileIndex tile_index = 0; | ||
for (const auto& tile : tiles) { | ||
tile_json_array += emit_tile_definition(tile, tile_index); | ||
++tile_index; | ||
} | ||
|
||
return tile_json_array; | ||
} | ||
|
||
} // namespace tactile::tmj |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copyright (C) 2023 Albin Johansson (GNU General Public License v3.0) | ||
|
||
#include "tactile/tmj-format/emit/tmj_tile_emitter.hpp" | ||
|
||
#include <gtest/gtest.h> | ||
|
||
using namespace tactile; | ||
|
||
TEST(TmjTileEmitter, EmitEmptyTileDefinition) | ||
{ | ||
const TileIndex tile_index = 182; | ||
const ir::Tile tile {}; | ||
|
||
const auto tile_json = tmj::emit_tile_definition(tile, tile_index); | ||
|
||
EXPECT_EQ(tile_json["id"], tile_index); | ||
EXPECT_FALSE(tile_json.contains("properties")); | ||
EXPECT_FALSE(tile_json.contains("animation")); | ||
EXPECT_FALSE(tile_json.contains("objectgroup")); | ||
} | ||
|
||
TEST(TmjTileEmitter, EmitComplexTileDefinition) | ||
{ | ||
const TileIndex tile_index = 42; | ||
|
||
const ir::Tile tile { | ||
.meta = | ||
{ | ||
.name = "T42", | ||
.properties = | ||
{ | ||
ir::NamedAttribute {.name = "P1", .value = 100}, | ||
}, | ||
.components = {}, | ||
}, | ||
.objects = | ||
{ | ||
ir::Object {}, | ||
ir::Object {}, | ||
ir::Object {}, | ||
}, | ||
.animation = | ||
{ | ||
ir::AnimationFrame {.tile_index = 42, .duration_ms = 500}, | ||
ir::AnimationFrame {.tile_index = 50, .duration_ms = 600}, | ||
ir::AnimationFrame {.tile_index = 93, .duration_ms = 300}, | ||
ir::AnimationFrame {.tile_index = 6, .duration_ms = 123}, | ||
}, | ||
}; | ||
|
||
const auto tile_json = tmj::emit_tile_definition(tile, tile_index); | ||
|
||
EXPECT_EQ(tile_json["id"], tile_index); | ||
ASSERT_TRUE(tile_json.contains("properties")); | ||
ASSERT_TRUE(tile_json.contains("animation")); | ||
ASSERT_TRUE(tile_json.contains("objectgroup")); | ||
|
||
const auto& properties_json = tile_json.at("properties"); | ||
EXPECT_EQ(properties_json.size(), tile.meta.properties.size()); | ||
EXPECT_EQ(properties_json.at(0).at("name"), "P1"); | ||
EXPECT_EQ(properties_json.at(0).at("value"), 100); | ||
|
||
const auto& animation_json = tile_json.at("animation"); | ||
EXPECT_EQ(animation_json.size(), tile.animation.size()); | ||
EXPECT_EQ(animation_json.at(0).at("tileid"), tile.animation.at(0).tile_index); | ||
EXPECT_EQ(animation_json.at(0).at("duration"), tile.animation.at(0).duration_ms); | ||
EXPECT_EQ(animation_json.at(1).at("tileid"), tile.animation.at(1).tile_index); | ||
EXPECT_EQ(animation_json.at(1).at("duration"), tile.animation.at(1).duration_ms); | ||
EXPECT_EQ(animation_json.at(2).at("tileid"), tile.animation.at(2).tile_index); | ||
EXPECT_EQ(animation_json.at(2).at("duration"), tile.animation.at(2).duration_ms); | ||
EXPECT_EQ(animation_json.at(3).at("tileid"), tile.animation.at(3).tile_index); | ||
EXPECT_EQ(animation_json.at(3).at("duration"), tile.animation.at(3).duration_ms); | ||
|
||
EXPECT_EQ(tile_json.at("objectgroup").at("objects").size(), tile.objects.size()); | ||
} |