Skip to content

Commit

Permalink
Add IR layer factory function
Browse files Browse the repository at this point in the history
  • Loading branch information
albin-johansson committed Jul 17, 2024
1 parent 82a70a5 commit b2c18c1
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 0 deletions.
2 changes: 2 additions & 0 deletions source/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ target_sources(tactile-core
"src/tactile/core/layer/dense_tile_matrix.cpp"
"src/tactile/core/layer/group_layer.cpp"
"src/tactile/core/layer/layer.cpp"
"src/tactile/core/layer/layer_common.cpp"
"src/tactile/core/layer/object.cpp"
"src/tactile/core/layer/object_layer.cpp"
"src/tactile/core/layer/sparse_tile_matrix.cpp"
Expand Down Expand Up @@ -172,6 +173,7 @@ target_sources(tactile-core
"inc/tactile/core/layer/dense_tile_matrix.hpp"
"inc/tactile/core/layer/group_layer.hpp"
"inc/tactile/core/layer/layer.hpp"
"inc/tactile/core/layer/layer_common.hpp"
"inc/tactile/core/layer/object.hpp"
"inc/tactile/core/layer/object_layer.hpp"
"inc/tactile/core/layer/sparse_tile_matrix.hpp"
Expand Down
28 changes: 28 additions & 0 deletions source/core/inc/tactile/core/layer/layer_common.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (C) 2024 Albin Johansson (GNU General Public License v3.0)

#pragma once

#include "tactile/base/prelude.hpp"
#include "tactile/core/entity/entity.hpp"

namespace tactile {

class Registry;

namespace ir {
struct Layer;
} // namespace ir

/**
* Creates a layer from an intermediate representation.
*
* \param registry The associated registry.
* \param ir_layer The intermediate layer representation.
*
* \return
* A layer entity identifier.
*/
[[nodiscard]]
auto make_layer(Registry& registry, const ir::Layer& ir_layer) -> EntityID;

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

#include "tactile/core/layer/layer_common.hpp"

#include "tactile/base/io/save/ir.hpp"
#include "tactile/core/debug/assert.hpp"
#include "tactile/core/debug/exception.hpp"
#include "tactile/core/entity/registry.hpp"
#include "tactile/core/layer/group_layer.hpp"
#include "tactile/core/layer/layer.hpp"
#include "tactile/core/layer/object.hpp"
#include "tactile/core/layer/object_layer.hpp"
#include "tactile/core/layer/tile_layer.hpp"
#include "tactile/core/meta/meta.hpp"

namespace tactile {

auto make_layer(Registry& registry, const ir::Layer& ir_layer) -> EntityID
{
EntityID layer_id {kInvalidEntity};

switch (ir_layer.type) {
case LayerType::kTileLayer: {
layer_id = make_tile_layer(registry, ir_layer.extent);

auto& tile_data = get_tile_layer_data(registry, layer_id);

for (ssize row = 0; row < ir_layer.extent.rows; ++row) {
for (ssize col = 0; col < ir_layer.extent.cols; ++col) {
const auto tile_id =
ir_layer.tiles[static_cast<usize>(row)][static_cast<usize>(col)];
if (tile_id != kEmptyTile) {
tile_data[MatrixIndex {row, col}] = tile_id;
}
}
}

break;
}
case LayerType::kObjectLayer: {
layer_id = make_object_layer(registry);

auto& object_layer = registry.get<CObjectLayer>(layer_id);
object_layer.objects.reserve(ir_layer.objects.size());

for (const auto& ir_object : ir_layer.objects) {
object_layer.objects.push_back(convert_ir_object(registry, ir_object));
}

break;
}
case LayerType::kGroupLayer: {
layer_id = make_group_layer(registry);

auto& group_layer = registry.get<CGroupLayer>(layer_id);
group_layer.layers.reserve(ir_layer.layers.size());

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

break;
}
default: throw Exception {"invalid layer type"};
}

auto& layer = registry.get<CLayer>(layer_id);
layer.persistent_id = ir_layer.id;
layer.opacity = ir_layer.opacity;
layer.visible = ir_layer.visible;

convert_ir_metadata(registry, layer_id, ir_layer.meta);

TACTILE_ASSERT(is_layer(registry, layer_id));
return layer_id;
}

} // namespace tactile
1 change: 1 addition & 0 deletions source/core/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ target_sources(tactile-core-test
"src/event/event_dispatcher_test.cpp"
"src/io/ini_test.cpp"
"src/layer/group_layer_test.cpp"
"src/layer/layer_common_test.cpp"
"src/layer/layer_test.cpp"
"src/layer/object_layer_test.cpp"
"src/layer/object_test.cpp"
Expand Down
99 changes: 99 additions & 0 deletions source/core/test/src/layer/layer_common_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright (C) 2024 Albin Johansson (GNU General Public License v3.0)

#include "tactile/core/layer/layer_common.hpp"

#include <gtest/gtest.h>

#include "tactile/base/io/save/ir.hpp"
#include "tactile/base/test_util/ir.hpp"
#include "tactile/core/entity/registry.hpp"
#include "tactile/core/layer/group_layer.hpp"
#include "tactile/core/layer/layer.hpp"
#include "tactile/core/layer/object.hpp"
#include "tactile/core/layer/object_layer.hpp"
#include "tactile/core/layer/tile_layer.hpp"
#include "tactile/core/test/ir_comparison.hpp"

namespace tactile::test {

// tactile::make_layer [Registry&, const ir::Layer&]
TEST(LayerCommon, MakeLayerWithTileLayerIR)
{
Registry registry {};

auto ir_layer = make_ir_tile_layer(LayerID {99}, MatrixExtent {8, 6});
ir_layer.opacity = 0.75f;
ir_layer.visible = false;
ir_layer.meta.properties.emplace_back("A", Attribute {1});
ir_layer.meta.properties.emplace_back("B", Attribute {2});

{
TileID tile_id {1};
for (ssize row = 0; row < ir_layer.extent.rows; ++row) {
for (ssize col = 0; col < ir_layer.extent.cols; ++col) {
ir_layer.tiles[static_cast<usize>(row)][static_cast<usize>(col)] = tile_id;
++tile_id;
}
}
}

const auto layer_id = make_layer(registry, ir_layer);
ASSERT_TRUE(is_tile_layer(registry, layer_id));

compare_layer(registry, layer_id, ir_layer);
}

// tactile::make_layer [Registry&, const ir::Layer&]
TEST(LayerCommon, MakeLayerWithObjectLayerIR)
{
Registry registry {};

auto ir_layer = make_ir_object_layer(LayerID {123});
ir_layer.opacity = 0.50f;
ir_layer.meta.properties.emplace_back("foo", Attribute {"bar"});

ir_layer.objects = {
make_ir_object(ObjectID {1}, ObjectType::kPoint),
make_ir_object(ObjectID {2}, ObjectType::kRect),
make_ir_object(ObjectID {3}, ObjectType::kEllipse),
};

const auto layer_id = make_layer(registry, ir_layer);
ASSERT_TRUE(is_object_layer(registry, layer_id));

compare_layer(registry, layer_id, ir_layer);
}

// tactile::make_layer [Registry&, const ir::Layer&]
TEST(LayerCommon, MakeLayerWithGroupLayerIR)
{
Registry registry {};

auto ir_layer = make_ir_group_layer(LayerID {1});
ir_layer.meta.properties.emplace_back("1", Attribute {1});
ir_layer.meta.properties.emplace_back("2", Attribute {2});
ir_layer.meta.properties.emplace_back("3", Attribute {3});

ir_layer.layers = {
make_ir_group_layer(LayerID {1},
{
make_ir_object_layer(LayerID {4}),
make_ir_tile_layer(LayerID {5}, MatrixExtent {5, 5}),
make_ir_group_layer(LayerID {6},
{
make_ir_object_layer(LayerID {7}),
make_ir_group_layer(LayerID {8}),
make_ir_object_layer(LayerID {9}),
}),
}),
make_ir_tile_layer(LayerID {2}, MatrixExtent {5, 5}),
make_ir_object_layer(LayerID {3}),
};

const auto layer_id = make_layer(registry, ir_layer);
ASSERT_TRUE(is_group_layer(registry, layer_id));

compare_layer(registry, layer_id, ir_layer);
}

} // namespace tactile::test

0 comments on commit b2c18c1

Please sign in to comment.