diff --git a/flecs.h b/flecs.h index 86842952ff..faffb85723 100644 --- a/flecs.h +++ b/flecs.h @@ -20952,7 +20952,6 @@ flecs::string to_json() { * \memberof flecs::world * \ingroup cpp_addons_json */ -template const char* from_json(flecs::entity_t tid, void* value, const char *json, flecs::from_json_desc_t *desc = nullptr) { return ecs_ptr_from_json(m_world, tid, value, json, desc); } @@ -23473,6 +23472,114 @@ Self& quantity() { # endif +# ifdef FLECS_JSON +/** + * @file addons/cpp/mixins/json/entity_builder.inl + * @brief JSON entity mixin. + */ + +/** Set component from JSON. + * + * \memberof flecs::entity_builder + * \ingroup cpp_addons_json + */ +Self& set_json( + flecs::id_t e, + const char *json, + flecs::from_json_desc_t *desc = nullptr) +{ + flecs::entity_t type = ecs_get_typeid(m_world, e); + if (!type) { + ecs_err("id is not a type"); + return to_base(); + } + + void *ptr = ecs_get_mut_id(m_world, m_id, e); + ecs_assert(ptr != NULL, ECS_INTERNAL_ERROR, NULL); + ecs_ptr_from_json(m_world, type, ptr, json, desc); + ecs_modified_id(m_world, m_id, e); + + return to_base(); +} + +/** Set pair from JSON. + * + * \memberof flecs::entity_builder + * \ingroup cpp_addons_json + */ +Self& set_json( + flecs::entity_t r, + flecs::entity_t t, + const char *json, + flecs::from_json_desc_t *desc = nullptr) +{ + return set_json(ecs_pair(r, t), json, desc); +} + +/** Set component from JSON. + * + * \memberof flecs::entity_builder + * \ingroup cpp_addons_json + */ +template +Self& set_json( + const char *json, + flecs::from_json_desc_t *desc = nullptr) +{ + return set_json(_::cpp_type::id(m_world), json, desc); +} + +/** Set pair from JSON. + * + * \memberof flecs::entity_builder + * \ingroup cpp_addons_json + */ +template +Self& set_json( + const char *json, + flecs::from_json_desc_t *desc = nullptr) +{ + return set_json( + _::cpp_type::id(m_world), + _::cpp_type::id(m_world), + json, desc); +} + +/** Set pair from JSON. + * + * \memberof flecs::entity_builder + * \ingroup cpp_addons_json + */ +template +Self& set_json( + flecs::entity_t t, + const char *json, + flecs::from_json_desc_t *desc = nullptr) +{ + return set_json( + _::cpp_type::id(m_world), t, + json, desc); +} + +/** Set pair from JSON. + * + * \memberof flecs::entity_builder + * \ingroup cpp_addons_json + */ +template +Self& set_json_second( + flecs::entity_t r, + const char *json, + flecs::from_json_desc_t *desc = nullptr) +{ + return set_json( + r, _::cpp_type::id(m_world), + json, desc); +} + +# endif + + protected: Self& to_base() { return *static_cast(this); @@ -23783,7 +23890,6 @@ const char* from_json(const char *json) { return ecs_entity_from_json(m_world, m_id, json, nullptr); } - # endif }; diff --git a/include/flecs/addons/cpp/mixins/entity/builder.hpp b/include/flecs/addons/cpp/mixins/entity/builder.hpp index 6cefe126f8..237b687c2a 100644 --- a/include/flecs/addons/cpp/mixins/entity/builder.hpp +++ b/include/flecs/addons/cpp/mixins/entity/builder.hpp @@ -956,6 +956,11 @@ struct entity_builder : entity_view { # include "../meta/entity_builder.inl" # endif +# ifdef FLECS_JSON +# include "../json/entity_builder.inl" +# endif + + protected: Self& to_base() { return *static_cast(this); diff --git a/include/flecs/addons/cpp/mixins/json/entity.inl b/include/flecs/addons/cpp/mixins/json/entity.inl index 38af2bd715..0db9a5afc0 100644 --- a/include/flecs/addons/cpp/mixins/json/entity.inl +++ b/include/flecs/addons/cpp/mixins/json/entity.inl @@ -7,4 +7,3 @@ const char* from_json(const char *json) { return ecs_entity_from_json(m_world, m_id, json, nullptr); } - diff --git a/include/flecs/addons/cpp/mixins/json/entity_builder.inl b/include/flecs/addons/cpp/mixins/json/entity_builder.inl new file mode 100644 index 0000000000..28a02bd117 --- /dev/null +++ b/include/flecs/addons/cpp/mixins/json/entity_builder.inl @@ -0,0 +1,103 @@ +/** + * @file addons/cpp/mixins/json/entity_builder.inl + * @brief JSON entity mixin. + */ + +/** Set component from JSON. + * + * \memberof flecs::entity_builder + * \ingroup cpp_addons_json + */ +Self& set_json( + flecs::id_t e, + const char *json, + flecs::from_json_desc_t *desc = nullptr) +{ + flecs::entity_t type = ecs_get_typeid(m_world, e); + if (!type) { + ecs_err("id is not a type"); + return to_base(); + } + + void *ptr = ecs_get_mut_id(m_world, m_id, e); + ecs_assert(ptr != NULL, ECS_INTERNAL_ERROR, NULL); + ecs_ptr_from_json(m_world, type, ptr, json, desc); + ecs_modified_id(m_world, m_id, e); + + return to_base(); +} + +/** Set pair from JSON. + * + * \memberof flecs::entity_builder + * \ingroup cpp_addons_json + */ +Self& set_json( + flecs::entity_t r, + flecs::entity_t t, + const char *json, + flecs::from_json_desc_t *desc = nullptr) +{ + return set_json(ecs_pair(r, t), json, desc); +} + +/** Set component from JSON. + * + * \memberof flecs::entity_builder + * \ingroup cpp_addons_json + */ +template +Self& set_json( + const char *json, + flecs::from_json_desc_t *desc = nullptr) +{ + return set_json(_::cpp_type::id(m_world), json, desc); +} + +/** Set pair from JSON. + * + * \memberof flecs::entity_builder + * \ingroup cpp_addons_json + */ +template +Self& set_json( + const char *json, + flecs::from_json_desc_t *desc = nullptr) +{ + return set_json( + _::cpp_type::id(m_world), + _::cpp_type::id(m_world), + json, desc); +} + +/** Set pair from JSON. + * + * \memberof flecs::entity_builder + * \ingroup cpp_addons_json + */ +template +Self& set_json( + flecs::entity_t t, + const char *json, + flecs::from_json_desc_t *desc = nullptr) +{ + return set_json( + _::cpp_type::id(m_world), t, + json, desc); +} + +/** Set pair from JSON. + * + * \memberof flecs::entity_builder + * \ingroup cpp_addons_json + */ +template +Self& set_json_second( + flecs::entity_t r, + const char *json, + flecs::from_json_desc_t *desc = nullptr) +{ + return set_json( + r, _::cpp_type::id(m_world), + json, desc); +} diff --git a/include/flecs/addons/cpp/mixins/json/world.inl b/include/flecs/addons/cpp/mixins/json/world.inl index 43691653ca..a7bd2dadbd 100644 --- a/include/flecs/addons/cpp/mixins/json/world.inl +++ b/include/flecs/addons/cpp/mixins/json/world.inl @@ -38,7 +38,6 @@ flecs::string to_json() { * \memberof flecs::world * \ingroup cpp_addons_json */ -template const char* from_json(flecs::entity_t tid, void* value, const char *json, flecs::from_json_desc_t *desc = nullptr) { return ecs_ptr_from_json(m_world, tid, value, json, desc); } diff --git a/test/cpp_api/project.json b/test/cpp_api/project.json index 40d3c40249..8b8175be62 100644 --- a/test/cpp_api/project.json +++ b/test/cpp_api/project.json @@ -1288,10 +1288,17 @@ "vector_type", "i32_from_json", "struct_from_json", + "void_from_json", "entity_from_json_empty", "entity_from_json_w_path", "entity_from_json_w_ids", "entity_from_json_w_values", + "set_type_json", + "set_pair_R_T_json", + "set_pair_R_t_json", + "set_pair_r_T_json", + "set_pair_r_t_json", + "set_id_json", "ser_deser_std_string", "ser_deser_std_vector_int", "ser_deser_std_vector_std_string", diff --git a/test/cpp_api/src/Meta.cpp b/test/cpp_api/src/Meta.cpp index 67e065096e..f7e7785f90 100644 --- a/test/cpp_api/src/Meta.cpp +++ b/test/cpp_api/src/Meta.cpp @@ -693,6 +693,21 @@ void Meta_struct_from_json(void) { test_int(v.y, 20); } +void Meta_void_from_json(void) { + flecs::world ecs; + + flecs::entity pos = ecs.component() + .member("x") + .member("y"); + + Position v = {}; + void *ptr = &v; + const char *r = ecs.from_json(pos, ptr, "{\"x\":10, \"y\":20}"); + test_str(r, ""); + test_int(v.x, 10); + test_int(v.y, 20); +} + void Meta_entity_from_json_empty(void) { flecs::world ecs; @@ -760,6 +775,106 @@ void Meta_entity_from_json_w_values(void) { test_int(p->y, 20); } +void Meta_set_type_json(void) { + flecs::world ecs; + + ecs.component() + .member("x") + .member("y"); + + flecs::entity e = ecs.entity() + .set_json("{\"x\":10, \"y\":20}"); + + const Position *p = e.get(); + test_assert(p != NULL); + test_int(p->x, 10); + test_int(p->y, 20); +} + +void Meta_set_pair_R_T_json(void) { + flecs::world ecs; + + ecs.component() + .member("x") + .member("y"); + + flecs::entity e = ecs.entity() + .set_json("{\"x\":10, \"y\":20}"); + + const Position *p = e.get(); + test_assert(p != NULL); + test_int(p->x, 10); + test_int(p->y, 20); +} + +void Meta_set_pair_R_t_json(void) { + flecs::world ecs; + + ecs.component() + .member("x") + .member("y"); + + flecs::entity tgt = ecs.entity(); + + flecs::entity e = ecs.entity() + .set_json(tgt, "{\"x\":10, \"y\":20}"); + + const Position *p = e.get(tgt); + test_assert(p != NULL); + test_int(p->x, 10); + test_int(p->y, 20); +} + +void Meta_set_pair_r_T_json(void) { + flecs::world ecs; + + flecs::entity pos = ecs.component() + .member("x") + .member("y"); + + flecs::entity e = ecs.entity() + .set_json_second(pos, "{\"x\":10, \"y\":20}"); + + const Position *p = e.get(); + test_assert(p != NULL); + test_int(p->x, 10); + test_int(p->y, 20); +} + +void Meta_set_pair_r_t_json(void) { + flecs::world ecs; + + flecs::entity pos = ecs.component() + .member("x") + .member("y"); + + flecs::entity tgt = ecs.entity(); + + flecs::entity e = ecs.entity() + .set_json(pos, tgt, "{\"x\":10, \"y\":20}"); + + const Position *p = e.get(tgt); + test_assert(p != NULL); + test_int(p->x, 10); + test_int(p->y, 20); +} + +void Meta_set_id_json(void) { + flecs::world ecs; + + flecs::entity pos = ecs.component() + .member("x") + .member("y"); + + flecs::entity e = ecs.entity() + .set_json(pos, "{\"x\":10, \"y\":20}"); + + const Position *p = e.get(); + test_assert(p != NULL); + test_int(p->x, 10); + test_int(p->y, 20); +} + void Meta_ser_deser_std_string(void) { flecs::world world; diff --git a/test/cpp_api/src/main.cpp b/test/cpp_api/src/main.cpp index 038f9d2213..612ed55b66 100644 --- a/test/cpp_api/src/main.cpp +++ b/test/cpp_api/src/main.cpp @@ -1232,10 +1232,17 @@ void Meta_array_type(void); void Meta_vector_type(void); void Meta_i32_from_json(void); void Meta_struct_from_json(void); +void Meta_void_from_json(void); void Meta_entity_from_json_empty(void); void Meta_entity_from_json_w_path(void); void Meta_entity_from_json_w_ids(void); void Meta_entity_from_json_w_values(void); +void Meta_set_type_json(void); +void Meta_set_pair_R_T_json(void); +void Meta_set_pair_R_t_json(void); +void Meta_set_pair_r_T_json(void); +void Meta_set_pair_r_t_json(void); +void Meta_set_id_json(void); void Meta_ser_deser_std_string(void); void Meta_ser_deser_std_vector_int(void); void Meta_ser_deser_std_vector_std_string(void); @@ -6058,6 +6065,10 @@ bake_test_case Meta_testcases[] = { "struct_from_json", Meta_struct_from_json }, + { + "void_from_json", + Meta_void_from_json + }, { "entity_from_json_empty", Meta_entity_from_json_empty @@ -6074,6 +6085,30 @@ bake_test_case Meta_testcases[] = { "entity_from_json_w_values", Meta_entity_from_json_w_values }, + { + "set_type_json", + Meta_set_type_json + }, + { + "set_pair_R_T_json", + Meta_set_pair_R_T_json + }, + { + "set_pair_R_t_json", + Meta_set_pair_R_t_json + }, + { + "set_pair_r_T_json", + Meta_set_pair_r_T_json + }, + { + "set_pair_r_t_json", + Meta_set_pair_r_t_json + }, + { + "set_id_json", + Meta_set_id_json + }, { "ser_deser_std_string", Meta_ser_deser_std_string @@ -6474,7 +6509,7 @@ static bake_test_suite suites[] = { "Meta", NULL, NULL, - 47, + 54, Meta_testcases }, {