Skip to content

Commit

Permalink
Add TMJ object emitter
Browse files Browse the repository at this point in the history
  • Loading branch information
albin-johansson committed Oct 14, 2023
1 parent af4942d commit b14c637
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (C) 2023 Albin Johansson (GNU General Public License v3.0)

#pragma once

#include "tactile/core/container/vector.hpp"
#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 map object to a TMJ JSON object.
*
* \param object the object to convert.
*
* \return a JSON object.
*/
[[nodiscard]]
TACTILE_TMJ_API auto emit_object(const ir::Object& object) -> JSON;

/**
* \brief Converts a group of map objects to an array of TMJ JSON objects.
*
* \param objects the objects to convert.
*
* \return a JSON array.
*/
[[nodiscard]]
TACTILE_TMJ_API auto emit_object_array(const Vector<ir::Object>& objects) -> JSON;

} // namespace tactile::tmj
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (C) 2023 Albin Johansson (GNU General Public License v3.0)

#include "tactile/tmj-format/emit/tmj_object_emitter.hpp"

#include "tactile/tmj-format/emit/tmj_meta_emitter.hpp"

namespace tactile::tmj {

auto emit_object(const ir::Object& object) -> JSON
{
auto object_json = JSON::object();

object_json["id"] = object.id;
object_json["name"] = object.meta.name;
object_json["x"] = object.x;
object_json["y"] = object.y;
object_json["width"] = object.width;
object_json["height"] = object.height;
object_json["visible"] = object.visible;
object_json["type"] = object.tag;
object_json["rotation"] = 0;
object_json["properties"] = emit_property_array(object.meta);

// TMJ objects are assumed to be rectangles if there's no point or ellipse indicators.
if (object.type == ObjectType::kPoint) {
object_json["point"] = true;
}
else if (object.type == ObjectType::kEllipse) {
object_json["ellipse"] = true;
}

return object_json;
}

auto emit_object_array(const Vector<ir::Object>& objects) -> JSON
{
auto object_json_array = JSON::array();

for (const auto& object : objects) {
object_json_array += emit_object(object);
}

return object_json_array;
}

} // namespace tactile::tmj
79 changes: 79 additions & 0 deletions modules/tmj-format/test/emit/tmj_object_emitter_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright (C) 2023 Albin Johansson (GNU General Public License v3.0)

#include "tactile/tmj-format/emit/tmj_object_emitter.hpp"

#include <gtest/gtest.h>

using namespace tactile;

class ParameterizedTmjObjectEmitterTest : public testing::TestWithParam<ObjectType> {};

INSTANTIATE_TEST_SUITE_P(AllObjectTypes,
ParameterizedTmjObjectEmitterTest,
testing::Values(ObjectType::kRect,
ObjectType::kEllipse,
ObjectType::kPoint));

/// \tests tactile::tmj::emit_object
TEST_P(ParameterizedTmjObjectEmitterTest, EmitObject)
{
const ObjectType object_type = GetParam();

const ir::Object object {
.meta =
{
.name = "ObjectName",
.properties =
{
ir::NamedAttribute {.name = "P1", .value = 42},
ir::NamedAttribute {.name = "P2", .value = "XYZ"},
},
.components = {},
},
.id = 72,
.type = object_type,
.x = 83,
.y = -21,
.width = 129,
.height = 310,
.tag = "Object::tag",
.visible = true,
};

const auto object_json = tmj::emit_object(object);
ASSERT_TRUE(object_json.is_object());

EXPECT_EQ(object_json.at("name"), object.meta.name);
EXPECT_EQ(object_json.at("id"), object.id);
EXPECT_EQ(object_json.at("x"), object.x);
EXPECT_EQ(object_json.at("y"), object.y);
EXPECT_EQ(object_json.at("width"), object.width);
EXPECT_EQ(object_json.at("height"), object.height);
EXPECT_EQ(object_json.at("type"), object.tag);
EXPECT_EQ(object_json.at("visible"), object.visible);

if (object_type == ObjectType::kPoint) {
EXPECT_TRUE(object_json.contains("point"));
EXPECT_FALSE(object_json.contains("ellipse"));
}
else if (object_type == ObjectType::kEllipse) {
EXPECT_FALSE(object_json.contains("point"));
EXPECT_TRUE(object_json.contains("ellipse"));
}
else {
EXPECT_FALSE(object_json.contains("point"));
EXPECT_FALSE(object_json.contains("ellipse"));
}

ASSERT_TRUE(object_json.contains("properties"));
ASSERT_EQ(object_json.at("properties").size(), object.meta.properties.size());

EXPECT_EQ(object_json.at("properties").at(0).at("name"), "P1");
EXPECT_EQ(object_json.at("properties").at(0).at("type"), "int");
EXPECT_EQ(object_json.at("properties").at(0).at("value"), 42);

EXPECT_EQ(object_json.at("properties").at(1).at("name"), "P2");
EXPECT_EQ(object_json.at("properties").at(1).at("type"), "string");
EXPECT_EQ(object_json.at("properties").at(1).at("value"), "XYZ");
}

0 comments on commit b14c637

Please sign in to comment.