Skip to content

Commit

Permalink
Add map IR factory function
Browse files Browse the repository at this point in the history
  • Loading branch information
albin-johansson committed Jul 18, 2024
1 parent 9a734f4 commit 1d54b57
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 7 deletions.
20 changes: 20 additions & 0 deletions source/core/inc/tactile/core/map/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ namespace tactile {
struct MapSpec;
struct TilesetSpec;
class Registry;
class IRenderer;

namespace ir {
struct Map;
} // namespace ir

/**
* A component featured by all maps.
Expand Down Expand Up @@ -126,6 +131,21 @@ auto is_map(const Registry& registry, EntityID entity) -> bool;
[[nodiscard]]
auto make_map(Registry& registry, const MapSpec& spec) -> EntityID;

/**
* Creates a map based on an intermediate representation.
*
* \param registry The associated registry.
* \param renderer The renderer used to load textures.
* \param ir_map The intermediate map representation.
*
* \return
* A map entity identifier if successful; an error code otherwise.
*/
[[nodiscard]]
auto make_map(Registry& registry,
IRenderer& renderer,
const ir::Map& ir_map) -> Result<EntityID>;

/**
* Destroys a map.
*
Expand Down
63 changes: 63 additions & 0 deletions source/core/src/tactile/core/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

#include "tactile/core/map/map.hpp"

#include "tactile/base/io/save/ir.hpp"
#include "tactile/base/numeric/saturate_cast.hpp"
#include "tactile/core/debug/assert.hpp"
#include "tactile/core/debug/generic_error.hpp"
#include "tactile/core/entity/registry.hpp"
#include "tactile/core/layer/group_layer.hpp"
#include "tactile/core/layer/layer_common.hpp"
#include "tactile/core/layer/object_layer.hpp"
#include "tactile/core/layer/tile_layer.hpp"
#include "tactile/core/log/logger.hpp"
Expand Down Expand Up @@ -74,6 +76,67 @@ auto make_map(Registry& registry, const MapSpec& spec) -> EntityID
return map_entity;
}

auto make_map(Registry& registry,
IRenderer& renderer,
const ir::Map& ir_map) -> Result<EntityID>
{
const auto map_id = registry.make_entity();

registry.add<CMeta>(map_id);
convert_ir_metadata(registry, map_id, ir_map.meta);

auto& map = registry.add<CMap>(map_id);
map.orientation = TileOrientation::kOrthogonal; // TODO
map.extent = ir_map.extent;
map.tile_size = ir_map.tile_size;
map.root_layer = make_group_layer(registry);
map.active_layer = kInvalidEntity;
map.active_tileset = kInvalidEntity;

auto& format = registry.add<CTileFormat>(map_id);
format.encoding = ir_map.tile_format.encoding;
format.compression = ir_map.tile_format.compression;
format.comp_level = ir_map.tile_format.compression_level;

auto& id_cache = registry.add<CMapIdCache>(map_id);
id_cache.next_tile_id = TileID {1}; // TODO
id_cache.next_object_id = ir_map.next_object_id;
id_cache.next_layer_id = ir_map.next_layer_id;

auto& suffixes = registry.add<CLayerSuffixes>(map_id);
suffixes.tile_layer_suffix = 1;
suffixes.object_layer_suffix = 1;
suffixes.group_layer_suffix = 1;

auto& viewport = registry.add<CViewport>(map_id);
viewport.pos = Float2 {0, 0};
viewport.size = Float2 {0, 0};
viewport.scale = 1.0f;

// TODO components

map.attached_tilesets.reserve(ir_map.tilesets.size());
for (const auto& ir_tileset_ref : ir_map.tilesets) {
const auto tileset_id = make_tileset(registry, renderer, ir_tileset_ref);

if (!tileset_id.has_value()) {
return propagate_unexpected(tileset_id);
}

map.attached_tilesets.push_back(*tileset_id);
}

auto& root_layer = registry.get<CGroupLayer>(map.root_layer);
root_layer.layers.reserve(ir_map.layers.size());

for (const auto& ir_layer : ir_map.layers) {
root_layer.layers.push_back(make_layer(registry, ir_layer));
}

TACTILE_ASSERT(is_map(registry, map_id));
return map_id;
}

void destroy_map(Registry& registry, const EntityID map_entity)
{
TACTILE_ASSERT(is_map(registry, map_entity));
Expand Down
2 changes: 2 additions & 0 deletions source/core/test/inc/tactile/core/test/ir_comparison.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ void compare_tileset(const Registry& registry,
EntityID tileset_id,
const ir::TilesetRef& ir_tileset_ref);

void compare_map(const Registry& registry, EntityID map_id, const ir::Map& ir_map);

} // namespace tactile::test
41 changes: 41 additions & 0 deletions source/core/test/src/ir_comparison.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "tactile/core/layer/object.hpp"
#include "tactile/core/layer/object_layer.hpp"
#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/tile.hpp"
Expand Down Expand Up @@ -249,4 +250,44 @@ void compare_tileset(const Registry& registry,
compare_meta(registry, tileset_id, ir_tileset.meta);
}

void compare_map(const Registry& registry, const EntityID map_id, const ir::Map& ir_map)
{
ASSERT_TRUE(is_map(registry, map_id));

const auto& map = registry.get<CMap>(map_id);
const auto& id_cache = registry.get<CMapIdCache>(map_id);
const auto& tile_format = registry.get<CTileFormat>(map_id);

EXPECT_EQ(map.orientation, TileOrientation::kOrthogonal);
EXPECT_EQ(map.tile_size, ir_map.tile_size);
EXPECT_EQ(map.extent, ir_map.extent);
EXPECT_EQ(map.active_tileset, kInvalidEntity);
EXPECT_EQ(map.active_layer, kInvalidEntity);
ASSERT_EQ(map.attached_tilesets.size(), ir_map.tilesets.size());
ASSERT_TRUE(is_group_layer(registry, map.root_layer));

// TODO next_tile_id
EXPECT_EQ(id_cache.next_layer_id, ir_map.next_layer_id);
EXPECT_EQ(id_cache.next_object_id, ir_map.next_object_id);

EXPECT_EQ(tile_format.encoding, TileEncoding::kPlainText); // TODO
EXPECT_EQ(tile_format.compression, ir_map.tile_format.compression);
EXPECT_EQ(tile_format.comp_level, ir_map.tile_format.compression_level);

for (usize index = 0, count = map.attached_tilesets.size(); index < count; ++index) {
const auto tileset_id = map.attached_tilesets.at(index);
const auto& ir_tileset_ref = ir_map.tilesets.at(index);
compare_tileset(registry, tileset_id, ir_tileset_ref);
}

const auto& root_layer = registry.get<CGroupLayer>(map.root_layer);
for (usize index = 0, count = ir_map.layers.size(); index < count; ++index) {
const auto layer_id = root_layer.layers.at(index);
const auto& ir_layer = ir_map.layers.at(index);
compare_layer(registry, layer_id, ir_layer);
}

compare_meta(registry, map_id, ir_map.meta);
}

} // namespace tactile::test
31 changes: 24 additions & 7 deletions source/core/test/src/map/map_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@

#include <gtest/gtest.h>

#include "tactile/base/test_util/ir.hpp"
#include "tactile/base/test_util/ir_presets.hpp"
#include "tactile/core/entity/registry.hpp"
#include "tactile/core/layer/group_layer.hpp"
#include "tactile/core/layer/layer.hpp"
#include "tactile/core/map/map_spec.hpp"
#include "tactile/core/meta/meta.hpp"
#include "tactile/core/test/ir_comparison.hpp"
#include "tactile/core/tile/tileset.hpp"
#include "tactile/core/tile/tileset_spec.hpp"
#include "tactile/core/ui/viewport.hpp"
#include "tactile/null_renderer/null_renderer.hpp"

namespace tactile {
namespace tactile::test {

class MapTest : public testing::Test
{
Expand All @@ -25,9 +29,10 @@ class MapTest : public testing::Test

protected:
Registry mRegistry {};
NullRenderer mRenderer {nullptr};
};

/// \trace tactile::is_map
// tactile::is_map
TEST_F(MapTest, IsMap)
{
const MapSpec spec {
Expand All @@ -43,7 +48,7 @@ TEST_F(MapTest, IsMap)
EXPECT_TRUE(is_map(mRegistry, map_entity));
}

/// \trace tactile::make_map
// tactile::make_map [Registry&, const MapSpec&]
TEST_F(MapTest, MakeMap)
{
const MapSpec spec {
Expand Down Expand Up @@ -98,7 +103,19 @@ TEST_F(MapTest, MakeMap)
EXPECT_EQ(viewport.scale, 1.0f);
}

/// \trace tactile::make_map
// tactile::make_map [Registry&, IRenderer&, const ir::Map&]
TEST_F(MapTest, MakeMapFromIR)
{
const auto ir_map = make_complex_ir_map(make_ir_tile_format());

const auto map_id = make_map(mRegistry, mRenderer, ir_map);
ASSERT_TRUE(map_id.has_value());
ASSERT_TRUE(is_map(mRegistry, *map_id));

compare_map(mRegistry, *map_id, ir_map);
}

// tactile::make_map
TEST_F(MapTest, MakeMapWithInvalidSpec)
{
const MapSpec bad_extent {
Expand All @@ -117,7 +134,7 @@ TEST_F(MapTest, MakeMapWithInvalidSpec)
EXPECT_EQ(make_map(mRegistry, bad_tile_size), kInvalidEntity);
}

/// \trace tactile::destroy_map
// tactile::destroy_map
TEST_F(MapTest, DestroyMap)
{
const MapSpec spec {
Expand Down Expand Up @@ -151,7 +168,7 @@ TEST_F(MapTest, DestroyMap)
EXPECT_EQ(mRegistry.count(), 0);
}

/// \trace tactile::add_tileset_to_map
// tactile::add_tileset_to_map
TEST_F(MapTest, AddTilesetToMap)
{
const MapSpec spec {
Expand Down Expand Up @@ -195,4 +212,4 @@ TEST_F(MapTest, AddTilesetToMap)
EXPECT_EQ(mRegistry.count<CTilesetInstance>(), 1);
}

} // namespace tactile
} // namespace tactile::test

0 comments on commit 1d54b57

Please sign in to comment.