Skip to content
Flecs v4.1
reflection/ser_opaque_type

  • C

    View on GitHub

    1#include <ser_opaque_type.h>
    2#include <stdio.h>
    3
    4// Use opaque reflection support to add a computed 'result' member to type
    5typedef struct {
    6 int32_t a;
    7 int32_t b;
    8} Sum;
    9
    10// Reflection support for Sum
    11int Sum_serialize(const ecs_serializer_t *ser, const void *ptr) {
    12 const Sum *data = ptr;
    13 ser->member(ser, "a");
    14 ser->value(ser, ecs_id(ecs_i32_t), &data->a);
    15 ser->member(ser, "b");
    16 ser->value(ser, ecs_id(ecs_i32_t), &data->b);
    17
    18 int32_t result = data->a + data->b; // Serialize fake member
    19 ser->member(ser, "result");
    20 ser->value(ser, ecs_id(ecs_i32_t), &result);
    21 return 0;
    22}
    23
    24// Return address for requested member
    25void* Sum_ensure_member(void *ptr, const char *member) {
    26 Sum *data = ptr;
    27 if (!strcmp(member, "a")) {
    28 return &data->a;
    29 } else if (!strcmp(member, "b")) {
    30 return &data->b;
    31 } else {
    32 return NULL; // We can't serialize into fake result member
    33 }
    34}
    35
    36int main(int argc, char *argv[]) {
    37 ecs_world_t *ecs = ecs_init_w_args(argc, argv);
    38
    39 // Register type as component so the size is known
    40 ECS_COMPONENT(ecs, Sum);
    41
    42 // Create struct type that describes the structure of Sum
    43 ecs_entity_t sum_type_descriptor = ecs_struct(ecs, {
    44 .members = {
    45 { .name = "a", .type = ecs_id(ecs_i32_t) },
    46 { .name = "b", .type = ecs_id(ecs_i32_t) },
    47 { .name = "result", .type = ecs_id(ecs_i32_t) }
    48 }
    49 });
    50
    51 // Register Sum as opaque type. An opaque type is a type of which the
    52 // reflection framework doesn't know the layout, but which it can serialize.
    53 ecs_opaque(ecs, {
    54 // Link reflection with component
    55 .entity = ecs_id(Sum),
    56 // Let reflection framework know the type represents a struct
    57 .type.as_type = sum_type_descriptor,
    58 // Register function for serializing sum contents
    59 .type.serialize = Sum_serialize,
    60 // Register function for getting access to members
    61 .type.ensure_member = Sum_ensure_member
    62 });
    63
    64 Sum v = { .a = 10, .b = 20 };
    65
    66 // Serialize value of Sum to JSON
    67 char *json = ecs_ptr_to_json(ecs, ecs_id(Sum), &v);
    68 printf("%s\n", json);
    69 ecs_os_free(json);
    70
    71 // Deserialize new value into Sum
    72 ecs_ptr_from_json(ecs, ecs_id(Sum), &v, "{\"a\": 20, \"b\": 22}", NULL);
    73
    74 // Serialize value again
    75 json = ecs_ptr_to_json(ecs, ecs_id(Sum), &v);
    76 printf("%s\n", json);
    77 ecs_os_free(json);
    78
    79 // Output
    80 // {"a":10, "b":20, "result":30}
    81 // {"a":22, "b":20, "result":42}
    82
    83 ecs_fini(ecs);
    84}
    FLECS_API const ecs_entity_t ecs_id(EcsDocDescription)
    Component ID for EcsDocDescription.
    FLECS_API char * ecs_ptr_to_json(const ecs_world_t *world, ecs_entity_t type, const void *data)
    Serialize value into JSON string.
    FLECS_API const char * ecs_ptr_from_json(const ecs_world_t *world, ecs_entity_t type, void *ptr, const char *json, const ecs_from_json_desc_t *desc)
    Parse JSON string into value.
    #define ecs_struct(world,...)
    Create a struct type.
    Definition meta.h:1777
    #define ecs_opaque(world,...)
    Create an opaque type.
    Definition meta.h:1773
    int32_t ecs_i32_t
    Built-in i32 type.
    Definition meta.h:105
    ecs_id_t ecs_entity_t
    An entity identifier.
    Definition flecs.h:395
    struct ecs_world_t ecs_world_t
    A world is the container for all ECS data and supporting features.
    Definition flecs.h:439
    #define ECS_COMPONENT(world, id)
    Declare and define a component.
    Definition flecs_c.h:98
    int ecs_fini(ecs_world_t *world)
    Delete a world.
    ecs_world_t * ecs_init_w_args(int argc, char *argv[])
    Create a new world with arguments.
    Serializer interface.
    Definition meta.h:348
    int(*) member(const struct ecs_serializer_t *ser, const char *member)
    Serialize member.
    Definition meta.h:356
    int(*) value(const struct ecs_serializer_t *ser, ecs_entity_t type, const void *value)
    Serialize value.
    Definition meta.h:350

  • C++

    View on GitHub

    1#include <ser_opaque_type.h>
    2#include <iostream>
    3#include <string>
    4
    5// Use opaque reflection support to add a computed 'result' member to type
    6struct Sum {
    7 int32_t a;
    8 int32_t b;
    9};
    10
    11int main(int, char *[]) {
    12 flecs::world ecs;
    13
    14 // Register serialization support for opaque type
    15 ecs.component<Sum>()
    16 // Serialize as struct
    17 .opaque(ecs.component()
    18 .member<int32_t>("a")
    19 .member<int32_t>("b")
    20 .member<int32_t>("result"))
    21
    22 // Forward struct members to serializer
    23 .serialize([](const flecs::serializer *s, const Sum *data) {
    24 s->member("x");
    25 s->value(data->a);
    26 s->member("y");
    27 s->value(data->b);
    28
    29 s->member("result");
    30 s->value(data->a + data->b); // Serialize fake member
    31 return 0;
    32 })
    33
    34 // Return address for requested member
    35 .ensure_member([](Sum *dst, const char *member) -> void* {
    36 if (!strcmp(member, "a")) {
    37 return &dst->a;
    38 } else if (!strcmp(member, "b")) {
    39 return &dst->b;
    40 } else {
    41 return nullptr; // We can't serialize into fake result member
    42 }
    43 });
    44
    45 // Serialize value of Sum to JSON
    46 Sum v = {10, 20};
    47 std::cout << ecs.to_json(&v) << std::endl;
    48
    49 // Deserialize new value into Sum
    50 ecs.from_json(&v, "{\"a\": 20, \"b\": 22}");
    51
    52 // Serialize value again
    53 std::cout << ecs.to_json(&v) << std::endl;
    54
    55 // Output
    56 // {"a":10, "b":20, "result":30}
    57 // {"a":22, "b":20, "result":42}
    58}
    component & opaque(const Func &type_support)
    Register an opaque type interface.
    Definition component.inl:8
    const char * from_json(flecs::entity_t tid, void *value, const char *json, flecs::from_json_desc_t *desc=nullptr)
    Deserialize a value from JSON.
    Definition world.hpp:42
    flecs::string to_json(flecs::entity_t tid, const void *value) const
    Serialize an untyped value to JSON.
    Definition world.hpp:12
    ecs_serializer_t serializer
    Serializer object, used for serializing opaque types.
    Definition opaque.hpp:19
    flecs::component< T > component(Args &&... args) const
    Find or register a component.
    Definition impl.hpp:11
    The world.
    Definition world.hpp:129