Skip to content

Commit

Permalink
Add tile IR factory function
Browse files Browse the repository at this point in the history
  • Loading branch information
albin-johansson committed Jul 17, 2024
1 parent 8b43e68 commit c4f06e1
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 23 deletions.
17 changes: 17 additions & 0 deletions source/core/inc/tactile/core/tile/tile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#pragma once

#include "tactile/base/container/expected.hpp"
#include "tactile/base/container/vector.hpp"
#include "tactile/base/id.hpp"
#include "tactile/base/prelude.hpp"
Expand All @@ -11,6 +12,10 @@ namespace tactile {

class Registry;

namespace ir {
struct Tile;
} // namespace ir

/**
* A component that represents a tile definition.
*/
Expand Down Expand Up @@ -52,6 +57,18 @@ auto is_tile(const Registry& registry, EntityID entity) -> bool;
[[nodiscard]]
auto make_tile(Registry& registry, TileIndex index) -> EntityID;

/**
* Creates a tile from an intermediate representation.
*
* \param registry The associated registry.
* \param tile The intermediate tile representation.
*
* \return
* A tile entity identifier if successful; an error code otherwise.
*/
[[nodiscard]]
auto make_tile(Registry& registry, const ir::Tile& ir_tile) -> Result<EntityID>;

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

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

#include "tactile/base/io/save/ir.hpp"
#include "tactile/core/debug/assert.hpp"
#include "tactile/core/entity/registry.hpp"
#include "tactile/core/layer/object.hpp"
#include "tactile/core/meta/meta.hpp"
#include "tactile/core/tile/animation.hpp"

namespace tactile {
namespace tile {

[[nodiscard]]
auto convert_animation(Registry& registry,
const EntityID tile_id,
const ir::Tile& ir_tile) -> Result<void>
{
usize frame_index = 0;

for (const auto& ir_frame : ir_tile.animation) {
const AnimationFrame frame {ir_frame.tile_index, ir_frame.duration};

const auto add_frame_result = add_animation_frame(registry, tile_id, frame_index, frame);
if (!add_frame_result.has_value()) {
return propagate_unexpected(add_frame_result);
}

++frame_index;
}

return kOK;
}

} // namespace tile

auto is_tile(const Registry& registry, const EntityID entity) -> bool
{
Expand All @@ -27,6 +52,29 @@ auto make_tile(Registry& registry, const TileIndex index) -> EntityID
return tile_entity;
}

auto make_tile(Registry& registry, const ir::Tile& ir_tile) -> Result<EntityID>
{
const auto tile_id = make_tile(registry, ir_tile.index);

const auto convert_animation_result = tile::convert_animation(registry, tile_id, ir_tile);
if (!convert_animation_result.has_value()) {
destroy_tile(registry, tile_id);
return propagate_unexpected(convert_animation_result);
}

auto& tile = registry.get<CTile>(tile_id);
tile.objects.reserve(ir_tile.objects.size());

for (const auto& ir_object : ir_tile.objects) {
tile.objects.push_back(make_object(registry, ir_object));
}

convert_ir_metadata(registry, tile_id, ir_tile.meta);

TACTILE_ASSERT(is_tile(registry, tile_id));
return tile_id;
}

void destroy_tile(Registry& registry, const EntityID tile_entity)
{
TACTILE_ASSERT(is_tile(registry, tile_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 @@ -26,4 +26,6 @@ void compare_group_layer(const Registry& registry,

void compare_layer(const Registry& registry, EntityID layer_id, const ir::Layer& ir_layer);

void compare_tile(const Registry& registry, EntityID tile_id, const ir::Tile& ir_tile);

} // namespace tactile::test
59 changes: 53 additions & 6 deletions source/core/test/src/ir_comparison.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,37 @@
#include "tactile/core/layer/object_layer.hpp"
#include "tactile/core/layer/tile_layer.hpp"
#include "tactile/core/meta/meta.hpp"
#include "tactile/core/tile/animation.hpp"
#include "tactile/core/tile/tile.hpp"

namespace tactile::test {
namespace ir_comparison {

void compare_tile_animation(const Registry& registry,
const EntityID tile_id,
const ir::Tile& ir_tile)
{
const auto* animation = registry.find<CAnimation>(tile_id);
EXPECT_EQ(animation == nullptr, ir_tile.animation.empty());

if (animation != nullptr) {
EXPECT_EQ(animation->frame_index, 0);
ASSERT_EQ(animation->frames.size(), ir_tile.animation.size());

for (usize index = 0, count = animation->frames.size(); index < count; ++index) {
const auto& frame = animation->frames.at(index);
const auto& ir_frame = ir_tile.animation.at(index);

EXPECT_EQ(frame.tile_index, ir_frame.tile_index);
EXPECT_EQ(frame.duration, ir_frame.duration);
}
}
else {
EXPECT_EQ(ir_tile.animation.size(), 0);
}
}

} // namespace ir_comparison

void compare_meta(const Registry& registry,
const EntityID meta_id,
Expand Down Expand Up @@ -101,11 +130,10 @@ void compare_object_layer(const Registry& registry,
EXPECT_EQ(layer.opacity, ir_layer.opacity);
EXPECT_EQ(layer.visible, ir_layer.visible);

const auto object_count = object_layer.objects.size();
ASSERT_EQ(object_count, ir_layer.objects.size());
ASSERT_EQ(object_layer.objects.size(), ir_layer.objects.size());
EXPECT_EQ(object_layer.objects.capacity(), ir_layer.objects.size());

for (usize index = 0; index < object_count; ++index) {
for (usize index = 0, count = object_layer.objects.size(); index < count; ++index) {
const auto object_id = object_layer.objects.at(index);
const auto& ir_object = ir_layer.objects.at(index);
compare_object(registry, object_id, ir_object);
Expand All @@ -127,11 +155,10 @@ void compare_group_layer(const Registry& registry,
EXPECT_EQ(layer.opacity, ir_layer.opacity);
EXPECT_EQ(layer.visible, ir_layer.visible);

const auto layer_count = group_layer.layers.size();
ASSERT_EQ(layer_count, ir_layer.layers.size());
ASSERT_EQ(group_layer.layers.size(), ir_layer.layers.size());
EXPECT_EQ(group_layer.layers.capacity(), ir_layer.layers.size());

for (usize index = 0; index < layer_count; ++index) {
for (usize index = 0, count = group_layer.layers.size(); index < count; ++index) {
const auto sublayer_id = group_layer.layers.at(index);
const auto& ir_sublayer = ir_layer.layers.at(index);
compare_layer(registry, sublayer_id, ir_sublayer);
Expand All @@ -150,4 +177,24 @@ void compare_layer(const Registry& registry,
}
}

void compare_tile(const Registry& registry, const EntityID tile_id, const ir::Tile& ir_tile)
{
ASSERT_TRUE(is_tile(registry, tile_id));

const auto& tile = registry.get<CTile>(tile_id);
EXPECT_EQ(tile.index, ir_tile.index);

ASSERT_EQ(tile.objects.size(), ir_tile.objects.size());
EXPECT_EQ(tile.objects.capacity(), ir_tile.objects.size());

for (usize index = 0, count = tile.objects.size(); index < count; ++index) {
const auto object_id = tile.objects.at(index);
const auto& ir_object = ir_tile.objects.at(index);
compare_object(registry, object_id, ir_object);
}

ir_comparison::compare_tile_animation(registry, tile_id, ir_tile);
compare_meta(registry, tile_id, ir_tile.meta);
}

} // namespace tactile::test
42 changes: 25 additions & 17 deletions source/core/test/src/tile/tile_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,22 @@

#include <gtest/gtest.h>

#include "tactile/base/test_util/ir_presets.hpp"
#include "tactile/core/entity/registry.hpp"
#include "tactile/core/layer/object.hpp"
#include "tactile/core/meta/meta.hpp"
#include "tactile/core/test/ir_comparison.hpp"
#include "tactile/core/tile/animation.hpp"

namespace tactile {
namespace tactile::test {

class TileTest : public testing::Test
{
protected:
Registry mRegistry {};
};

// tactile::make_tile
// tactile::make_tile [Registry&, TileIndex]
// tactile::is_tile
TEST_F(TileTest, MakeTile)
{
Expand All @@ -38,6 +40,19 @@ TEST_F(TileTest, MakeTile)
EXPECT_EQ(tile.objects.size(), 0);
}

// tactile::make_tile [Registry&, const ir::Tile&]
TEST_F(TileTest, MakeTileFromIR)
{
ObjectID next_object_id {30};
const auto ir_tile = make_complex_ir_tile(TileIndex {74}, next_object_id);

const auto tile_id = make_tile(mRegistry, ir_tile);
ASSERT_TRUE(tile_id.has_value());
ASSERT_TRUE(is_tile(mRegistry, *tile_id));

compare_tile(mRegistry, *tile_id, ir_tile);
}

// tactile::destroy_tile
TEST_F(TileTest, DestroyTile)
{
Expand All @@ -46,12 +61,9 @@ TEST_F(TileTest, DestroyTile)

{
auto& tile = mRegistry.get<CTile>(tile_entity);
tile.objects.push_back(
make_object(mRegistry, ObjectID {1}, ObjectType::kRect));
tile.objects.push_back(
make_object(mRegistry, ObjectID {2}, ObjectType::kEllipse));
tile.objects.push_back(
make_object(mRegistry, ObjectID {3}, ObjectType::kPoint));
tile.objects.push_back(make_object(mRegistry, ObjectID {1}, ObjectType::kRect));
tile.objects.push_back(make_object(mRegistry, ObjectID {2}, ObjectType::kEllipse));
tile.objects.push_back(make_object(mRegistry, ObjectID {3}, ObjectType::kPoint));
}

// Tiles: 1 * (1 CMeta + 1 CTile)
Expand Down Expand Up @@ -81,12 +93,9 @@ TEST_F(TileTest, CopyTile)
meta1.components[UUID::generate()];

auto& tile1 = mRegistry.get<CTile>(e1);
tile1.objects.push_back(
make_object(mRegistry, ObjectID {1}, ObjectType::kPoint));
tile1.objects.push_back(
make_object(mRegistry, ObjectID {2}, ObjectType::kRect));
tile1.objects.push_back(
make_object(mRegistry, ObjectID {3}, ObjectType::kEllipse));
tile1.objects.push_back(make_object(mRegistry, ObjectID {1}, ObjectType::kPoint));
tile1.objects.push_back(make_object(mRegistry, ObjectID {2}, ObjectType::kRect));
tile1.objects.push_back(make_object(mRegistry, ObjectID {3}, ObjectType::kEllipse));

const auto e2 = copy_tile(mRegistry, e1);
EXPECT_TRUE(is_tile(mRegistry, e2));
Expand Down Expand Up @@ -118,8 +127,7 @@ TEST_F(TileTest, IsTilePlain)

{
auto& tile3 = mRegistry.get<CTile>(id3);
tile3.objects.push_back(
make_object(mRegistry, ObjectID {1}, ObjectType::kPoint));
tile3.objects.push_back(make_object(mRegistry, ObjectID {1}, ObjectType::kPoint));
}

{
Expand All @@ -139,4 +147,4 @@ TEST_F(TileTest, IsTilePlain)
EXPECT_FALSE(is_tile_plain(mRegistry, id5)); // Has component
}

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

0 comments on commit c4f06e1

Please sign in to comment.