From f4b4d684bd9d32097a94d7d165bd19e9b549bacc Mon Sep 17 00:00:00 2001 From: Albin Johansson Date: Sun, 6 Oct 2024 12:17:57 +0200 Subject: [PATCH] Add new layer view functions --- .../inc/tactile/base/document/layer_view.hpp | 23 ++++++++++ .../tactile/core/document/layer_view_impl.hpp | 6 +++ .../tactile/core/document/layer_view_impl.cpp | 44 +++++++++++++++++++ .../tactile/godot_tscn_format/gd3_types.hpp | 1 + .../lib/src/gd3_document_converter.cpp | 6 ++- .../tactile/test_util/document_view_mocks.hpp | 7 +++ 6 files changed, 85 insertions(+), 2 deletions(-) diff --git a/source/base/lib/inc/tactile/base/document/layer_view.hpp b/source/base/lib/inc/tactile/base/document/layer_view.hpp index f88986d582..2b9eb47b40 100644 --- a/source/base/lib/inc/tactile/base/document/layer_view.hpp +++ b/source/base/lib/inc/tactile/base/document/layer_view.hpp @@ -129,6 +129,29 @@ class ILayerView [[nodiscard]] virtual auto get_tile(const Index2D& index) const -> std::optional = 0; + /** + * Returns the position of a tile in its parent tileset. + * + * \param tile_id The target tile identifier. + * + * \return + * The position of the tile in the tileset if successful; an empty optional otherwise. + */ + [[nodiscard]] + virtual auto get_tile_position_in_tileset(TileID tile_id) const + -> std::optional = 0; + + /** + * Indicates whether the tile at a given world position is animated. + * + * \param world_pos The world position of the tile to check. + * + * \return + * True if the tile is animated; false otherwise. + */ + [[nodiscard]] + virtual auto is_tile_animated(const Index2D& world_pos) const -> bool = 0; + /** * Returns the tile encoding format used by the layer. * diff --git a/source/core/inc/tactile/core/document/layer_view_impl.hpp b/source/core/inc/tactile/core/document/layer_view_impl.hpp index e763d7a5b9..4911a79ca9 100644 --- a/source/core/inc/tactile/core/document/layer_view_impl.hpp +++ b/source/core/inc/tactile/core/document/layer_view_impl.hpp @@ -63,6 +63,12 @@ class LayerViewImpl final : public ILayerView [[nodiscard]] auto get_tile(const Index2D& index) const -> std::optional override; + [[nodiscard]] + auto get_tile_position_in_tileset(TileID tile_id) const -> std::optional override; + + [[nodiscard]] + auto is_tile_animated(const Index2D& position) const -> bool override; + [[nodiscard]] auto get_tile_encoding() const -> TileEncoding override; diff --git a/source/core/src/tactile/core/document/layer_view_impl.cpp b/source/core/src/tactile/core/document/layer_view_impl.cpp index 1c8c61b45f..8f4cb68962 100644 --- a/source/core/src/tactile/core/document/layer_view_impl.cpp +++ b/source/core/src/tactile/core/document/layer_view_impl.cpp @@ -15,6 +15,8 @@ #include "tactile/core/layer/tile_layer.hpp" #include "tactile/core/map/map.hpp" #include "tactile/core/meta/meta.hpp" +#include "tactile/core/tile/animation.hpp" +#include "tactile/core/tile/tileset.hpp" namespace tactile { @@ -161,6 +163,48 @@ auto LayerViewImpl::get_tile(const Index2D& index) const -> std::optional std::optional +{ + const auto& registry = mDocument->get_registry(); + + const auto tile_index = get_tile_index(registry, tile_id); + if (!tile_index.has_value()) { + return std::nullopt; + } + + const auto tileset_id = find_tileset(registry, tile_id); + if (tileset_id == kInvalidEntity) { + return std::nullopt; + } + + const auto& tileset = registry.get(tileset_id); + return Index2D::from_1d(static_cast(*tile_index), tileset.extent.cols); +} + +auto LayerViewImpl::is_tile_animated(const Index2D& position) const -> bool +{ + const auto& registry = mDocument->get_registry(); + + const auto tile_id = get_layer_tile(registry, mLayerId, position).value(); + if (tile_id == kEmptyTile) { + return false; + } + + const auto tileset_id = find_tileset(registry, tile_id); + if (tileset_id == kInvalidEntity) { + return false; + } + + const auto& tileset = registry.get(tileset_id); + const auto& tileset_instance = registry.get(tileset_id); + + const auto tile_index = tile_id - tileset_instance.tile_range.first_id; + const auto tile_entity = tileset.tiles.at(static_cast(tile_index)); + + return registry.has(tile_entity); +} + auto LayerViewImpl::get_tile_encoding() const -> TileEncoding { return _get_tile_format().encoding; diff --git a/source/godot_tscn_format/lib/inc/tactile/godot_tscn_format/gd3_types.hpp b/source/godot_tscn_format/lib/inc/tactile/godot_tscn_format/gd3_types.hpp index db40fcfc13..1fe99685c3 100644 --- a/source/godot_tscn_format/lib/inc/tactile/godot_tscn_format/gd3_types.hpp +++ b/source/godot_tscn_format/lib/inc/tactile/godot_tscn_format/gd3_types.hpp @@ -169,6 +169,7 @@ struct Gd3Map final { Gd3Scene scene; ExtResourceId tileset_id; + Int2 tile_size; Gd3Tileset tileset; std::vector layers; std::unordered_map tileset_texture_ids; diff --git a/source/godot_tscn_format/lib/src/gd3_document_converter.cpp b/source/godot_tscn_format/lib/src/gd3_document_converter.cpp index ff6d0ae515..0b24fb3060 100644 --- a/source/godot_tscn_format/lib/src/gd3_document_converter.cpp +++ b/source/godot_tscn_format/lib/src/gd3_document_converter.cpp @@ -150,6 +150,7 @@ auto _convert_tile(const ILayerView& layer, [[nodiscard]] auto _convert_tile_layer(const ILayerView& layer, + const Int2 tile_size, const Gd3Tileset& gd_tileset, std::string parent_path) -> Gd3Layer { @@ -157,7 +158,7 @@ auto _convert_tile_layer(const ILayerView& layer, _convert_common_layer_data(layer, gd_layer, std::move(parent_path)); auto& gd_tile_layer = gd_layer.value.emplace(); - gd_tile_layer.cell_size = layer.get_tile_size(); + gd_tile_layer.cell_size = tile_size; const auto extent = layer.get_extent().value(); for (Extent2D::value_type row = 0; row < extent.rows; ++row) { @@ -275,6 +276,7 @@ auto Gd3DocumentConverter::visit(const IMapView& map) -> std::expected, get_tile, (const Index2D&), (const, override)); + MOCK_METHOD(std::optional, + get_tile_position_in_tileset, + (TileID), + (const, override)); + + MOCK_METHOD(bool, is_tile_animated, (const Index2D&), (const, override)); + MOCK_METHOD(TileEncoding, get_tile_encoding, (), (const, override)); MOCK_METHOD(std::optional, get_tile_compression, (), (const, override));