├── .github └── workflows │ └── ci.yml ├── .gitignore ├── LICENSE ├── README.md ├── examples ├── c │ ├── 01_struct │ │ ├── .gitignore │ │ ├── include │ │ │ ├── struct.h │ │ │ └── struct │ │ │ │ └── bake_config.h │ │ ├── project.json │ │ └── src │ │ │ └── main.c │ ├── 02_primitives │ │ ├── .gitignore │ │ ├── include │ │ │ ├── primitives.h │ │ │ └── primitives │ │ │ │ └── bake_config.h │ │ ├── project.json │ │ └── src │ │ │ └── main.c │ ├── 03_enum │ │ ├── .gitignore │ │ ├── include │ │ │ ├── enum.h │ │ │ └── enum │ │ │ │ └── bake_config.h │ │ ├── project.json │ │ └── src │ │ │ └── main.c │ ├── 04_bitmask │ │ ├── .gitignore │ │ ├── include │ │ │ ├── bitmask.h │ │ │ └── bitmask │ │ │ │ └── bake_config.h │ │ ├── project.json │ │ └── src │ │ │ └── main.c │ ├── 05_array │ │ ├── .gitignore │ │ ├── include │ │ │ ├── array.h │ │ │ └── array │ │ │ │ └── bake_config.h │ │ ├── project.json │ │ └── src │ │ │ └── main.c │ ├── 06_vector │ │ ├── .gitignore │ │ ├── include │ │ │ ├── vector.h │ │ │ └── vector │ │ │ │ └── bake_config.h │ │ ├── project.json │ │ └── src │ │ │ └── main.c │ ├── 07_map │ │ ├── .gitignore │ │ ├── include │ │ │ ├── map.h │ │ │ └── map │ │ │ │ └── bake_config.h │ │ ├── project.json │ │ └── src │ │ │ └── main.c │ ├── 08_serialize_entity │ │ ├── .gitignore │ │ ├── include │ │ │ ├── serialize_entity.h │ │ │ └── serialize_entity │ │ │ │ └── bake_config.h │ │ ├── project.json │ │ └── src │ │ │ └── main.c │ ├── 09_serialize_type │ │ ├── .gitignore │ │ ├── include │ │ │ ├── serialize_type.h │ │ │ └── serialize_type │ │ │ │ └── bake_config.h │ │ ├── project.json │ │ └── src │ │ │ └── main.c │ ├── 10_runtime_type │ │ ├── .gitignore │ │ ├── include │ │ │ ├── runtime_type.h │ │ │ └── runtime_type │ │ │ │ └── bake_config.h │ │ ├── project.json │ │ └── src │ │ │ └── main.c │ └── 11_nested_struct │ │ ├── .gitignore │ │ ├── include │ │ ├── nested_struct.h │ │ └── nested_struct │ │ │ └── bake_config.h │ │ ├── project.json │ │ └── src │ │ └── main.c └── cpp │ ├── 01_struct │ ├── .gitignore │ ├── include │ │ ├── struct.h │ │ └── struct │ │ │ └── bake_config.h │ ├── project.json │ └── src │ │ └── main.cpp │ ├── 02_primitives │ ├── .gitignore │ ├── include │ │ ├── primitives.h │ │ └── primitives │ │ │ └── bake_config.h │ ├── project.json │ └── src │ │ └── main.cpp │ ├── 03_enum │ ├── .gitignore │ ├── include │ │ ├── enum.h │ │ └── enum │ │ │ └── bake_config.h │ ├── project.json │ └── src │ │ └── main.cpp │ ├── 04_bitmask │ ├── .gitignore │ ├── include │ │ ├── bitmask.h │ │ └── bitmask │ │ │ └── bake_config.h │ ├── project.json │ └── src │ │ └── main.cpp │ ├── 05_array │ ├── .gitignore │ ├── include │ │ ├── array.h │ │ └── array │ │ │ └── bake_config.h │ ├── project.json │ └── src │ │ └── main.cpp │ ├── 06_vector │ ├── .gitignore │ ├── include │ │ ├── vector.h │ │ └── vector │ │ │ └── bake_config.h │ ├── project.json │ └── src │ │ └── main.cpp │ ├── 07_map │ ├── .gitignore │ ├── include │ │ ├── map.h │ │ └── map │ │ │ └── bake_config.h │ ├── project.json │ └── src │ │ └── main.cpp │ ├── 08_serialize_entity │ ├── .gitignore │ ├── include │ │ ├── serialize_entity.h │ │ └── serialize_entity │ │ │ └── bake_config.h │ ├── project.json │ └── src │ │ └── main.cpp │ ├── 09_serialize_type │ ├── .gitignore │ ├── include │ │ ├── serialize_type.h │ │ └── serialize_type │ │ │ └── bake_config.h │ ├── project.json │ └── src │ │ └── main.cpp │ ├── 10_runtime_type │ ├── .gitignore │ ├── include │ │ ├── runtime_type.h │ │ └── runtime_type │ │ │ └── bake_config.h │ ├── project.json │ └── src │ │ └── main.cpp │ └── 11_nested_struct │ ├── .gitignore │ ├── include │ ├── nested_struct.h │ └── nested_struct │ │ └── bake_config.h │ ├── project.json │ └── src │ └── main.cpp ├── flecs_meta.c ├── flecs_meta.h ├── include ├── flecs-meta │ └── bake_config.h └── flecs_meta.h ├── meson.build ├── project.json ├── src ├── deserializer.c ├── main.c ├── parser.c ├── parser.h ├── pretty_print.c ├── serializer.c ├── serializer.h ├── type.c ├── type.h └── util.c └── test ├── .gitignore ├── deserializer ├── include │ ├── test.h │ └── test │ │ └── bake_config.h ├── project.json └── src │ ├── Struct.c │ └── main.c └── serialize ├── include ├── test.h └── test │ └── bake_config.h ├── project.json └── src ├── Array.c ├── Bitmask.c ├── Enum.c ├── Map.c ├── Primitive.c ├── Struct.c ├── Vector.c └── main.c /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build-linux: 7 | timeout-minutes: 10 8 | runs-on: ubuntu-latest 9 | env: 10 | CC: ${{ matrix.compiler.cc }} 11 | CXX: ${{ matrix.compiler.cxx }} 12 | 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | compiler: 17 | - cc: gcc-7 18 | cxx: g++-7 19 | - cc: gcc-8 20 | cxx: g++-8 21 | - cc: gcc-9 22 | cxx: g++-9 23 | - cc: gcc-10 24 | cxx: g++-10 25 | - cc: clang-8 26 | cxx: clang++-8 27 | - cc: clang-9 28 | cxx: clang++-9 29 | - cc: clang-10 30 | cxx: clang++-10 31 | 32 | steps: 33 | - uses: actions/checkout@v2 34 | - name: install compiler 35 | run: | 36 | sudo apt-get install -y ${{ matrix.compiler.cc }} 37 | sudo apt-get install -y ${{ matrix.compiler.cxx }} 38 | 39 | - name: install bake 40 | run: | 41 | git clone https://github.com/SanderMertens/bake 42 | make -C bake/build-$(uname) 43 | bake/bake setup 44 | 45 | - name: install flecs 46 | run: | 47 | git clone https://github.com/SanderMertens/flecs 48 | bake flecs 49 | 50 | - name: build (debug) 51 | run: | 52 | bake --strict --cfg debug 53 | 54 | - name: build (release) 55 | run: | 56 | bake --strict --cfg release 57 | 58 | - name: build examples (debug) 59 | run: | 60 | bake examples --strict --cfg debug 61 | 62 | - name: build examples (release) 63 | run: | 64 | bake examples --strict --cfg release 65 | 66 | build-windows: 67 | timeout-minutes: 10 68 | runs-on: windows-latest 69 | 70 | strategy: 71 | fail-fast: false 72 | 73 | steps: 74 | - uses: actions/checkout@v2 75 | - uses: ilammy/msvc-dev-cmd@v1 76 | 77 | - name: install bake 78 | run: | 79 | git clone https://github.com/SanderMertens/bake 80 | cd bake\build-Windows 81 | nmake 82 | cd .. 83 | ./bake setup --local 84 | 85 | - name: install flecs 86 | run: | 87 | git clone https://github.com/SanderMertens/flecs 88 | bake/bake flecs 89 | 90 | - name: build (debug) 91 | run: bake/bake --strict --cfg debug 92 | 93 | - name: build (release) 94 | run: bake/bake --strict --cfg release 95 | 96 | - name: build examples (debug) 97 | run: | 98 | bake/bake examples --strict --cfg debug 99 | 100 | - name: build examples (release) 101 | run: | 102 | bake/bake examples --strict --cfg release 103 | 104 | test-unix: 105 | timeout-minutes: 20 106 | runs-on: ${{ matrix.os }} 107 | strategy: 108 | fail-fast: false 109 | matrix: 110 | os: [ ubuntu-latest, macOS-latest ] 111 | 112 | steps: 113 | - uses: actions/checkout@v2 114 | 115 | - name: install bake 116 | run: | 117 | git clone https://github.com/SanderMertens/bake 118 | make -C bake/build-$(uname) 119 | bake/bake setup 120 | 121 | - name: install flecs 122 | run: | 123 | git clone https://github.com/SanderMertens/flecs 124 | bake flecs 125 | 126 | - name: build 127 | run: bake --strict 128 | 129 | - name: run tests 130 | run: | 131 | bake run test/serialize 132 | bake run test/deserializer 133 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | bin 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Sander Mertens 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flecs.meta 2 | This repository has been archived! Use the `meta` addon in the Flecs main repository instead. 3 | -------------------------------------------------------------------------------- /examples/c/01_struct/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/c/01_struct/include/struct.h: -------------------------------------------------------------------------------- 1 | #ifndef STRUCT_H 2 | #define STRUCT_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "struct/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/c/01_struct/include/struct/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef STRUCT_BAKE_CONFIG_H 18 | #define STRUCT_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/c/01_struct/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "struct", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /examples/c/01_struct/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_STRUCT(Position, { 4 | int32_t x; 5 | int32_t y; 6 | }) 7 | 8 | int main(int argc, char *argv[]) { 9 | ecs_world_t *world = ecs_init_w_args(argc, argv); 10 | 11 | /* Import meta module */ 12 | ECS_IMPORT(world, FlecsMeta); 13 | 14 | /* Insert the meta definitions for Position. This will also register the 15 | * Position type as a component */ 16 | ECS_META(world, Position); 17 | 18 | /* Create an instance of the Position type */ 19 | Position p = {10, 20}; 20 | 21 | /* Pretty print the value */ 22 | char *str = ecs_ptr_to_str(world, ecs_id(Position), &p); 23 | printf("%s\n", str); 24 | free(str); 25 | 26 | return ecs_fini(world); 27 | } 28 | -------------------------------------------------------------------------------- /examples/c/02_primitives/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/c/02_primitives/include/primitives.h: -------------------------------------------------------------------------------- 1 | #ifndef PRIMITIVES_H 2 | #define PRIMITIVES_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "primitives/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/c/02_primitives/include/primitives/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef PRIMITIVES_BAKE_CONFIG_H 18 | #define PRIMITIVES_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/c/02_primitives/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "primitives", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /examples/c/02_primitives/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_STRUCT(Primitives, { 4 | bool a_bool; 5 | char a_char; 6 | ecs_byte_t a_byte; 7 | int32_t an_int; 8 | uint32_t a_uint; 9 | float a_float; 10 | char *a_string; 11 | }) 12 | 13 | int main(int argc, char *argv[]) { 14 | ecs_world_t *world = ecs_init_w_args(argc, argv); 15 | 16 | /* Import meta module */ 17 | ECS_IMPORT(world, FlecsMeta); 18 | 19 | /* Insert the meta definitions for Primitives. This will also register the 20 | * Primitives type as a component */ 21 | ECS_META(world, Primitives); 22 | 23 | /* Create an instance of the Primitives type */ 24 | Primitives p = { 25 | .a_bool = true, 26 | .a_char = 'a', 27 | .a_byte = 16, 28 | .an_int = -10, 29 | .a_uint = 10, 30 | .a_float = 20.5, 31 | .a_string = (char*)"Hello World" 32 | }; 33 | 34 | /* Pretty print the value */ 35 | char *str = ecs_ptr_to_str(world, ecs_id(Primitives), &p); 36 | printf("%s\n", str); 37 | free(str); 38 | 39 | return ecs_fini(world); 40 | } 41 | -------------------------------------------------------------------------------- /examples/c/03_enum/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/c/03_enum/include/enum.h: -------------------------------------------------------------------------------- 1 | #ifndef ENUM_H 2 | #define ENUM_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "enum/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/c/03_enum/include/enum/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef ENUM_BAKE_CONFIG_H 18 | #define ENUM_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/c/03_enum/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "enum", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /examples/c/03_enum/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_ENUM(Color, { 4 | Red, 5 | Green, 6 | Blue 7 | }) 8 | 9 | ECS_STRUCT(Vert2D, { 10 | float x; 11 | float y; 12 | Color color; 13 | }) 14 | 15 | int main(int argc, char *argv[]) { 16 | ecs_world_t *world = ecs_init_w_args(argc, argv); 17 | 18 | /* Import meta module */ 19 | ECS_IMPORT(world, FlecsMeta); 20 | 21 | /* Insert the meta definitions. Make sure to define Color before Vert2D as 22 | * it is used by Vert2D. */ 23 | ECS_META(world, Color); 24 | ECS_META(world, Vert2D); 25 | 26 | /* Create an instance of the Vert2D type */ 27 | Vert2D v = {10, 20, Green }; 28 | 29 | /* Pretty print the value */ 30 | char *str = ecs_ptr_to_str(world, ecs_id(Vert2D), &v); 31 | printf("%s\n", str); 32 | free(str); 33 | 34 | return ecs_fini(world); 35 | } 36 | -------------------------------------------------------------------------------- /examples/c/04_bitmask/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/c/04_bitmask/include/bitmask.h: -------------------------------------------------------------------------------- 1 | #ifndef BITMASK_H 2 | #define BITMASK_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "bitmask/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/c/04_bitmask/include/bitmask/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef BITMASK_BAKE_CONFIG_H 18 | #define BITMASK_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/c/04_bitmask/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "bitmask", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /examples/c/04_bitmask/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_BITMASK(Toppings, { 4 | Bacon = 0x1, 5 | Lettuce = 0x2, 6 | Tomato = 0x4, 7 | Onion = 0x8, 8 | Egg = 0x10, 9 | Turkey = 0x20 10 | }) 11 | 12 | ECS_STRUCT(Sandwich, { 13 | char *name; 14 | Toppings toppings; 15 | }) 16 | 17 | int main(int argc, char *argv[]) { 18 | ecs_world_t *world = ecs_init_w_args(argc, argv); 19 | 20 | /* Import meta module */ 21 | ECS_IMPORT(world, FlecsMeta); 22 | 23 | /* Insert the meta definitions. Make sure to define Toppings before 24 | * Sandwich, as Sandwich uses Toppings. */ 25 | ECS_META(world, Toppings); 26 | ECS_META(world, Sandwich); 27 | 28 | /* Create an instance of the Sandwich type */ 29 | Sandwich s = { (char*)"BLT", Bacon | Lettuce | Tomato }; 30 | 31 | /* Pretty print the value */ 32 | char *str = ecs_ptr_to_str(world, ecs_id(Sandwich), &s); 33 | printf("%s\n", str); 34 | free(str); 35 | 36 | return ecs_fini(world); 37 | } 38 | -------------------------------------------------------------------------------- /examples/c/05_array/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/c/05_array/include/array.h: -------------------------------------------------------------------------------- 1 | #ifndef ARRAY_H 2 | #define ARRAY_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "array/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/c/05_array/include/array/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef ARRAY_BAKE_CONFIG_H 18 | #define ARRAY_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/c/05_array/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "array", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /examples/c/05_array/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_STRUCT(Vert2D, { 4 | float coord[2]; 5 | }) 6 | 7 | int main(int argc, char *argv[]) { 8 | ecs_world_t *world = ecs_init_w_args(argc, argv); 9 | 10 | /* Import meta module */ 11 | ECS_IMPORT(world, FlecsMeta); 12 | 13 | /* Insert the meta definitions for Vert2D. This will also register the 14 | * Vert2D type as a component */ 15 | ECS_META(world, Vert2D); 16 | 17 | /* Create an instance of the Vert2D type */ 18 | Vert2D v = { { 10, 20 } }; 19 | 20 | /* Pretty print the value */ 21 | char *str = ecs_ptr_to_str(world, ecs_id(Vert2D), &v); 22 | printf("%s\n", str); 23 | free(str); 24 | 25 | return ecs_fini(world); 26 | } 27 | -------------------------------------------------------------------------------- /examples/c/06_vector/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/c/06_vector/include/vector.h: -------------------------------------------------------------------------------- 1 | #ifndef VECTOR_H 2 | #define VECTOR_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "vector/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/c/06_vector/include/vector/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef VECTOR_BAKE_CONFIG_H 18 | #define VECTOR_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/c/06_vector/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "vector", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /examples/c/06_vector/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_STRUCT(Vert2D, { 4 | float x; 5 | float y; 6 | }) 7 | 8 | ECS_STRUCT(Mesh, { 9 | ecs_vector(Vert2D) vertices; 10 | }) 11 | 12 | int main(int argc, char *argv[]) { 13 | ecs_world_t *world = ecs_init_w_args(argc, argv); 14 | 15 | /* Import meta module */ 16 | ECS_IMPORT(world, FlecsMeta); 17 | 18 | /* Insert the meta definitions for Vert2D and Mesh. Make sure to define Vert2D 19 | * before Mesh as Mesh uses Vert2D */ 20 | ECS_META(world, Vert2D); 21 | ECS_META(world, Mesh); 22 | 23 | /* Create an instance of the Mesh type */ 24 | Mesh m = { NULL }; 25 | Vert2D *v = ecs_vector_add(&m.vertices, Vert2D); 26 | v->x = 10; 27 | v->y = 20; 28 | 29 | v = ecs_vector_add(&m.vertices, Vert2D); 30 | v->x = 30; 31 | v->y = 40; 32 | 33 | v = ecs_vector_add(&m.vertices, Vert2D); 34 | v->x = 50; 35 | v->y = 60; 36 | 37 | /* Pretty print the value */ 38 | char *str = ecs_ptr_to_str(world, ecs_id(Mesh), &m); 39 | printf("%s\n", str); 40 | free(str); 41 | 42 | return ecs_fini(world); 43 | } 44 | -------------------------------------------------------------------------------- /examples/c/07_map/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/c/07_map/include/map.h: -------------------------------------------------------------------------------- 1 | #ifndef MAP_H 2 | #define MAP_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "map/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/c/07_map/include/map/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef MAP_BAKE_CONFIG_H 18 | #define MAP_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/c/07_map/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "map", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /examples/c/07_map/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_BITMASK(Toppings, { 4 | Bacon = 0x1, 5 | Lettuce = 0x2, 6 | Tomato = 0x4, 7 | Onion = 0x8, 8 | Egg = 0x10, 9 | Turkey = 0x20 10 | }) 11 | 12 | ECS_STRUCT(Sandwich, { 13 | int32_t cost; 14 | Toppings toppings; 15 | }) 16 | 17 | ECS_STRUCT(Menu, { 18 | ecs_map(ecs_string_t, Sandwich) items; 19 | }) 20 | 21 | int main(int argc, char *argv[]) { 22 | ecs_world_t *world = ecs_init_w_args(argc, argv); 23 | 24 | /* Import meta module */ 25 | ECS_IMPORT(world, FlecsMeta); 26 | 27 | /* Insert the meta definitions for Toppings, Sandwich and Menu. Make sure 28 | * that dependencies are registered before they are used. */ 29 | ECS_META(world, Toppings); 30 | ECS_META(world, Sandwich); 31 | ECS_META(world, Menu); 32 | 33 | /* Create an instance of the Menu type */ 34 | Menu m = { ecs_map_new(Sandwich, 0) }; 35 | 36 | /* Insert a BLT sandwich. Because ecs_map_t only accepts 64bit integers as 37 | * key, we need to cast the string key. */ 38 | Sandwich s = {2, Bacon | Lettuce | Tomato}; 39 | ecs_map_set(m.items, (intptr_t)"BLT", &s); 40 | 41 | /* Insert another sandwich */ 42 | s = (Sandwich){3, Bacon | Turkey | Onion}; 43 | ecs_map_set(m.items, (intptr_t)"Turkey sub", &s); 44 | 45 | /* Pretty print the value */ 46 | char *str = ecs_ptr_to_str(world, ecs_id(Menu), &m); 47 | printf("%s\n", str); 48 | free(str); 49 | 50 | return ecs_fini(world); 51 | } 52 | -------------------------------------------------------------------------------- /examples/c/08_serialize_entity/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/c/08_serialize_entity/include/serialize_entity.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALIZE_ENTITY_H 2 | #define SERIALIZE_ENTITY_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "serialize_entity/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/c/08_serialize_entity/include/serialize_entity/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef SERIALIZE_ENTITY_BAKE_CONFIG_H 18 | #define SERIALIZE_ENTITY_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/c/08_serialize_entity/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "serialize_entity", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /examples/c/08_serialize_entity/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_STRUCT(Position, { 4 | float x; 5 | float y; 6 | }) 7 | 8 | ECS_ENUM(AgentKind, { 9 | Human, 10 | AI 11 | }) 12 | 13 | ECS_STRUCT(Agent, { 14 | AgentKind kind; 15 | }) 16 | 17 | int main(int argc, char *argv[]) { 18 | ecs_world_t *world = ecs_init_w_args(argc, argv); 19 | 20 | /* Import meta module */ 21 | ECS_IMPORT(world, FlecsMeta); 22 | 23 | /* Insert the meta definitions for Position, AgentKind and Agent. Make sure 24 | * that dependencies are registered before they are used. */ 25 | ECS_META(world, Position); 26 | ECS_META(world, AgentKind); 27 | ECS_META(world, Agent); 28 | 29 | /* Create a player entity */ 30 | ecs_entity_t player = ecs_entity_init(world, &(ecs_entity_desc_t) { 31 | .name = "Player One" }); 32 | 33 | ecs_set(world, player, Agent, {Human}); 34 | ecs_set(world, player, Position, {10, 20}); 35 | 36 | /* Pretty print the player entity */ 37 | char *str = ecs_entity_to_str(world, player); 38 | printf("%s\n", str); 39 | free(str); 40 | 41 | return ecs_fini(world); 42 | } 43 | -------------------------------------------------------------------------------- /examples/c/09_serialize_type/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/c/09_serialize_type/include/serialize_type.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALIZE_TYPE_H 2 | #define SERIALIZE_TYPE_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "serialize_type/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/c/09_serialize_type/include/serialize_type/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef SERIALIZE_TYPE_BAKE_CONFIG_H 18 | #define SERIALIZE_TYPE_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/c/09_serialize_type/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "serialize_type", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /examples/c/09_serialize_type/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_STRUCT(Position, { 4 | float x; 5 | float y; 6 | }) 7 | 8 | int main(int argc, char *argv[]) { 9 | ecs_world_t *world = ecs_init_w_args(argc, argv); 10 | 11 | /* Import meta module */ 12 | ECS_IMPORT(world, FlecsMeta); 13 | 14 | /* Insert the meta definitions for Position. */ 15 | ECS_META(world, Position); 16 | 17 | /* Pretty print the type. Because the type is an entity, the metadata is 18 | * stored in components that support reflection, we can serialize types. */ 19 | char *str = ecs_entity_to_str(world, ecs_id(Position)); 20 | printf("%s\n", str); 21 | free(str); 22 | 23 | return ecs_fini(world); 24 | } 25 | -------------------------------------------------------------------------------- /examples/c/10_runtime_type/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/c/10_runtime_type/include/runtime_type.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNTIME_TYPE_H 2 | #define RUNTIME_TYPE_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "runtime_type/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/c/10_runtime_type/include/runtime_type/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef RUNTIME_TYPE_BAKE_CONFIG_H 18 | #define RUNTIME_TYPE_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/c/10_runtime_type/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "runtime_type", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /examples/c/10_runtime_type/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct Position { 4 | float x; 5 | float y; 6 | } Position; 7 | 8 | int main(int argc, char *argv[]) { 9 | ecs_world_t *world = ecs_init_w_args(argc, argv); 10 | 11 | ECS_IMPORT(world, FlecsMeta); 12 | 13 | /* Create new entity for our type. This type will describe Position. */ 14 | ecs_entity_t position_type = ecs_entity_init(world, &(ecs_entity_desc_t) { 15 | .name = "Position" 16 | }); 17 | 18 | /* Add an EcsStruct component to the type that holds our members */ 19 | EcsStruct *type = ecs_get_mut(world, position_type, EcsStruct, NULL); 20 | 21 | /* Add the members to the members vector */ 22 | EcsMember *m_x = ecs_vector_add(&type->members, EcsMember); 23 | m_x->name = (char*)"x"; 24 | m_x->type = ecs_lookup_fullpath(world, "float"); 25 | 26 | EcsMember *m_y = ecs_vector_add(&type->members, EcsMember); 27 | m_y->name = (char*)"y"; 28 | m_y->type = ecs_lookup_fullpath(world, "float"); 29 | 30 | /* Let the framework know we're done modifying EcsStruct */ 31 | ecs_modified(world, position_type, EcsStruct); 32 | 33 | /* Create a dummy value */ 34 | Position p = {10, 20}; 35 | 36 | /* Serialize the value to a string */ 37 | char *str = ecs_ptr_to_str(world, position_type, &p); 38 | printf("Position: %s\n", str); 39 | free(str); 40 | 41 | return ecs_fini(world); 42 | } 43 | -------------------------------------------------------------------------------- /examples/c/11_nested_struct/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/c/11_nested_struct/include/nested_struct.h: -------------------------------------------------------------------------------- 1 | #ifndef NESTED_STRUCT_H 2 | #define NESTED_STRUCT_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "nested_struct/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/c/11_nested_struct/include/nested_struct/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef NESTED_STRUCT_BAKE_CONFIG_H 18 | #define NESTED_STRUCT_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/c/11_nested_struct/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "nested_struct", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "public": false, 8 | "use": [ 9 | "flecs", 10 | "flecs.meta" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /examples/c/11_nested_struct/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_STRUCT(Point, { 4 | int32_t x; 5 | int32_t y; 6 | }) 7 | 8 | ECS_STRUCT(Line, { 9 | Point start; 10 | Point stop; 11 | }) 12 | 13 | int main(int argc, char *argv[]) { 14 | ecs_world_t *world = ecs_init_w_args(argc, argv); 15 | 16 | /* Import meta module */ 17 | ECS_IMPORT(world, FlecsMeta); 18 | 19 | /* Insert the meta definitions for Position. This will also register the 20 | * Position type as a component */ 21 | ECS_META(world, Point); 22 | ECS_META(world, Line); 23 | 24 | /* Create an instance of the Position type */ 25 | Line l = {{10, 20}, {30, 40}}; 26 | 27 | /* Pretty print the value */ 28 | char *str = ecs_ptr_to_str(world, ecs_id(Line), &l); 29 | printf("%s\n", str); 30 | free(str); 31 | 32 | return ecs_fini(world); 33 | } 34 | -------------------------------------------------------------------------------- /examples/cpp/01_struct/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/cpp/01_struct/include/struct.h: -------------------------------------------------------------------------------- 1 | #ifndef STRUCT_H 2 | #define STRUCT_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "struct/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/cpp/01_struct/include/struct/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef STRUCT_BAKE_CONFIG_H 18 | #define STRUCT_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/cpp/01_struct/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "struct", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ], 11 | "language": "c++" 12 | } 13 | } -------------------------------------------------------------------------------- /examples/cpp/01_struct/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | ECS_STRUCT(Position, { 5 | int32_t x; 6 | int32_t y; 7 | }) 8 | 9 | int main(int, char *[]) { 10 | flecs::world ecs; 11 | 12 | // Import meta module 13 | ecs.import(); 14 | 15 | // Insert the meta definitions for Position. This will also register the 16 | // Position type as a component 17 | flecs::meta(ecs); 18 | 19 | // Create an instance of the Position type 20 | Position p = {10, 20}; 21 | 22 | // Pretty print the value 23 | std::cout << flecs::pretty_print(ecs, p) << std::endl; 24 | } 25 | -------------------------------------------------------------------------------- /examples/cpp/02_primitives/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/cpp/02_primitives/include/primitives.h: -------------------------------------------------------------------------------- 1 | #ifndef PRIMITIVES_H 2 | #define PRIMITIVES_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "primitives/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/cpp/02_primitives/include/primitives/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef PRIMITIVES_BAKE_CONFIG_H 18 | #define PRIMITIVES_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/cpp/02_primitives/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "primitives", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ], 11 | "language": "c++" 12 | } 13 | } -------------------------------------------------------------------------------- /examples/cpp/02_primitives/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | ECS_STRUCT(Primitives, { 5 | bool a_bool; 6 | char a_char; 7 | flecs::byte_t a_byte; 8 | int32_t an_int; 9 | uint32_t a_uint; 10 | float a_float; 11 | const char *a_string; 12 | }) 13 | 14 | int main(int, char *[]) { 15 | flecs::world ecs; 16 | 17 | /* Import meta module */ 18 | ecs.import(); 19 | 20 | /* Insert the meta definitions for Primitives. This will also register the 21 | * Primitives type as a component */ 22 | flecs::meta(ecs); 23 | 24 | /* Create an instance of the Primitives type */ 25 | Primitives p; 26 | p.a_bool = true; 27 | p.a_char = 'a'; 28 | p.a_byte = 16; 29 | p.an_int = -10; 30 | p.a_uint = 10; 31 | p.a_float = 20.5; 32 | p.a_string = "Hello World"; 33 | 34 | /* Pretty print the value */ 35 | std::cout << flecs::pretty_print(ecs, p) << std::endl; 36 | } 37 | -------------------------------------------------------------------------------- /examples/cpp/03_enum/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/cpp/03_enum/include/enum.h: -------------------------------------------------------------------------------- 1 | #ifndef ENUM_H 2 | #define ENUM_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "enum/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/cpp/03_enum/include/enum/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef ENUM_BAKE_CONFIG_H 18 | #define ENUM_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/cpp/03_enum/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "enum", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ], 11 | "language": "c++" 12 | } 13 | } -------------------------------------------------------------------------------- /examples/cpp/03_enum/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | ECS_ENUM(Color, { 5 | Red, 6 | Green, 7 | Blue 8 | }) 9 | 10 | ECS_STRUCT(Vert2D, { 11 | float x; 12 | float y; 13 | Color color; 14 | }) 15 | 16 | int main(int argc, char *argv[]) { 17 | flecs::world world(argc, argv); 18 | 19 | /* Import meta module */ 20 | flecs::import(world); 21 | 22 | /* Insert the meta definitions */ 23 | flecs::meta(world); 24 | flecs::meta(world); 25 | 26 | /* Create an instance of the Vert2D type */ 27 | Vert2D v = {10, 20, Green }; 28 | 29 | /* Pretty print the value */ 30 | std::cout << flecs::pretty_print(world, v) << std::endl; 31 | } 32 | -------------------------------------------------------------------------------- /examples/cpp/04_bitmask/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/cpp/04_bitmask/include/bitmask.h: -------------------------------------------------------------------------------- 1 | #ifndef BITMASK_H 2 | #define BITMASK_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "bitmask/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/cpp/04_bitmask/include/bitmask/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef BITMASK_BAKE_CONFIG_H 18 | #define BITMASK_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/cpp/04_bitmask/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "bitmask", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ], 11 | "language": "c++" 12 | } 13 | } -------------------------------------------------------------------------------- /examples/cpp/04_bitmask/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | ECS_BITMASK(Toppings, { 5 | Bacon = 0x1, 6 | Lettuce = 0x2, 7 | Tomato = 0x4, 8 | Onion = 0x8, 9 | Egg = 0x10, 10 | Turkey = 0x20 11 | }) 12 | 13 | ECS_STRUCT(Sandwich, { 14 | const char *name; 15 | flecs::bitmask toppings; 16 | }) 17 | 18 | int main(int argc, char *argv[]) { 19 | flecs::world world(argc, argv); 20 | 21 | /* Import meta module */ 22 | flecs::import(world); 23 | 24 | /* Insert the meta definitions */ 25 | flecs::meta(world); 26 | flecs::meta(world); 27 | 28 | /* Create an instance of the Sandwich type */ 29 | Sandwich s = { "BLT", Bacon | Lettuce | Tomato }; 30 | 31 | /* Pretty print the value */ 32 | std::cout << flecs::pretty_print(world, s) << std::endl; 33 | } 34 | -------------------------------------------------------------------------------- /examples/cpp/05_array/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/cpp/05_array/include/array.h: -------------------------------------------------------------------------------- 1 | #ifndef ARRAY_H 2 | #define ARRAY_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "array/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/cpp/05_array/include/array/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef ARRAY_BAKE_CONFIG_H 18 | #define ARRAY_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/cpp/05_array/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "array", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ], 11 | "language": "c++" 12 | } 13 | } -------------------------------------------------------------------------------- /examples/cpp/05_array/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | ECS_STRUCT(Vert2D, { 5 | float coord[2]; 6 | }) 7 | 8 | int main(int argc, char *argv[]) { 9 | flecs::world world(argc, argv); 10 | 11 | /* Import meta module */ 12 | flecs::import(world); 13 | 14 | /* Insert the meta definitions */ 15 | flecs::meta(world); 16 | 17 | /* Create an instance of the Sandwich type */ 18 | Vert2D v = { { 10, 20 } }; 19 | 20 | /* Pretty print the value */ 21 | std::cout << flecs::pretty_print(world, v) << std::endl; 22 | } 23 | -------------------------------------------------------------------------------- /examples/cpp/06_vector/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/cpp/06_vector/include/vector.h: -------------------------------------------------------------------------------- 1 | #ifndef VECTOR_H 2 | #define VECTOR_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "vector/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/cpp/06_vector/include/vector/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef VECTOR_BAKE_CONFIG_H 18 | #define VECTOR_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/cpp/06_vector/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "vector", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ], 11 | "language": "c++" 12 | } 13 | } -------------------------------------------------------------------------------- /examples/cpp/06_vector/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | ECS_STRUCT(Vert2D, { 5 | float x; 6 | float y; 7 | }) 8 | 9 | ECS_STRUCT(Mesh, { 10 | flecs::vector vertices; 11 | }) 12 | 13 | int main(int argc, char *argv[]) { 14 | flecs::world world(argc, argv); 15 | 16 | /* Import meta module */ 17 | flecs::import(world); 18 | 19 | /* Insert the meta definitions */ 20 | flecs::meta(world); 21 | flecs::meta(world); 22 | 23 | /* Create an instance of the Mesh type */ 24 | Mesh m = { 25 | { 26 | {10.0f, 20.0f}, 27 | {30.0f, 40.0f}, 28 | {50.0f, 60.0f} 29 | } 30 | }; 31 | 32 | /* Pretty print the value */ 33 | std::cout << flecs::pretty_print(world, m) << std::endl; 34 | } 35 | -------------------------------------------------------------------------------- /examples/cpp/07_map/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/cpp/07_map/include/map.h: -------------------------------------------------------------------------------- 1 | #ifndef MAP_H 2 | #define MAP_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "map/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/cpp/07_map/include/map/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef MAP_BAKE_CONFIG_H 18 | #define MAP_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/cpp/07_map/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "map", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ], 11 | "language": "c++" 12 | } 13 | } -------------------------------------------------------------------------------- /examples/cpp/07_map/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | ECS_BITMASK(Toppings, { 5 | Bacon = 0x1, 6 | Lettuce = 0x2, 7 | Tomato = 0x4, 8 | Onion = 0x8, 9 | Egg = 0x10, 10 | Turkey = 0x20 11 | }) 12 | 13 | ECS_STRUCT(Sandwich, { 14 | int32_t cost; 15 | flecs::bitmask toppings; 16 | }) 17 | 18 | ECS_STRUCT(Menu, { 19 | flecs::map items; 20 | }) 21 | 22 | int main(int argc, char *argv[]) { 23 | flecs::world world(argc, argv); 24 | 25 | /* Import meta module */ 26 | flecs::import(world); 27 | 28 | /* Insert the meta definitions */ 29 | flecs::meta(world); 30 | flecs::meta(world); 31 | flecs::meta(world); 32 | 33 | /* Create an instance of the Menu type */ 34 | Menu m = { { 35 | {"BLT", {2, Bacon | Lettuce | Tomato}}, 36 | {"Turkey sub", {3, Turkey | Bacon | Onion}} 37 | } }; 38 | 39 | /* Pretty print the value */ 40 | std::cout << flecs::pretty_print(world, m) << std::endl; 41 | } 42 | -------------------------------------------------------------------------------- /examples/cpp/08_serialize_entity/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/cpp/08_serialize_entity/include/serialize_entity.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALIZE_ENTITY_H 2 | #define SERIALIZE_ENTITY_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "serialize_entity/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/cpp/08_serialize_entity/include/serialize_entity/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef SERIALIZE_ENTITY_BAKE_CONFIG_H 18 | #define SERIALIZE_ENTITY_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/cpp/08_serialize_entity/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "serialize_entity", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ], 11 | "language": "c++" 12 | } 13 | } -------------------------------------------------------------------------------- /examples/cpp/08_serialize_entity/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | ECS_STRUCT(Position, { 5 | float x; 6 | float y; 7 | }) 8 | 9 | ECS_ENUM(AgentKind, { 10 | Human, 11 | AI 12 | }) 13 | 14 | ECS_STRUCT(Agent, { 15 | AgentKind kind; 16 | }) 17 | 18 | int main(int argc, char *argv[]) { 19 | flecs::world world(argc, argv); 20 | 21 | /* Import meta module */ 22 | flecs::import(world); 23 | 24 | /* Insert the meta definitions */ 25 | flecs::meta(world); 26 | flecs::meta(world); 27 | flecs::meta(world); 28 | 29 | auto e = flecs::entity(world, "Player One") 30 | .set({10, 20}) 31 | .set({ Human }); 32 | 33 | /* Pretty print the player entity */ 34 | std::cout << flecs::pretty_print(world, e) << std::endl; 35 | } 36 | -------------------------------------------------------------------------------- /examples/cpp/09_serialize_type/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/cpp/09_serialize_type/include/serialize_type.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALIZE_TYPE_H 2 | #define SERIALIZE_TYPE_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "serialize_type/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/cpp/09_serialize_type/include/serialize_type/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef SERIALIZE_TYPE_BAKE_CONFIG_H 18 | #define SERIALIZE_TYPE_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/cpp/09_serialize_type/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "serialize_type", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ], 11 | "language": "c++" 12 | } 13 | } -------------------------------------------------------------------------------- /examples/cpp/09_serialize_type/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | ECS_STRUCT(Position, { 5 | float x; 6 | float y; 7 | }) 8 | 9 | int main(int argc, char *argv[]) { 10 | flecs::world world(argc, argv); 11 | 12 | /* Import meta module */ 13 | flecs::import(world); 14 | 15 | /* Insert the meta definitions */ 16 | auto position_type = flecs::meta(world); 17 | 18 | /* Pretty print the type. Because the type is an entity, the metadata is 19 | * stored in components that support reflection, we can serialize types. */ 20 | std::cout << flecs::pretty_print(world, position_type) << std::endl; 21 | } 22 | -------------------------------------------------------------------------------- /examples/cpp/10_runtime_type/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/cpp/10_runtime_type/include/runtime_type.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNTIME_TYPE_H 2 | #define RUNTIME_TYPE_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "runtime_type/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/cpp/10_runtime_type/include/runtime_type/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef RUNTIME_TYPE_BAKE_CONFIG_H 18 | #define RUNTIME_TYPE_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/cpp/10_runtime_type/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "runtime_type", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "use": [ 8 | "flecs", 9 | "flecs.meta" 10 | ], 11 | "language": "c++" 12 | } 13 | } -------------------------------------------------------------------------------- /examples/cpp/10_runtime_type/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Position { 5 | float x; 6 | float y; 7 | }; 8 | 9 | int main(int argc, char *argv[]) { 10 | flecs::world world(argc, argv); 11 | 12 | /* Import meta module */ 13 | flecs::import(world); 14 | 15 | auto position_type = flecs::entity(world, "Position") 16 | .set({ 17 | { 18 | {const_cast("x"), world.lookup("float").id()}, 19 | {const_cast("y"), world.lookup("float").id()} 20 | }, 21 | false 22 | }); 23 | 24 | /* Create a dummy value */ 25 | Position p = {10, 20}; 26 | 27 | /* Serialize the value to a string */ 28 | std::cout << flecs::pretty_print(world, position_type, p) << std::endl; 29 | } 30 | -------------------------------------------------------------------------------- /examples/cpp/11_nested_struct/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /examples/cpp/11_nested_struct/include/nested_struct.h: -------------------------------------------------------------------------------- 1 | #ifndef NESTED_STRUCT_H 2 | #define NESTED_STRUCT_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "nested_struct/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /examples/cpp/11_nested_struct/include/nested_struct/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef NESTED_STRUCT_BAKE_CONFIG_H 18 | #define NESTED_STRUCT_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /examples/cpp/11_nested_struct/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "nested_struct", 3 | "type": "application", 4 | "value": { 5 | "author": "Jane Doe", 6 | "description": "A simple hello world flecs application", 7 | "public": false, 8 | "use": [ 9 | "flecs", 10 | "flecs.meta" 11 | ], 12 | "language": "c++" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/cpp/11_nested_struct/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | ECS_STRUCT(Point, { 5 | int32_t x; 6 | int32_t y; 7 | }) 8 | 9 | ECS_STRUCT(Line, { 10 | Point start; 11 | Point stop; 12 | }) 13 | 14 | int main(int argc, char *argv[]) { 15 | flecs::world world(argc, argv); 16 | 17 | /* Import meta module */ 18 | flecs::import(world); 19 | 20 | /* Insert the meta definitions for Position. This will also register the 21 | * Position type as a component */ 22 | flecs::meta(world); 23 | flecs::meta(world); 24 | 25 | /* Create an instance of the Position type */ 26 | Line l = {{10, 20}, {30, 40}}; 27 | 28 | /* Pretty print the value */ 29 | std::cout << flecs::pretty_print(world, l) << std::endl; 30 | } 31 | -------------------------------------------------------------------------------- /include/flecs-meta/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef FLECS_META_BAKE_CONFIG_H 18 | #define FLECS_META_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | 23 | /* Convenience macro for exporting symbols */ 24 | #ifndef flecs_meta_STATIC 25 | #if flecs_meta_EXPORTS && (defined(_MSC_VER) || defined(__MINGW32__)) 26 | #define FLECS_META_API __declspec(dllexport) 27 | #elif flecs_meta_EXPORTS 28 | #define FLECS_META_API __attribute__((__visibility__("default"))) 29 | #elif defined _MSC_VER 30 | #define FLECS_META_API __declspec(dllimport) 31 | #else 32 | #define FLECS_META_API 33 | #endif 34 | #else 35 | #define FLECS_META_API 36 | #endif 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /include/flecs_meta.h: -------------------------------------------------------------------------------- 1 | #ifndef FLECS_META_H 2 | #define FLECS_META_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "flecs-meta/bake_config.h" 6 | 7 | #ifndef FLECS_LEGACY 8 | //////////////////////////////////////////////////////////////////////////////// 9 | //// Utility macro's (do not use in code!) 10 | //////////////////////////////////////////////////////////////////////////////// 11 | 12 | /** Translate C type to metatype. */ 13 | #define ecs_meta(name) FLECS__D##name 14 | 15 | #define ECS_ENUM_BOOTSTRAP(name, ...)\ 16 | typedef enum name __VA_ARGS__ name;\ 17 | ECS_UNUSED \ 18 | static const char * ecs_meta(name) = #__VA_ARGS__; 19 | 20 | #define ECS_STRUCT_IMPL(name, descriptor, ...)\ 21 | typedef struct name __VA_ARGS__ name;\ 22 | ECS_UNUSED \ 23 | static EcsMetaType ecs_meta(name) = {EcsStructType, sizeof(name), ECS_ALIGNOF(name), descriptor, NULL}; 24 | 25 | #define ECS_ENUM_IMPL(name, descriptor, ...)\ 26 | typedef enum name __VA_ARGS__ name;\ 27 | ECS_UNUSED \ 28 | static EcsMetaType ecs_meta(name) = {EcsEnumType, sizeof(name), ECS_ALIGNOF(name), descriptor, NULL}; 29 | 30 | #define ECS_BITMASK_IMPL(name, descriptor, ...)\ 31 | typedef enum name __VA_ARGS__ name;\ 32 | ECS_UNUSED \ 33 | static EcsMetaType ecs_meta(name) = {EcsBitmaskType, sizeof(name), ECS_ALIGNOF(name), descriptor, NULL}; 34 | 35 | #define ECS_STRUCT_C(T, ...) ECS_STRUCT_IMPL(T, #__VA_ARGS__, __VA_ARGS__) 36 | #define ECS_ENUM_C(T, ...) ECS_ENUM_IMPL(T, #__VA_ARGS__, __VA_ARGS__) 37 | #define ECS_BITMASK_C(T, ...) ECS_BITMASK_IMPL(T, #__VA_ARGS__, __VA_ARGS__) 38 | 39 | #define ECS_ARRAY(name, T, length)\ 40 | typedef T name[length];\ 41 | ECS_UNUSED \ 42 | static EcsMetaType ecs_meta(name) = {EcsArrayType, sizeof(T) * length, ECS_ALIGNOF(T), "(" #T "," #length ")", NULL} 43 | 44 | #define ECS_VECTOR(name, T)\ 45 | typedef ecs_vector_t *name;\ 46 | ECS_UNUSED \ 47 | static EcsMetaType ecs_meta(name) = {EcsVectorType, sizeof(ecs_vector_t*), ECS_ALIGNOF(ecs_vector_t*), "(" #T ")", NULL} 48 | 49 | #define ECS_MAP(name, K, T)\ 50 | typedef ecs_map_t *name;\ 51 | ECS_UNUSED \ 52 | static EcsMetaType ecs_meta(name) = {EcsMapType, sizeof(ecs_map_t*), ECS_ALIGNOF(ecs_map_t*), "(" #K "," #T ")", NULL} 53 | 54 | #ifdef __cplusplus 55 | 56 | // Unspecialized class (see below) 57 | namespace flecs { 58 | template 59 | class __meta__ { }; 60 | } 61 | 62 | // Specialized C++ class that stores name and descriptor of type 63 | #define ECS_META_CPP(T, kind, descr)\ 64 | namespace flecs {\ 65 | template<>\ 66 | class __meta__ {\ 67 | public:\ 68 | static const char* name() {\ 69 | return #T;\ 70 | }\ 71 | static EcsMetaType descriptor() {\ 72 | return {kind, sizeof(T), ECS_ALIGNOF(T), descr, NULL};\ 73 | }\ 74 | };\ 75 | } 76 | 77 | #endif 78 | 79 | 80 | //////////////////////////////////////////////////////////////////////////////// 81 | //// Use these macro's to define types. 82 | //// The API will automatically select the right macro's for C or C++ 83 | //////////////////////////////////////////////////////////////////////////////// 84 | 85 | #ifdef __cplusplus 86 | 87 | // C++ 88 | 89 | // Define a struct 90 | #define ECS_STRUCT(T, ...)\ 91 | ECS_STRUCT_IMPL(T, #__VA_ARGS__, __VA_ARGS__)\ 92 | ECS_META_CPP(T, EcsStructType, #__VA_ARGS__) 93 | 94 | // Define an enumeration 95 | #define ECS_ENUM(T, ...)\ 96 | ECS_ENUM_IMPL(T, #__VA_ARGS__, __VA_ARGS__)\ 97 | ECS_META_CPP(T, EcsEnumType, #__VA_ARGS__) 98 | 99 | // Define a bitmask 100 | #define ECS_BITMASK(T, ...)\ 101 | ECS_BITMASK_IMPL(T, #__VA_ARGS__, __VA_ARGS__)\ 102 | ECS_META_CPP(T, EcsBitmaskType, #__VA_ARGS__) 103 | 104 | #else 105 | 106 | // C 107 | 108 | // Define a struct 109 | #define ECS_STRUCT(name, ...)\ 110 | ECS_STRUCT_IMPL(name, #__VA_ARGS__, __VA_ARGS__) 111 | 112 | // Define an enumeration 113 | #define ECS_ENUM(name, ...)\ 114 | ECS_ENUM_IMPL(name, #__VA_ARGS__, __VA_ARGS__) 115 | 116 | // Define a bitmask 117 | #define ECS_BITMASK(name, ...)\ 118 | ECS_BITMASK_IMPL(name, #__VA_ARGS__, __VA_ARGS__) 119 | 120 | // Define a type alias 121 | #define ECS_ALIAS(type, name)\ 122 | typedef type name;\ 123 | ECS_UNUSED \ 124 | static EcsMetaType ecs_meta(name) = {0, sizeof(name), ECS_ALIGNOF(name), NULL, &ecs_meta(type)};\ 125 | 126 | #endif 127 | 128 | 129 | //////////////////////////////////////////////////////////////////////////////// 130 | //// Use these macro's inside types 131 | //////////////////////////////////////////////////////////////////////////////// 132 | 133 | // Define a vector 134 | #define ecs_vector(T) ecs_vector_t* 135 | 136 | // Define a map 137 | #define ecs_map(K, T) ecs_map_t* 138 | 139 | // Indicate that members after this should not be serialized 140 | #define ECS_PRIVATE 141 | 142 | 143 | //////////////////////////////////////////////////////////////////////////////// 144 | //// Meta description types 145 | //////////////////////////////////////////////////////////////////////////////// 146 | 147 | /* Explicit string type */ 148 | typedef const char* ecs_string_t; 149 | 150 | /* Explicit byte type */ 151 | typedef uint8_t ecs_byte_t; 152 | 153 | #ifdef __cplusplus 154 | 155 | namespace flecs { 156 | using string_t = ecs_string_t; 157 | using byte_t = ecs_byte_t; 158 | 159 | // Define a bitmask 160 | // In C++ trying to assign multiple flags to a variable of an enum type will 161 | // result in a compiler error. Use this template so that the serializer knows 162 | // this value is a bitmask, while also keeping the compiler happy. 163 | template 164 | using bitmask = int32_t; 165 | } 166 | 167 | #endif 168 | 169 | ECS_ENUM_BOOTSTRAP( ecs_type_kind_t, { 170 | EcsPrimitiveType, 171 | EcsBitmaskType, 172 | EcsEnumType, 173 | EcsStructType, 174 | EcsArrayType, 175 | EcsVectorType, 176 | EcsMapType 177 | }) 178 | 179 | ECS_STRUCT( EcsMetaType, { 180 | ecs_type_kind_t kind; 181 | ecs_size_t size; 182 | int16_t alignment; 183 | const char *descriptor; 184 | void *alias; 185 | }) 186 | 187 | ECS_ENUM( ecs_primitive_kind_t, { 188 | EcsBool, 189 | EcsChar, 190 | EcsByte, 191 | EcsU8, 192 | EcsU16, 193 | EcsU32, 194 | EcsU64, 195 | EcsI8, 196 | EcsI16, 197 | EcsI32, 198 | EcsI64, 199 | EcsF32, 200 | EcsF64, 201 | EcsUPtr, 202 | EcsIPtr, 203 | EcsString, 204 | EcsEntity 205 | }) 206 | 207 | ECS_STRUCT( EcsPrimitive, { 208 | ecs_primitive_kind_t kind; 209 | }) 210 | 211 | // Define EcsBitmask for both C and C++. Both representations are equivalent in 212 | // memory, but allow for a nicer type-safe API in C++ 213 | #if defined(__cplusplus) && !defined(FLECS_NO_CPP) 214 | ECS_STRUCT( EcsBitmask, { 215 | flecs::map constants; 216 | }) 217 | #else 218 | ECS_STRUCT( EcsBitmask, { 219 | ecs_map(int32_t, ecs_string_t) constants; 220 | }) 221 | #endif 222 | 223 | // Define EcsEnum for both C and C++. Both representations are equivalent in 224 | // memory, but allow for a nicer type-safe API in C++ 225 | #if defined(__cplusplus) && !defined(FLECS_NO_CPP) 226 | ECS_STRUCT( EcsEnum, { 227 | flecs::map constants; 228 | }) 229 | #else 230 | ECS_STRUCT( EcsEnum, { 231 | ecs_map(int32_t, ecs_string_t) constants; 232 | }) 233 | #endif 234 | 235 | ECS_STRUCT( EcsMember, { 236 | char *name; 237 | ecs_entity_t type; 238 | }) 239 | 240 | // Define EcsStruct for both C and C++. Both representations are equivalent in 241 | // memory, but allow for a nicer type-safe API in C++ 242 | #if defined(__cplusplus) && !defined(FLECS_NO_CPP) 243 | ECS_STRUCT( EcsStruct, { 244 | flecs::vector members; 245 | bool is_partial; 246 | }) 247 | #else 248 | ECS_STRUCT( EcsStruct, { 249 | ecs_vector(EcsMember) members; 250 | bool is_partial; 251 | }) 252 | #endif 253 | 254 | ECS_STRUCT( EcsArray, { 255 | ecs_entity_t element_type; 256 | int32_t count; 257 | }) 258 | 259 | ECS_STRUCT( EcsVector, { 260 | ecs_entity_t element_type; 261 | }) 262 | 263 | ECS_STRUCT( EcsMap, { 264 | ecs_entity_t key_type; 265 | ecs_entity_t element_type; 266 | }) 267 | 268 | 269 | //////////////////////////////////////////////////////////////////////////////// 270 | //// Type serializer 271 | //////////////////////////////////////////////////////////////////////////////// 272 | 273 | ECS_ENUM_C( ecs_type_op_kind_t, { 274 | EcsOpHeader, 275 | EcsOpPrimitive, 276 | EcsOpEnum, 277 | EcsOpBitmask, 278 | EcsOpPush, 279 | EcsOpPop, 280 | EcsOpArray, 281 | EcsOpVector, 282 | EcsOpMap 283 | }) 284 | 285 | typedef ecs_vector_t ecs_type_op_vector_t; 286 | typedef ecs_vector_t ecs_constant_vector_t; 287 | 288 | ECS_STRUCT_C( ecs_type_op_t, { 289 | ecs_entity_t type; 290 | ecs_type_op_kind_t kind; 291 | ecs_size_t size; /* Size of value or element type if array or vector */ 292 | int16_t alignment; /* Alignment of value */ 293 | int32_t count; /* Number of array elements or struct members */ 294 | int32_t offset; /* Offset of value */ 295 | const char *name; /* Name of value (only used for struct members) */ 296 | 297 | ECS_PRIVATE 298 | 299 | /* Instruction-specific data */ 300 | union { 301 | ecs_primitive_kind_t primitive; 302 | ecs_ref_t constant; 303 | ecs_ref_t collection; 304 | 305 | struct { 306 | ecs_ref_t key; 307 | ecs_ref_t element; 308 | } map; 309 | } is; 310 | }) 311 | 312 | ECS_STRUCT_C( EcsMetaTypeSerializer, { 313 | ecs_vector(ecs_type_op_t) ops; 314 | }) 315 | 316 | #endif 317 | 318 | #ifdef __cplusplus 319 | extern "C" { 320 | #endif 321 | 322 | 323 | //////////////////////////////////////////////////////////////////////////////// 324 | //// Pretty printer 325 | //////////////////////////////////////////////////////////////////////////////// 326 | 327 | /** Convert value to a string. */ 328 | FLECS_META_API 329 | char* ecs_ptr_to_str( 330 | ecs_world_t *world, 331 | ecs_entity_t type, 332 | void* ptr); 333 | 334 | /** Convert value to a string. */ 335 | FLECS_META_API 336 | char* ecs_entity_to_str( 337 | ecs_world_t *world, 338 | ecs_entity_t entity); 339 | 340 | 341 | //////////////////////////////////////////////////////////////////////////////// 342 | //// Serialization utilities 343 | //////////////////////////////////////////////////////////////////////////////// 344 | 345 | #define ECS_MAX_I8 127 346 | #define ECS_MIN_I8 -128 347 | 348 | #define ECS_MAX_I16 32767 349 | #define ECS_MIN_I16 -32768 350 | 351 | #define ECS_MAX_I32 2147483647 352 | #define ECS_MIN_I32 -2147483648 353 | 354 | #define ECS_MAX_I64 9223372036854775807 355 | #define ECS_MIN_I64 (-9223372036854775807 - 1) 356 | 357 | #define ECS_MAX_U8 255u 358 | #define ECS_MAX_U16 65535u 359 | #define ECS_MAX_U32 4294967295u 360 | #define ECS_MAX_U64 18446744073709551615u 361 | 362 | #define ECS_MAX_I8_STR "127" 363 | #define ECS_MIN_I8_STR "-128" 364 | 365 | #define ECS_MAX_I16_STR "32767" 366 | #define ECS_MIN_I16_STR "-32768" 367 | 368 | #define ECS_MAX_I32_STR "2147483647" 369 | #define ECS_MIN_I32_STR "-2147483648" 370 | 371 | #define ECS_MAX_I64_STR "9223372036854775807" 372 | #define ECS_MIN_I64_STR "-9223372036854775808" 373 | 374 | #define ECS_MAX_U8_STR "255" 375 | #define ECS_MAX_U16_STR "65535" 376 | #define ECS_MAX_U32_STR "4294967295" 377 | #define ECS_MAX_U64_STR "18446744073709551615" 378 | 379 | /** Escape a character */ 380 | FLECS_META_API 381 | char* ecs_chresc( 382 | char *out, 383 | char in, 384 | char delimiter); 385 | 386 | /** Parse an escaped character */ 387 | FLECS_META_API 388 | const char* ecs_chrparse( 389 | const char *in, 390 | char *out); 391 | 392 | /** Escape a string */ 393 | FLECS_META_API 394 | ecs_size_t ecs_stresc( 395 | char *out, 396 | ecs_size_t n, 397 | char delimiter, 398 | const char *in); 399 | 400 | #ifdef __cplusplus 401 | } 402 | #endif 403 | 404 | 405 | //////////////////////////////////////////////////////////////////////////////// 406 | //// Deserialization API 407 | //////////////////////////////////////////////////////////////////////////////// 408 | 409 | #define ECS_META_MAX_SCOPE_DEPTH (32) /* >32 levels of nesting is not sane */ 410 | 411 | typedef struct ecs_meta_scope_t { 412 | ecs_entity_t type; 413 | ecs_vector_t *ops; 414 | int32_t start; 415 | int32_t cur_op; 416 | int32_t cur_elem; 417 | int32_t count; 418 | void *base; 419 | ecs_vector_t *vector; 420 | bool is_collection; 421 | } ecs_meta_scope_t; 422 | 423 | typedef struct ecs_meta_cursor_t { 424 | const ecs_world_t *world; 425 | ecs_meta_scope_t scope[ECS_META_MAX_SCOPE_DEPTH]; 426 | int32_t depth; 427 | } ecs_meta_cursor_t; 428 | 429 | FLECS_META_API 430 | ecs_meta_cursor_t ecs_meta_cursor( 431 | const ecs_world_t *world, 432 | ecs_entity_t type, 433 | void *base); 434 | 435 | FLECS_META_API 436 | void* ecs_meta_get_ptr( 437 | ecs_meta_cursor_t *cursor); 438 | 439 | FLECS_META_API 440 | int ecs_meta_next( 441 | ecs_meta_cursor_t *cursor); 442 | 443 | FLECS_META_API 444 | int ecs_meta_move( 445 | ecs_meta_cursor_t *cursor, 446 | int32_t pos); 447 | 448 | FLECS_META_API 449 | int ecs_meta_move_name( 450 | ecs_meta_cursor_t *cursor, 451 | const char *name); 452 | 453 | FLECS_META_API 454 | int ecs_meta_push( 455 | ecs_meta_cursor_t *cursor); 456 | 457 | FLECS_META_API 458 | int ecs_meta_pop( 459 | ecs_meta_cursor_t *cursor); 460 | 461 | FLECS_META_API 462 | int ecs_meta_set_bool( 463 | ecs_meta_cursor_t *cursor, 464 | bool value); 465 | 466 | FLECS_META_API 467 | int ecs_meta_set_char( 468 | ecs_meta_cursor_t *cursor, 469 | char value); 470 | 471 | FLECS_META_API 472 | int ecs_meta_set_int( 473 | ecs_meta_cursor_t *cursor, 474 | int64_t value); 475 | 476 | FLECS_META_API 477 | int ecs_meta_set_uint( 478 | ecs_meta_cursor_t *cursor, 479 | uint64_t value); 480 | 481 | FLECS_META_API 482 | int ecs_meta_set_float( 483 | ecs_meta_cursor_t *cursor, 484 | double value); 485 | 486 | FLECS_META_API 487 | int ecs_meta_set_string( 488 | ecs_meta_cursor_t *cursor, 489 | const char *value); 490 | 491 | FLECS_META_API 492 | int ecs_meta_set_entity( 493 | ecs_meta_cursor_t *cursor, 494 | ecs_entity_t value); 495 | 496 | FLECS_META_API 497 | int ecs_meta_set_null( 498 | ecs_meta_cursor_t *cursor); 499 | 500 | 501 | //////////////////////////////////////////////////////////////////////////////// 502 | //// Module implementation 503 | //////////////////////////////////////////////////////////////////////////////// 504 | 505 | typedef struct FlecsMeta { 506 | ECS_DECLARE_COMPONENT(EcsPrimitive); 507 | ECS_DECLARE_COMPONENT(EcsEnum); 508 | ECS_DECLARE_COMPONENT(EcsBitmask); 509 | ECS_DECLARE_COMPONENT(EcsStruct); 510 | ECS_DECLARE_COMPONENT(EcsArray); 511 | ECS_DECLARE_COMPONENT(EcsVector); 512 | ECS_DECLARE_COMPONENT(EcsMap); 513 | ECS_DECLARE_COMPONENT(EcsMetaType); 514 | ECS_DECLARE_COMPONENT(EcsMetaTypeSerializer); 515 | } FlecsMeta; 516 | 517 | #ifdef __cplusplus 518 | extern "C" { 519 | #endif 520 | 521 | FLECS_META_API extern ECS_COMPONENT_DECLARE(EcsPrimitive); 522 | FLECS_META_API extern ECS_COMPONENT_DECLARE(EcsEnum); 523 | FLECS_META_API extern ECS_COMPONENT_DECLARE(EcsBitmask); 524 | FLECS_META_API extern ECS_COMPONENT_DECLARE(EcsMember); 525 | FLECS_META_API extern ECS_COMPONENT_DECLARE(EcsStruct); 526 | FLECS_META_API extern ECS_COMPONENT_DECLARE(EcsArray); 527 | FLECS_META_API extern ECS_COMPONENT_DECLARE(EcsVector); 528 | FLECS_META_API extern ECS_COMPONENT_DECLARE(EcsMap); 529 | FLECS_META_API extern ECS_COMPONENT_DECLARE(EcsMetaType); 530 | FLECS_META_API extern ECS_COMPONENT_DECLARE(ecs_type_op_kind_t); 531 | FLECS_META_API extern ECS_COMPONENT_DECLARE(ecs_type_op_t); 532 | FLECS_META_API extern ECS_COMPONENT_DECLARE(EcsMetaTypeSerializer); 533 | 534 | FLECS_META_API 535 | void FlecsMetaImport( 536 | ecs_world_t *world); 537 | 538 | #define FlecsMetaImportHandles(handles) 539 | 540 | //////////////////////////////////////////////////////////////////////////////// 541 | //// Macro for inserting metadata in C application 542 | //////////////////////////////////////////////////////////////////////////////// 543 | 544 | FLECS_META_API 545 | void ecs_new_meta( 546 | ecs_world_t *world, 547 | ecs_entity_t component, 548 | struct EcsMetaType *meta_type); 549 | 550 | #define ECS_META(world, T)\ 551 | ECS_COMPONENT(world, T);\ 552 | ecs_new_meta(world, ecs_id(T), &ecs_meta(T)); 553 | 554 | /** Define a meta component, store in variable outside of the current scope. 555 | * Use this macro in a header when defining a component identifier globally. 556 | * Must be used together with ECS_COMPONENT_DECLARE. 557 | */ 558 | #define ECS_META_DEFINE(world, T)\ 559 | ECS_COMPONENT_DEFINE(world, T);\ 560 | ecs_new_meta(world, ecs_id(T), &ecs_meta(T)); 561 | 562 | #ifdef __cplusplus 563 | } 564 | #endif 565 | 566 | 567 | //////////////////////////////////////////////////////////////////////////////// 568 | //// C++ Module implementation 569 | //////////////////////////////////////////////////////////////////////////////// 570 | 571 | #ifdef __cplusplus 572 | #ifndef FLECS_NO_CPP 573 | 574 | namespace flecs { 575 | namespace components { 576 | 577 | class meta { 578 | public: 579 | using Primitive = EcsPrimitive; 580 | using Enum = EcsEnum; 581 | using Bitmask = EcsBitmask; 582 | using Struct = EcsStruct; 583 | using Array = EcsArray; 584 | using Vector = EcsVector; 585 | using Type = EcsMetaType; 586 | using TypeSerializer = EcsMetaTypeSerializer; 587 | 588 | enum TypeKind { 589 | PrimitiveType = EcsPrimitiveType, 590 | BitmaskType = EcsBitmaskType, 591 | EnumType = EcsEnumType, 592 | StructType = EcsStructType, 593 | ArrayType = EcsArrayType, 594 | VectorType = EcsVectorType, 595 | MapType = EcsMapType 596 | }; 597 | 598 | meta(flecs::world& world) { 599 | FlecsMetaImport(world); 600 | 601 | world.module("flecs::components::meta"); 602 | 603 | world.component("EcsPrimitive"); 604 | world.component("EcsEnum"); 605 | world.component("EcsBitmask"); 606 | world.component("EcsStruct"); 607 | world.component("EcsArray"); 608 | world.component("EcsVector"); 609 | world.component("EcsMetaType"); 610 | world.component("EcsMetaTypeSerializer"); 611 | } 612 | }; 613 | } 614 | 615 | //////////////////////////////////////////////////////////////////////////////// 616 | //// Functions for inserting metadata in C++ applications 617 | //////////////////////////////////////////////////////////////////////////////// 618 | 619 | // Template that injects metadata into ECS 620 | template 621 | flecs::entity meta(flecs::world& world) { 622 | flecs::entity e = flecs::component(world, flecs::__meta__::name()); 623 | e.set({ flecs::__meta__::descriptor() }); 624 | return e; 625 | } 626 | 627 | 628 | //////////////////////////////////////////////////////////////////////////////// 629 | //// Serialize values to string 630 | //////////////////////////////////////////////////////////////////////////////// 631 | 632 | template 633 | flecs::string pretty_print(flecs::world& world, flecs::entity_t type, T& data) { 634 | char *str = ecs_ptr_to_str(world.c_ptr(), type, &data); 635 | flecs::string result = flecs::string(str); 636 | return result; 637 | } 638 | 639 | template 640 | flecs::string pretty_print(flecs::world& world, flecs::entity type, T& data) { 641 | return pretty_print(world, type.id(), data); 642 | } 643 | 644 | template 645 | flecs::string pretty_print(flecs::world& world, T& data) { 646 | entity_t type = _::cpp_type::id(); 647 | return flecs::pretty_print(world, type, data); 648 | } 649 | 650 | template <> 651 | inline flecs::string pretty_print(flecs::world& world, flecs::entity& entity) { 652 | char *str = ecs_entity_to_str(world.c_ptr(), entity.id()); 653 | flecs::string result = flecs::string(str); 654 | return result; 655 | } 656 | 657 | } 658 | 659 | #endif // FLECS_NO_CPP 660 | #endif // __cplusplus 661 | 662 | #endif // FLECS_META_H 663 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('flecs-meta', 'c', version : '2.0') 2 | 3 | flecs_dep = dependency('flecs') 4 | 5 | meta_args = [] 6 | 7 | if get_option('default_library') == 'static' 8 | meta_args = '-Dflecs_meta_STATIC' 9 | endif 10 | 11 | meta_inc = include_directories('include') 12 | 13 | meta_src = files( 14 | 'src/deserializer.c', 15 | 'src/main.c', 16 | 'src/parser.c', 17 | 'src/pretty_print.c', 18 | 'src/serializer.c', 19 | 'src/type.c', 20 | 'src/util.c' 21 | ) 22 | 23 | meta_lib = library('flecs-meta', 24 | meta_src, 25 | dependencies : flecs_dep, 26 | include_directories : meta_inc, 27 | c_args : [ '-Dflecs_meta_EXPORTS', meta_args ], 28 | implicit_include_directories : false 29 | ) 30 | 31 | meta_dep = declare_dependency( 32 | link_with : meta_lib, 33 | compile_args : meta_args, 34 | dependencies : flecs_dep, 35 | include_directories : meta_inc 36 | ) 37 | 38 | executable('struct', 39 | 'examples/c/01_struct/src/main.c', 40 | include_directories : 'examples/c/01_struct/include', 41 | dependencies : meta_dep, 42 | implicit_include_directories : false 43 | ) 44 | 45 | if meson.version().version_compare('>= 0.54.0') 46 | meson.override_dependency('flecs-meta', meta_dep) 47 | endif -------------------------------------------------------------------------------- /project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "flecs.meta", 3 | "type": "package", 4 | "value": { 5 | "author": "Sander Mertens", 6 | "description": "Flecs module package", 7 | "amalgamate": true, 8 | "use": [ 9 | "flecs" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/deserializer.c: -------------------------------------------------------------------------------- 1 | #include "flecs_meta.h" 2 | 3 | static 4 | ecs_meta_scope_t* get_scope( 5 | ecs_meta_cursor_t *cursor) 6 | { 7 | ecs_assert(cursor != NULL, ECS_INVALID_PARAMETER, NULL); 8 | return &cursor->scope[cursor->depth]; 9 | } 10 | 11 | static 12 | ecs_type_op_t* get_op( 13 | ecs_meta_scope_t *scope) 14 | { 15 | ecs_type_op_t *ops = ecs_vector_first(scope->ops, ecs_type_op_t); 16 | ecs_assert(ops != NULL, ECS_INVALID_PARAMETER, NULL); 17 | return &ops[scope->cur_op]; 18 | } 19 | 20 | static 21 | ecs_type_op_t* get_ptr( 22 | ecs_meta_scope_t *scope) 23 | { 24 | ecs_type_op_t *op = get_op(scope); 25 | 26 | if (scope->vector) { 27 | _ecs_vector_set_min_count(&scope->vector, ECS_VECTOR_U(op->size, op->alignment), scope->cur_elem + 1); 28 | scope->base = ecs_vector_first_t(scope->vector, op->size, op->alignment); 29 | } 30 | 31 | return ECS_OFFSET(scope->base, op->offset + op->size * scope->cur_elem); 32 | } 33 | 34 | ecs_meta_cursor_t ecs_meta_cursor( 35 | const ecs_world_t *world, 36 | ecs_entity_t type, 37 | void *base) 38 | { 39 | ecs_assert(world != NULL, ECS_INVALID_PARAMETER, NULL); 40 | ecs_assert(type != 0, ECS_INVALID_PARAMETER, NULL); 41 | ecs_assert(base != NULL, ECS_INVALID_PARAMETER, NULL); 42 | 43 | ecs_meta_cursor_t result; 44 | 45 | const EcsMetaTypeSerializer *ser = ecs_get(world, type, EcsMetaTypeSerializer); 46 | ecs_assert(ser != NULL, ECS_INVALID_PARAMETER, NULL); 47 | 48 | #ifndef NDEBUG 49 | ecs_type_op_t *ops = ecs_vector_first(ser->ops, ecs_type_op_t); 50 | ecs_assert(ops != NULL, ECS_INVALID_PARAMETER, NULL); 51 | ecs_assert(ops[0].kind == EcsOpHeader, ECS_INVALID_PARAMETER, NULL); 52 | #endif 53 | 54 | result.world = world; 55 | result.depth = 0; 56 | result.scope[0].type = type; 57 | result.scope[0].ops = ser->ops; 58 | result.scope[0].start = 1; 59 | result.scope[0].cur_op = 1; 60 | result.scope[0].cur_elem = 0; 61 | result.scope[0].base = base; 62 | result.scope[0].is_collection = false; 63 | result.scope[0].count = 0; 64 | result.scope[0].vector = NULL; 65 | 66 | return result; 67 | } 68 | 69 | void* ecs_meta_get_ptr( 70 | ecs_meta_cursor_t *cursor) 71 | { 72 | return get_ptr(cursor->scope); 73 | } 74 | 75 | int ecs_meta_next( 76 | ecs_meta_cursor_t *cursor) 77 | { 78 | ecs_meta_scope_t *scope = get_scope(cursor); 79 | int32_t ops_count = ecs_vector_count(scope->ops); 80 | 81 | if (scope->count) { 82 | if (scope->cur_op >= scope->count) { 83 | return -1; 84 | } 85 | } else { 86 | if (scope->cur_op >= ops_count) { 87 | return -1; 88 | } 89 | } 90 | 91 | if (scope->is_collection) { 92 | scope->cur_op = 1; 93 | scope->cur_elem ++; 94 | 95 | if (scope->count) { 96 | if (scope->cur_elem >= scope->count) { 97 | return -1; 98 | } 99 | } 100 | } else { 101 | scope->cur_op ++; 102 | } 103 | 104 | return 0; 105 | } 106 | 107 | int ecs_meta_move( 108 | ecs_meta_cursor_t *cursor, 109 | int32_t pos) 110 | { 111 | ecs_meta_scope_t *scope = get_scope(cursor); 112 | int32_t ops_count = ecs_vector_count(scope->ops); 113 | 114 | if(pos < 0) return -1; 115 | 116 | if (scope->is_collection) { 117 | if (scope->count) { 118 | if (pos >= scope->count) { 119 | return -1; 120 | } 121 | 122 | scope->cur_op = 1; 123 | scope->cur_elem = pos; 124 | } 125 | } else { 126 | if (pos >= ops_count) { 127 | return -1; 128 | } 129 | scope->cur_op = scope->start + pos; 130 | } 131 | 132 | return 0; 133 | } 134 | 135 | int ecs_meta_move_name( 136 | ecs_meta_cursor_t *cursor, 137 | const char *name) 138 | { 139 | ecs_meta_scope_t *scope = get_scope(cursor); 140 | ecs_type_op_t *ops = ecs_vector_first(scope->ops, ecs_type_op_t); 141 | int32_t i, ops_count = ecs_vector_count(scope->ops); 142 | int32_t depth = 1; 143 | 144 | for (i = scope->start; i < ops_count; i ++) { 145 | ecs_type_op_t *op = &ops[i]; 146 | 147 | if (depth <= 1) { 148 | if (op->name && !strcmp(op->name, name)) { 149 | scope->cur_op = i; 150 | return 0; 151 | } 152 | } 153 | 154 | if (op->kind == EcsOpPush) { 155 | depth ++; 156 | } 157 | 158 | if (op->kind == EcsOpPop) { 159 | depth --; 160 | if (depth < 0) { 161 | return -1; 162 | } 163 | } 164 | } 165 | 166 | return -1; 167 | } 168 | 169 | int ecs_meta_push( 170 | ecs_meta_cursor_t *cursor) 171 | { 172 | ecs_meta_scope_t *scope = get_scope(cursor); 173 | ecs_type_op_t *op = get_op(scope); 174 | 175 | if (scope->vector) { 176 | /* This makes sure the vector has enough space for the pushed element */ 177 | get_ptr(scope); 178 | } 179 | 180 | scope->cur_op ++; 181 | cursor->depth ++; 182 | ecs_meta_scope_t *child_scope = get_scope(cursor); 183 | child_scope->cur_elem = 0; 184 | 185 | switch(op->kind) { 186 | case EcsOpPush: { 187 | child_scope->base = ECS_OFFSET(scope->base, op->size * scope->cur_elem); 188 | child_scope->start = scope->cur_op; 189 | child_scope->cur_op = scope->cur_op; 190 | child_scope->ops = scope->ops; 191 | child_scope->is_collection = false; 192 | child_scope->count = 0; 193 | child_scope->vector = NULL; 194 | break; 195 | } 196 | case EcsOpArray: 197 | case EcsOpVector: { 198 | void *ptr = ECS_OFFSET(scope->base, op->offset); 199 | const EcsMetaTypeSerializer *ser = ecs_get_ref_w_id(cursor->world, 200 | &op->is.collection, 0, 0); 201 | ecs_assert(ser != NULL, ECS_INTERNAL_ERROR, NULL); 202 | 203 | ecs_vector_t *ops = ser->ops; 204 | 205 | if (op->kind == EcsOpArray) { 206 | child_scope->base = ptr; 207 | child_scope->count = op->count; 208 | child_scope->vector = NULL; 209 | } else { 210 | ecs_vector_t *v = *(ecs_vector_t**)ptr; 211 | if (!v) { 212 | v = ecs_vector_new_t(op->size, op->alignment, 2); 213 | } else { 214 | ecs_vector_set_count_t(&v, op->size, op->alignment, 0); 215 | } 216 | 217 | child_scope->base = ecs_vector_first_t(v, op->size, op->alignment); 218 | child_scope->count = 0; 219 | child_scope->vector = v; 220 | } 221 | child_scope->start = 1; 222 | child_scope->cur_op = 1; 223 | child_scope->ops = ops; 224 | child_scope->is_collection = true; 225 | #ifndef NDEBUG 226 | ecs_type_op_t *hdr = ecs_vector_first(child_scope->ops, ecs_type_op_t); 227 | ecs_assert(hdr->kind == EcsOpHeader, ECS_INTERNAL_ERROR, NULL); 228 | #endif 229 | } 230 | break; 231 | default: 232 | return -1; 233 | } 234 | 235 | return 0; 236 | } 237 | 238 | int ecs_meta_pop( 239 | ecs_meta_cursor_t *cursor) 240 | { 241 | ecs_meta_scope_t *scope = get_scope(cursor); 242 | ecs_type_op_t *ops = ecs_vector_first(scope->ops, ecs_type_op_t); 243 | int32_t i, ops_count = ecs_vector_count(scope->ops); 244 | 245 | if (scope->is_collection) { 246 | cursor->depth --; 247 | if (scope->vector) { 248 | /* Vector ptr may have changed, so reassign vector field */ 249 | ecs_meta_scope_t *parent_scope = get_scope(cursor); 250 | parent_scope->cur_op --; 251 | void *ptr = get_ptr(parent_scope); 252 | *(ecs_vector_t**)ptr = scope->vector; 253 | parent_scope->cur_op ++; 254 | } 255 | return 0; 256 | } else { 257 | for (i = scope->cur_op; i < ops_count; i ++) { 258 | ecs_type_op_t *op = &ops[i]; 259 | if (op->kind == EcsOpPop) { 260 | cursor->depth -- ; 261 | ecs_meta_scope_t *parent_scope = get_scope(cursor); 262 | if (parent_scope->is_collection) { 263 | parent_scope->cur_op = 1; 264 | parent_scope->cur_elem ++; 265 | } else { 266 | parent_scope->cur_op = i; 267 | } 268 | return 0; 269 | } 270 | } 271 | } 272 | 273 | return -1; 274 | } 275 | 276 | int ecs_meta_set_bool( 277 | ecs_meta_cursor_t *cursor, 278 | bool value) 279 | { 280 | ecs_meta_scope_t *scope = get_scope(cursor); 281 | ecs_type_op_t *op = get_op(scope); 282 | 283 | if (op->kind != EcsOpPrimitive || op->is.primitive != EcsBool) { 284 | return -1; 285 | } else { 286 | void *ptr = get_ptr(scope); 287 | *(bool*)ptr = value; 288 | return 0; 289 | } 290 | } 291 | 292 | int ecs_meta_set_char( 293 | ecs_meta_cursor_t *cursor, 294 | char value) 295 | { 296 | ecs_meta_scope_t *scope = get_scope(cursor); 297 | ecs_type_op_t *op = get_op(scope); 298 | 299 | if (op->kind != EcsOpPrimitive || op->is.primitive != EcsChar) { 300 | return -1; 301 | } else { 302 | void *ptr = get_ptr(scope); 303 | *(char*)ptr = value; 304 | return 0; 305 | } 306 | } 307 | 308 | int ecs_meta_set_int( 309 | ecs_meta_cursor_t *cursor, 310 | int64_t value) 311 | { 312 | ecs_meta_scope_t *scope = get_scope(cursor); 313 | ecs_type_op_t *op = get_op(scope); 314 | 315 | ecs_primitive_kind_t primitive = op->is.primitive; 316 | 317 | if (op->kind != EcsOpPrimitive) { 318 | if (op->kind == EcsOpEnum || op->kind == EcsOpBitmask) { 319 | primitive = EcsI32; 320 | } else { 321 | return -1; 322 | } 323 | } 324 | 325 | void *ptr = get_ptr(scope); 326 | 327 | switch(primitive) { 328 | case EcsBool: 329 | if (value > 1 || value < 0) { 330 | return -1; 331 | } 332 | *(bool*)ptr = (bool)value; 333 | break; 334 | case EcsI8: 335 | case EcsChar: 336 | if (value > INT8_MAX || value < INT8_MIN) { 337 | return -1; 338 | } 339 | *(int8_t*)ptr = (int8_t)value; 340 | break; 341 | case EcsU8: 342 | case EcsByte: 343 | if (value > UINT8_MAX || value < INT8_MIN) { 344 | return -1; 345 | } 346 | *(uint8_t*)ptr = (uint8_t)value; 347 | break; 348 | case EcsI16: 349 | if (value > INT16_MAX || value < INT16_MIN) { 350 | return -1; 351 | } 352 | *(int16_t*)ptr = (int16_t)value; 353 | break; 354 | case EcsU16: 355 | if (value > UINT16_MAX || value < INT16_MIN) { 356 | return -1; 357 | } 358 | *(uint16_t*)ptr = (uint16_t)value; 359 | break; 360 | case EcsI32: 361 | if (value > INT32_MAX || value < INT32_MIN) { 362 | return -1; 363 | } 364 | *(int32_t*)ptr = (int32_t)value; 365 | break; 366 | case EcsU32: 367 | if (value > UINT32_MAX || value < INT32_MIN) { 368 | return -1; 369 | } 370 | *(uint32_t*)ptr = (uint32_t)value; 371 | break; 372 | case EcsI64: 373 | if (value > INT64_MAX) { 374 | return -1; 375 | } 376 | *(int64_t*)ptr = (int64_t)value; 377 | break; 378 | case EcsU64: 379 | *(uint64_t*)ptr = (uint64_t)value; 380 | break; 381 | case EcsEntity: 382 | *(ecs_entity_t*)ptr = (ecs_entity_t)value; 383 | break; 384 | case EcsF32: 385 | if (value > ((1 << 24)-1) || value < -(1 << 24)) { 386 | return -1; 387 | } 388 | *(float*)ptr = (float)value; 389 | break; 390 | case EcsF64: 391 | if (value > ((1LL << 53)-1) || value < -(1LL << 53)) { 392 | return -1; 393 | } 394 | *(double*)ptr = (double)value; 395 | break; 396 | case EcsIPtr: 397 | if (value > INTPTR_MAX) { 398 | return -1; 399 | } 400 | *(intptr_t*)ptr = (intptr_t)value; 401 | break; 402 | case EcsUPtr: 403 | *(uintptr_t*)ptr = (uintptr_t)value; 404 | break; 405 | default: 406 | if(!value) return ecs_meta_set_null(cursor); 407 | return -1; 408 | } 409 | 410 | return 0; 411 | } 412 | 413 | int ecs_meta_set_uint( 414 | ecs_meta_cursor_t *cursor, 415 | uint64_t value) 416 | { 417 | ecs_meta_scope_t *scope = get_scope(cursor); 418 | ecs_type_op_t *op = get_op(scope); 419 | 420 | if (op->kind != EcsOpPrimitive) { 421 | return -1; 422 | } else { 423 | void *ptr = get_ptr(scope); 424 | 425 | switch(op->is.primitive) { 426 | case EcsU8: 427 | case EcsByte: 428 | if (value > UINT8_MAX) { 429 | return -1; 430 | } 431 | *(uint8_t*)ptr = (uint8_t)value; 432 | break; 433 | case EcsU16: 434 | if (value > UINT16_MAX) { 435 | return -1; 436 | } 437 | *(uint16_t*)ptr = (uint16_t)value; 438 | break; 439 | case EcsU32: 440 | if (value > UINT32_MAX) { 441 | return -1; 442 | } 443 | *(uint32_t*)ptr = (uint32_t)value; 444 | break; 445 | case EcsU64: 446 | if (value > UINT64_MAX) { 447 | return -1; 448 | } 449 | *(uint64_t*)ptr = (uint64_t)value; 450 | break; 451 | case EcsUPtr: 452 | if (value > UINTPTR_MAX) { 453 | return -1; 454 | } 455 | *(uintptr_t*)ptr = (uintptr_t)value; 456 | break; 457 | case EcsEntity: 458 | *(ecs_entity_t*)ptr = value; 459 | break; 460 | default: 461 | if(!value) return ecs_meta_set_null(cursor); 462 | return -1; 463 | } 464 | 465 | return 0; 466 | } 467 | } 468 | 469 | int ecs_meta_set_float( 470 | ecs_meta_cursor_t *cursor, 471 | double value) 472 | { 473 | ecs_meta_scope_t *scope = get_scope(cursor); 474 | ecs_type_op_t *op = get_op(scope); 475 | 476 | if (op->kind != EcsOpPrimitive) { 477 | return -1; 478 | } else { 479 | void *ptr = get_ptr(scope); 480 | 481 | switch(op->is.primitive) { 482 | case EcsF32: 483 | *(float*)ptr = (float)value; 484 | break; 485 | case EcsF64: 486 | *(double*)ptr = value; 487 | break; 488 | default: 489 | return -1; 490 | break; 491 | } 492 | 493 | return 0; 494 | } 495 | } 496 | 497 | int ecs_meta_set_string( 498 | ecs_meta_cursor_t *cursor, 499 | const char *value) 500 | { 501 | ecs_meta_scope_t *scope = get_scope(cursor); 502 | ecs_type_op_t *op = get_op(scope); 503 | 504 | if (op->kind != EcsOpPrimitive) { 505 | return -1; 506 | } else { 507 | void *ptr = get_ptr(scope); 508 | 509 | switch(op->is.primitive) { 510 | case EcsString: 511 | if (*(char**)ptr) { 512 | ecs_os_free(*(char**)ptr); 513 | } 514 | if (value) { 515 | *(char**)ptr = ecs_os_strdup(value); 516 | } else { 517 | *(char**)ptr = NULL; 518 | } 519 | break; 520 | default: 521 | return -1; 522 | break; 523 | } 524 | 525 | return 0; 526 | } 527 | } 528 | 529 | int ecs_meta_set_entity( 530 | ecs_meta_cursor_t *cursor, 531 | ecs_entity_t value) 532 | { 533 | ecs_meta_scope_t *scope = get_scope(cursor); 534 | ecs_type_op_t *op = get_op(scope); 535 | 536 | if (op->kind != EcsOpPrimitive) { 537 | return -1; 538 | } else { 539 | void *ptr = get_ptr(scope); 540 | 541 | switch(op->is.primitive) { 542 | case EcsEntity: 543 | *(ecs_entity_t*)ptr = value; 544 | break; 545 | default: 546 | return -1; 547 | break; 548 | } 549 | 550 | return 0; 551 | } 552 | } 553 | 554 | int ecs_meta_set_null( 555 | ecs_meta_cursor_t *cursor) 556 | { 557 | ecs_meta_scope_t *scope = get_scope(cursor); 558 | ecs_type_op_t *op = get_op(scope); 559 | 560 | switch(op->kind) { 561 | case EcsOpPrimitive: { 562 | if (op->is.primitive != EcsString) { 563 | return -1; 564 | } 565 | 566 | void *ptr = get_ptr(scope); 567 | char *str = *(char**)ptr; 568 | if (str) { 569 | ecs_os_free(str); 570 | } 571 | 572 | *(char**)ptr = NULL; 573 | break; 574 | } 575 | 576 | case EcsOpVector: { 577 | void *ptr = get_ptr(scope); 578 | ecs_vector_t *vec = *(ecs_vector_t**)ptr; 579 | if (vec) { 580 | ecs_vector_free(vec); 581 | } 582 | 583 | *(ecs_vector_t**)ptr = NULL; 584 | break; 585 | } 586 | 587 | default: 588 | return -1; 589 | break; 590 | } 591 | 592 | return 0; 593 | } 594 | -------------------------------------------------------------------------------- /src/parser.c: -------------------------------------------------------------------------------- 1 | #include "parser.h" 2 | #include 3 | #include 4 | 5 | static 6 | const char* skip_ws(const char *ptr) { 7 | while (isspace(*ptr)) { 8 | ptr ++; 9 | } 10 | 11 | return ptr; 12 | } 13 | 14 | static 15 | const char* skip_scope(const char *ptr, ecs_meta_parse_ctx_t *ctx) { 16 | /* Keep track of which characters were used to open the scope */ 17 | char stack[256]; 18 | int32_t sp = 0; 19 | char ch; 20 | 21 | while ((ch = *ptr)) { 22 | if (ch == '(') { 23 | stack[sp++] = ch; 24 | } else if (ch == '<') { 25 | stack[sp++] = ch; 26 | } else if (ch == '>') { 27 | if (stack[--sp] != '<') { 28 | ecs_meta_error(ctx, ptr, "mismatching < > in type definition"); 29 | } 30 | } else if (ch == ')') { 31 | if (stack[--sp] != '(') { 32 | ecs_meta_error(ctx, ptr, "mismatching ( ) in type definition"); 33 | } 34 | } 35 | 36 | ptr ++; 37 | 38 | if (!sp) { 39 | break; 40 | } 41 | } 42 | 43 | return ptr; 44 | } 45 | 46 | static 47 | const char* parse_digit( 48 | const char *ptr, 49 | int64_t *value_out, 50 | ecs_meta_parse_ctx_t *ctx) 51 | { 52 | ptr = skip_ws(ptr); 53 | 54 | if (!isdigit(*ptr) && *ptr != '-') { 55 | ecs_meta_error(ctx, ptr, "expected number, got %c", *ptr); 56 | } 57 | 58 | *value_out = strtol(ptr, NULL, 0); 59 | 60 | if (ptr[0] == '-') { 61 | ptr ++; 62 | } else 63 | if (ptr[0] == '0' && ptr[1] == 'x') { 64 | ptr += 2; 65 | } 66 | 67 | while (isdigit(*ptr)) { 68 | ptr ++; 69 | } 70 | 71 | return skip_ws(ptr); 72 | } 73 | 74 | static 75 | const char* parse_identifier( 76 | const char *ptr, 77 | char *buff, 78 | char *params, 79 | ecs_meta_parse_ctx_t *ctx) 80 | { 81 | ecs_assert(ptr != NULL, ECS_INTERNAL_ERROR, NULL); 82 | ecs_assert(buff != NULL, ECS_INTERNAL_ERROR, NULL); 83 | ecs_assert(ctx != NULL, ECS_INTERNAL_ERROR, NULL); 84 | 85 | char *bptr = buff, ch; 86 | 87 | if (params) { 88 | params[0] = '\0'; 89 | } 90 | 91 | /* Ignore whitespaces */ 92 | ptr = skip_ws(ptr); 93 | 94 | if (!isalpha(*ptr)) { 95 | ecs_meta_error(ctx, ptr, 96 | "invalid identifier (starts with '%c')", *ptr); 97 | } 98 | 99 | while ((ch = *ptr) && !isspace(ch) && ch != ';' && ch != ',' && ch != ')' && ch != '>') { 100 | /* Type definitions can contain macro's or templates */ 101 | if (ch == '(' || ch == '<') { 102 | if (!params) { 103 | ecs_meta_error(ctx, ptr, "unexpected %c", *ptr); 104 | } 105 | 106 | const char *end = skip_scope(ptr, ctx); 107 | ecs_os_strncpy(params, ptr, (ecs_size_t)(end - ptr)); 108 | params[end - ptr] = '\0'; 109 | 110 | ptr = end; 111 | } else { 112 | *bptr = ch; 113 | bptr ++; 114 | ptr ++; 115 | } 116 | } 117 | 118 | *bptr = '\0'; 119 | 120 | if (!ch) { 121 | ecs_meta_error(ctx, ptr, "unexpected end of token"); 122 | } 123 | 124 | return ptr; 125 | } 126 | 127 | static 128 | const char * ecs_meta_open_scope( 129 | const char *ptr, 130 | ecs_meta_parse_ctx_t *ctx) 131 | { 132 | /* Skip initial whitespaces */ 133 | ptr = skip_ws(ptr); 134 | 135 | /* Is this the start of the type definition? */ 136 | if (ctx->decl == ptr) { 137 | if (*ptr != '{') { 138 | ecs_meta_error(ctx, ptr, "missing '{' in struct definition"); 139 | } 140 | 141 | ptr ++; 142 | ptr = skip_ws(ptr); 143 | } 144 | 145 | /* Is this the end of the type definition? */ 146 | if (!*ptr) { 147 | ecs_meta_error(ctx, ptr, "missing '}' at end of struct definition"); 148 | } 149 | 150 | /* Is this the end of the type definition? */ 151 | if (*ptr == '}') { 152 | ptr = skip_ws(ptr + 1); 153 | if (*ptr) { 154 | ecs_meta_error(ctx, ptr, 155 | "stray characters after struct definition"); 156 | } 157 | return NULL; 158 | } 159 | 160 | return ptr; 161 | } 162 | 163 | const char* ecs_meta_parse_constant( 164 | const char *ptr, 165 | ecs_meta_constant_t *token, 166 | ecs_meta_parse_ctx_t *ctx) 167 | { 168 | ptr = ecs_meta_open_scope(ptr, ctx); 169 | if (!ptr) { 170 | return NULL; 171 | } 172 | 173 | token->is_value_set = false; 174 | 175 | /* Parse token, constant identifier */ 176 | ptr = parse_identifier(ptr, token->name, NULL, ctx); 177 | ptr = skip_ws(ptr); 178 | 179 | /* Explicit value assignment */ 180 | if (*ptr == '=') { 181 | int64_t value = 0; 182 | ptr = parse_digit(ptr + 1, &value, ctx); 183 | token->value = value; 184 | token->is_value_set = true; 185 | } 186 | 187 | /* Expect a ',' or '}' */ 188 | if (*ptr != ',' && *ptr != '}') { 189 | ecs_meta_error(ctx, ptr, "missing , after enum constant"); 190 | } 191 | 192 | if (*ptr == ',') { 193 | return ptr + 1; 194 | } else { 195 | return ptr; 196 | } 197 | } 198 | 199 | static 200 | const char* ecs_meta_parse_type( 201 | const char *ptr, 202 | ecs_meta_type_t *token, 203 | ecs_meta_parse_ctx_t *ctx) 204 | { 205 | token->is_ptr = false; 206 | token->is_const = false; 207 | 208 | ptr = skip_ws(ptr); 209 | 210 | /* Parse token, expect type identifier or ECS_PROPERTY */ 211 | ptr = parse_identifier(ptr, token->type, token->params, ctx); 212 | 213 | if (!strcmp(token->type, "ECS_PRIVATE")) { 214 | /* Members from this point are not stored in metadata */ 215 | return NULL; 216 | } 217 | 218 | /* If token is const, set const flag and continue parsing type */ 219 | if (!strcmp(token->type, "const")) { 220 | token->is_const = true; 221 | 222 | /* Parse type after const */ 223 | ptr = parse_identifier(ptr + 1, token->type, token->params, ctx); 224 | } 225 | 226 | /* Check if type is a pointer */ 227 | ptr = skip_ws(ptr); 228 | if (*ptr == '*') { 229 | token->is_ptr = true; 230 | ptr ++; 231 | } 232 | 233 | return ptr; 234 | } 235 | 236 | const char* ecs_meta_parse_member( 237 | const char *ptr, 238 | ecs_meta_member_t *token, 239 | ecs_meta_parse_ctx_t *ctx) 240 | { 241 | ptr = ecs_meta_open_scope(ptr, ctx); 242 | if (!ptr) { 243 | return NULL; 244 | } 245 | 246 | token->count = 1; 247 | token->is_partial = false; 248 | 249 | /* Parse member type */ 250 | ptr = ecs_meta_parse_type(ptr, &token->type, ctx); 251 | if (!ptr) { 252 | /* If NULL is returned, parsing should stop */ 253 | token->is_partial = true; 254 | return NULL; 255 | } 256 | 257 | /* Next token is the identifier */ 258 | ptr = parse_identifier(ptr, token->name, NULL, ctx); 259 | 260 | /* Skip whitespace between member and [ or ; */ 261 | ptr = skip_ws(ptr); 262 | 263 | /* Check if this is an array */ 264 | char *array_start = strchr(token->name, '['); 265 | if (!array_start) { 266 | /* If the [ was separated by a space, it will not be parsed as part of 267 | * the name */ 268 | if (*ptr == '[') { 269 | array_start = (char*)ptr; /* safe, will not be modified */ 270 | } 271 | } 272 | 273 | if (array_start) { 274 | /* Check if the [ matches with a ] */ 275 | char *array_end = strchr(array_start, ']'); 276 | if (!array_end) { 277 | ecs_meta_error(ctx, ptr, "missing ']'"); 278 | 279 | } else if (array_end - array_start == 0) { 280 | ecs_meta_error(ctx, ptr, "dynamic size arrays are not supported"); 281 | } 282 | 283 | token->count = atoi(array_start + 1); 284 | 285 | if (array_start == ptr) { 286 | /* If [ was found after name, continue parsing after ] */ 287 | ptr = array_end + 1; 288 | } else { 289 | /* If [ was fonud in name, replace it with 0 terminator */ 290 | array_start[0] = '\0'; 291 | } 292 | } 293 | 294 | /* Expect a ; */ 295 | if (*ptr != ';') { 296 | ecs_meta_error(ctx, ptr, "missing ; after member declaration"); 297 | } 298 | 299 | return ptr + 1; 300 | } 301 | 302 | void ecs_meta_parse_params( 303 | const char *ptr, 304 | ecs_meta_params_t *token, 305 | ecs_meta_parse_ctx_t *ctx) 306 | { 307 | token->is_key_value = false; 308 | token->is_fixed_size = false; 309 | 310 | ptr = skip_ws(ptr); 311 | if (*ptr != '(' && *ptr != '<') { 312 | ecs_meta_error(ctx, ptr, 313 | "expected '(' at start of collection definition"); 314 | } 315 | 316 | ptr ++; 317 | 318 | /* Parse type identifier */ 319 | ptr = ecs_meta_parse_type(ptr, &token->type, ctx); 320 | ptr = skip_ws(ptr); 321 | 322 | /* If next token is a ',' the first type was a key type */ 323 | if (*ptr == ',') { 324 | ptr = skip_ws(ptr + 1); 325 | 326 | if (isdigit(*ptr)) { 327 | int64_t value; 328 | ptr = parse_digit(ptr, &value, ctx); 329 | token->count = value; 330 | token->is_fixed_size = true; 331 | } else { 332 | token->key_type = token->type; 333 | 334 | /* Parse element type */ 335 | ptr = ecs_meta_parse_type(ptr, &token->type, ctx); 336 | ptr = skip_ws(ptr); 337 | 338 | token->is_key_value = true; 339 | } 340 | } 341 | 342 | if (*ptr != ')' && *ptr != '>') { 343 | ecs_meta_error(ctx, ptr, 344 | "expected ')' at end of collection definition"); 345 | } 346 | } 347 | -------------------------------------------------------------------------------- /src/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef FLECS_META_PARSER_H 2 | #define FLECS_META_PARSER_H 3 | 4 | #include "flecs_meta.h" 5 | 6 | #define ECS_META_IDENTIFIER_LENGTH (256) 7 | 8 | #define ecs_meta_error(ctx, ptr, ...)\ 9 | ecs_parser_error((ctx)->name, (ctx)->decl, ptr - (ctx)->decl, __VA_ARGS__) 10 | 11 | typedef char ecs_meta_token_t[ECS_META_IDENTIFIER_LENGTH]; 12 | 13 | typedef struct ecs_meta_parse_ctx_t { 14 | const char *name; 15 | const char *decl; 16 | } ecs_meta_parse_ctx_t; 17 | 18 | typedef struct ecs_meta_type_t { 19 | ecs_meta_token_t type; 20 | ecs_meta_token_t params; 21 | bool is_const; 22 | bool is_ptr; 23 | } ecs_meta_type_t; 24 | 25 | typedef struct ecs_meta_member_t { 26 | ecs_meta_type_t type; 27 | ecs_meta_token_t name; 28 | int64_t count; 29 | bool is_partial; 30 | } ecs_meta_member_t; 31 | 32 | typedef struct ecs_meta_constant_t { 33 | ecs_meta_token_t name; 34 | int64_t value; 35 | bool is_value_set; 36 | } ecs_meta_constant_t; 37 | 38 | typedef struct ecs_meta_params_t { 39 | ecs_meta_type_t key_type; 40 | ecs_meta_type_t type; 41 | int64_t count; 42 | bool is_key_value; 43 | bool is_fixed_size; 44 | } ecs_meta_params_t; 45 | 46 | const char* ecs_meta_parse_constant( 47 | const char *ptr, 48 | ecs_meta_constant_t *token_out, 49 | ecs_meta_parse_ctx_t *ctx); 50 | 51 | const char* ecs_meta_parse_member( 52 | const char *ptr, 53 | ecs_meta_member_t *token_out, 54 | ecs_meta_parse_ctx_t *ctx); 55 | 56 | void ecs_meta_parse_params( 57 | const char *ptr, 58 | ecs_meta_params_t *token_out, 59 | ecs_meta_parse_ctx_t *ctx); 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/pretty_print.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* Simple serializer to turn values into strings. Use this code as a template 4 | * for when implementing a new serializer. */ 5 | 6 | static 7 | int str_ser_type( 8 | ecs_world_t *world, 9 | ecs_vector_t *ser, 10 | const void *base, 11 | ecs_strbuf_t *str); 12 | 13 | static 14 | int str_ser_type_op( 15 | ecs_world_t *world, 16 | ecs_type_op_t *op, 17 | const void *base, 18 | ecs_strbuf_t *str); 19 | 20 | /* Serialize a primitive value */ 21 | static 22 | void str_ser_primitive( 23 | ecs_world_t *world, 24 | ecs_type_op_t *op, 25 | const void *base, 26 | ecs_strbuf_t *str) 27 | { 28 | const char *bool_str[] = { "false", "true" }; 29 | 30 | switch(op->is.primitive) { 31 | case EcsBool: 32 | ecs_strbuf_appendstr(str, bool_str[(int)*(bool*)base]); 33 | break; 34 | case EcsChar: { 35 | char chbuf[3]; 36 | ecs_chresc(chbuf, *(char*)base, '\''); 37 | 38 | ecs_strbuf_appendstrn(str, "'", 1); 39 | ecs_strbuf_appendstr(str, chbuf); 40 | ecs_strbuf_appendstrn(str, "'", 1); 41 | break; 42 | } 43 | case EcsByte: 44 | ecs_strbuf_append(str, "0x%x", *(uint8_t*)base); 45 | break; 46 | case EcsU8: 47 | ecs_strbuf_append(str, "%u", *(uint8_t*)base); 48 | break; 49 | case EcsU16: 50 | ecs_strbuf_append(str, "%u", *(uint16_t*)base); 51 | break; 52 | case EcsU32: 53 | ecs_strbuf_append(str, "%u", *(uint32_t*)base); 54 | break; 55 | case EcsU64: 56 | ecs_strbuf_append(str, "%llu", *(uint64_t*)base); 57 | break; 58 | case EcsI8: 59 | ecs_strbuf_append(str, "%d", *(int8_t*)base); 60 | break; 61 | case EcsI16: 62 | ecs_strbuf_append(str, "%d", *(int16_t*)base); 63 | break; 64 | case EcsI32: 65 | ecs_strbuf_append(str, "%d", *(int32_t*)base); 66 | break; 67 | case EcsI64: 68 | ecs_strbuf_append(str, "%lld", *(int64_t*)base); 69 | break; 70 | case EcsF32: 71 | ecs_strbuf_append(str, "%f", (double)*(float*)base); 72 | break; 73 | case EcsF64: 74 | ecs_strbuf_append(str, "%f", *(double*)base); 75 | break; 76 | case EcsIPtr: 77 | ecs_strbuf_append(str, "%i", *(intptr_t*)base); 78 | break; 79 | case EcsUPtr: 80 | ecs_strbuf_append(str, "%u", *(uintptr_t*)base); 81 | break; 82 | case EcsString: { 83 | char *value = *(char**)base; 84 | if (value) { 85 | ecs_size_t length = ecs_stresc(NULL, 0, '"', value); 86 | if (length == ecs_os_strlen(value)) { 87 | ecs_strbuf_appendstrn(str, "\"", 1); 88 | ecs_strbuf_appendstr(str, value); 89 | ecs_strbuf_appendstrn(str, "\"", 1); 90 | } else { 91 | char *out = ecs_os_malloc(length + 3); 92 | ecs_stresc(out + 1, length, '"', value); 93 | out[0] = '"'; 94 | out[length + 1] = '"'; 95 | out[length + 2] = '\0'; 96 | ecs_strbuf_appendstr_zerocpy(str, out); 97 | } 98 | } else { 99 | ecs_strbuf_appendstr(str, "nullptr"); 100 | } 101 | break; 102 | } 103 | case EcsEntity: { 104 | ecs_entity_t e = *(ecs_entity_t*)base; 105 | const char *name; 106 | if (e && (name = ecs_get_name(world, e))) { 107 | ecs_strbuf_appendstr(str, name); 108 | } else { 109 | ecs_strbuf_append(str, "%u", e); 110 | } 111 | 112 | break; 113 | } 114 | } 115 | } 116 | 117 | /* Serialize enumeration */ 118 | static 119 | int str_ser_enum( 120 | ecs_world_t *world, 121 | ecs_type_op_t *op, 122 | const void *base, 123 | ecs_strbuf_t *str) 124 | { 125 | const EcsEnum *enum_type = ecs_get_ref_w_id(world, &op->is.constant, 0, 0); 126 | ecs_assert(enum_type != NULL, ECS_INVALID_PARAMETER, NULL); 127 | 128 | int32_t value = *(int32_t*)base; 129 | 130 | /* Enumeration constants are stored in a map that is keyed on the 131 | * enumeration value. */ 132 | char **constant = ecs_map_get(enum_type->constants, char*, value); 133 | if (!constant) { 134 | return -1; 135 | } 136 | 137 | ecs_strbuf_appendstr(str, *constant); 138 | 139 | return 0; 140 | } 141 | 142 | /* Serialize bitmask */ 143 | static 144 | int str_ser_bitmask( 145 | ecs_world_t *world, 146 | ecs_type_op_t *op, 147 | const void *base, 148 | ecs_strbuf_t *str) 149 | { 150 | const EcsBitmask *bitmask_type = ecs_get_ref_w_id(world, &op->is.constant, 0, 0); 151 | ecs_assert(bitmask_type != NULL, ECS_INVALID_PARAMETER, NULL); 152 | 153 | uint32_t value = *(uint32_t*)base; 154 | ecs_map_key_t key; 155 | char **constant; 156 | int count = 0; 157 | 158 | ecs_strbuf_list_push(str, "", " | "); 159 | 160 | /* Multiple flags can be set at a given time. Iterate through all the flags 161 | * and append the ones that are set. */ 162 | ecs_map_iter_t it = ecs_map_iter(bitmask_type->constants); 163 | while ((constant = ecs_map_next(&it, char*, &key))) { 164 | if ((value & key) == key) { 165 | ecs_strbuf_list_appendstr(str, *constant); 166 | count ++; 167 | } 168 | } 169 | 170 | if (!count) { 171 | ecs_strbuf_list_appendstr(str, "0"); 172 | } 173 | 174 | ecs_strbuf_list_pop(str, ""); 175 | 176 | return 0; 177 | } 178 | 179 | /* Serialize elements of a contiguous array */ 180 | static 181 | int str_ser_elements( 182 | ecs_world_t *world, 183 | ecs_vector_t *elem_ops, 184 | const void *base, 185 | int32_t elem_count, 186 | int32_t elem_size, 187 | ecs_strbuf_t *str) 188 | { 189 | ecs_strbuf_list_push(str, "[", ", "); 190 | 191 | const void *ptr = base; 192 | 193 | int i; 194 | for (i = 0; i < elem_count; i ++) { 195 | ecs_strbuf_list_next(str); 196 | if (str_ser_type(world, elem_ops, ptr, str)) { 197 | return -1; 198 | } 199 | ptr = ECS_OFFSET(ptr, elem_size); 200 | } 201 | 202 | ecs_strbuf_list_pop(str, "]"); 203 | 204 | return 0; 205 | } 206 | 207 | /* Serialize array */ 208 | static 209 | int str_ser_array( 210 | ecs_world_t *world, 211 | ecs_type_op_t *op, 212 | const void *base, 213 | ecs_strbuf_t *str) 214 | { 215 | const EcsMetaTypeSerializer *ser = ecs_get_ref_w_id(world, &op->is.collection, 0, 0); 216 | ecs_assert(ser != NULL, ECS_INTERNAL_ERROR, NULL); 217 | 218 | return str_ser_elements( 219 | world, ser->ops, base, op->count, op->size, str); 220 | } 221 | 222 | /* Serialize vector */ 223 | static 224 | int str_ser_vector( 225 | ecs_world_t *world, 226 | ecs_type_op_t *op, 227 | const void *base, 228 | ecs_strbuf_t *str) 229 | { 230 | ecs_vector_t *value = *(ecs_vector_t**)base; 231 | if (!value) { 232 | ecs_strbuf_appendstr(str, "nullptr"); 233 | return 0; 234 | } 235 | 236 | const EcsMetaTypeSerializer *ser = ecs_get_ref_w_id(world, &op->is.collection, 0, 0); 237 | ecs_assert(ser != NULL, ECS_INTERNAL_ERROR, NULL); 238 | 239 | int32_t count = ecs_vector_count(value); 240 | void *array = ecs_vector_first_t(value, op->size, op->alignment); 241 | ecs_vector_t *elem_ops = ser->ops; 242 | 243 | ecs_type_op_t *elem_op_hdr = (ecs_type_op_t*)ecs_vector_first(elem_ops, ecs_type_op_t); 244 | ecs_assert(elem_op_hdr != NULL, ECS_INTERNAL_ERROR, NULL); 245 | ecs_assert(elem_op_hdr->kind == EcsOpHeader, ECS_INTERNAL_ERROR, NULL); 246 | ecs_size_t elem_size = elem_op_hdr->size; 247 | 248 | /* Serialize contiguous buffer of vector */ 249 | return str_ser_elements(world, elem_ops, array, count, elem_size, str); 250 | } 251 | 252 | /* Serialize map */ 253 | static 254 | int str_ser_map( 255 | ecs_world_t *world, 256 | ecs_type_op_t *op, 257 | const void *base, 258 | ecs_strbuf_t *str) 259 | { 260 | ecs_map_t *value = *(ecs_map_t**)base; 261 | 262 | const EcsMetaTypeSerializer *key_ser = ecs_get_ref_w_id(world, &op->is.map.key, 0, 0); 263 | ecs_assert(key_ser != NULL, ECS_INTERNAL_ERROR, NULL); 264 | 265 | const EcsMetaTypeSerializer *elem_ser = ecs_get_ref_w_id(world, &op->is.map.element, 0, 0); 266 | ecs_assert(elem_ser != NULL, ECS_INTERNAL_ERROR, NULL); 267 | 268 | /* 2 instructions, one for the header */ 269 | ecs_assert(ecs_vector_count(key_ser->ops) == 2, ECS_INTERNAL_ERROR, NULL); 270 | 271 | ecs_type_op_t *key_op = ecs_vector_first(key_ser->ops, ecs_type_op_t); 272 | ecs_assert(key_op->kind == EcsOpHeader, ECS_INTERNAL_ERROR, NULL); 273 | key_op = &key_op[1]; 274 | 275 | ecs_map_iter_t it = ecs_map_iter(value); 276 | ecs_map_key_t key; 277 | void *ptr; 278 | 279 | ecs_strbuf_list_push(str, "{", ", "); 280 | 281 | while ((ptr = _ecs_map_next(&it, 0, &key))) { 282 | ecs_strbuf_list_next(str); 283 | if (str_ser_type_op(world, key_op, (void*)&key, str)) { 284 | return -1; 285 | } 286 | 287 | ecs_strbuf_appendstr(str, " = "); 288 | 289 | if (str_ser_type(world, elem_ser->ops, ptr, str)) { 290 | return -1; 291 | } 292 | 293 | key = 0; 294 | } 295 | 296 | ecs_strbuf_list_pop(str, "}"); 297 | 298 | return 0; 299 | } 300 | 301 | /* Forward serialization to the different type kinds */ 302 | static 303 | int str_ser_type_op( 304 | ecs_world_t *world, 305 | ecs_type_op_t *op, 306 | const void *base, 307 | ecs_strbuf_t *str) 308 | { 309 | switch(op->kind) { 310 | case EcsOpHeader: 311 | case EcsOpPush: 312 | case EcsOpPop: 313 | /* Should not be parsed as single op */ 314 | ecs_abort(ECS_INVALID_PARAMETER, NULL); 315 | break; 316 | case EcsOpPrimitive: 317 | str_ser_primitive(world, op, ECS_OFFSET(base, op->offset), str); 318 | break; 319 | case EcsOpEnum: 320 | if (str_ser_enum(world, op, ECS_OFFSET(base, op->offset), str)) { 321 | return -1; 322 | } 323 | break; 324 | case EcsOpBitmask: 325 | if (str_ser_bitmask(world, op, ECS_OFFSET(base, op->offset), str)) { 326 | return -1; 327 | } 328 | break; 329 | case EcsOpArray: 330 | if (str_ser_array(world, op, ECS_OFFSET(base, op->offset), str)) { 331 | return -1; 332 | } 333 | break; 334 | case EcsOpVector: 335 | if (str_ser_vector(world, op, ECS_OFFSET(base, op->offset), str)) { 336 | return -1; 337 | } 338 | break; 339 | case EcsOpMap: 340 | if (str_ser_map(world, op, ECS_OFFSET(base, op->offset), str)) { 341 | return -1; 342 | } 343 | break; 344 | } 345 | 346 | return 0; 347 | } 348 | 349 | /* Iterate over the type ops of a type */ 350 | static 351 | int str_ser_type( 352 | ecs_world_t *world, 353 | ecs_vector_t *ser, 354 | const void *base, 355 | ecs_strbuf_t *str) 356 | { 357 | ecs_type_op_t *ops = (ecs_type_op_t*)ecs_vector_first(ser, ecs_type_op_t); 358 | int32_t count = ecs_vector_count(ser); 359 | 360 | for (int i = 0; i < count; i ++) { 361 | ecs_type_op_t *op = &ops[i]; 362 | 363 | if (op->name) { 364 | if (op->kind != EcsOpHeader) 365 | { 366 | ecs_strbuf_list_next(str); 367 | } 368 | 369 | ecs_strbuf_append(str, "%s = ", op->name); 370 | } 371 | 372 | switch(op->kind) { 373 | case EcsOpHeader: 374 | break; 375 | case EcsOpPush: 376 | ecs_strbuf_list_push(str, "{", ", "); 377 | break; 378 | case EcsOpPop: 379 | ecs_strbuf_list_pop(str, "}"); 380 | break; 381 | default: 382 | if (str_ser_type_op(world, op, base, str)) { 383 | goto error; 384 | } 385 | break; 386 | } 387 | } 388 | 389 | return 0; 390 | error: 391 | ecs_strbuf_reset(str); 392 | return -1; 393 | } 394 | 395 | char* ecs_ptr_to_str( 396 | ecs_world_t *world, 397 | ecs_entity_t type, 398 | void* ptr) 399 | { 400 | const EcsMetaTypeSerializer *ser = ecs_get(world, type, EcsMetaTypeSerializer); 401 | ecs_assert(ser != NULL, ECS_INVALID_PARAMETER, NULL); 402 | 403 | ecs_strbuf_t str = ECS_STRBUF_INIT; 404 | if (str_ser_type(world, ser->ops, ptr, &str)) { 405 | return NULL; 406 | } 407 | 408 | return ecs_strbuf_get(&str); 409 | } 410 | 411 | char* ecs_entity_to_str( 412 | ecs_world_t *world, 413 | ecs_entity_t entity) 414 | { 415 | ecs_type_t type = ecs_get_type(world, entity); 416 | ecs_entity_t *ids = (ecs_entity_t*)ecs_vector_first(type, ecs_entity_t); 417 | int32_t count = ecs_vector_count(type); 418 | 419 | ecs_strbuf_t str = ECS_STRBUF_INIT; 420 | 421 | const char *name = ecs_get_name(world, entity); 422 | if (name) { 423 | ecs_strbuf_append(&str, "%s: ", name); 424 | } 425 | 426 | ecs_strbuf_appendstr(&str, "{\n"); 427 | 428 | int i, comps_serialized = 0; 429 | for (i = 0; i < count; i ++) { 430 | const EcsMetaTypeSerializer *ser = ecs_get(world, ids[i], EcsMetaTypeSerializer); 431 | if (ser) { 432 | const void *ptr = ecs_get_id(world, entity, ids[i]); 433 | ecs_strbuf_append(&str, " %s: ", ecs_get_name(world, ids[i])); 434 | if (str_ser_type(world, ser->ops, ptr, &str)) { 435 | goto error; 436 | } 437 | 438 | ecs_strbuf_appendstr(&str, "\n"); 439 | comps_serialized ++; 440 | } 441 | } 442 | 443 | ecs_strbuf_appendstr(&str, "}"); 444 | 445 | return ecs_strbuf_get(&str); 446 | error: 447 | ecs_strbuf_reset(&str); 448 | return NULL; 449 | } 450 | -------------------------------------------------------------------------------- /src/serializer.h: -------------------------------------------------------------------------------- 1 | #ifndef FLECS_META_SERIALIZER_H 2 | #define FLECS_META_SERIALIZER_H 3 | 4 | #include "flecs_meta.h" 5 | 6 | void EcsAddStruct( 7 | ecs_iter_t *it); 8 | 9 | void EcsSetPrimitive( 10 | ecs_iter_t *it); 11 | 12 | void EcsSetEnum( 13 | ecs_iter_t *it); 14 | 15 | void EcsSetBitmask( 16 | ecs_iter_t *it); 17 | 18 | void EcsSetStruct( 19 | ecs_iter_t *it); 20 | 21 | void EcsSetArray( 22 | ecs_iter_t *it); 23 | 24 | void EcsSetVector( 25 | ecs_iter_t *it); 26 | 27 | void EcsSetMap( 28 | ecs_iter_t *it); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/type.c: -------------------------------------------------------------------------------- 1 | #include "type.h" 2 | 3 | ecs_entity_t ecs_meta_lookup_array( 4 | ecs_world_t *world, 5 | ecs_entity_t e, 6 | const char *params_decl, 7 | ecs_meta_parse_ctx_t *ctx) 8 | { 9 | ecs_meta_parse_ctx_t param_ctx = { 10 | .name = ctx->name, 11 | .decl = params_decl 12 | }; 13 | 14 | ecs_meta_params_t params; 15 | ecs_meta_parse_params(params_decl, ¶ms, ¶m_ctx); 16 | if (!params.is_fixed_size) { 17 | ecs_meta_error(ctx, params_decl, "missing size for array"); 18 | } 19 | 20 | if (!params.count) { 21 | ecs_meta_error(ctx, params_decl, "invalid array size"); 22 | } 23 | 24 | ecs_entity_t element_type = ecs_lookup_symbol(world, params.type.type, true); 25 | if (!element_type) { 26 | ecs_meta_error(ctx, params_decl, "unknown element type '%s'", 27 | params.type.type); 28 | } 29 | 30 | if (!e) { 31 | const EcsMetaType *elem_type = ecs_get(world, element_type, EcsMetaType); 32 | ecs_assert(elem_type != NULL, ECS_INTERNAL_ERROR, NULL); 33 | 34 | ecs_assert(elem_type->size * params.count <= INT32_MAX, 35 | ECS_INVALID_PARAMETER, NULL); 36 | 37 | e = ecs_set(world, 0, EcsMetaType, { 38 | EcsArrayType, (int32_t)(elem_type->size * params.count), 39 | elem_type->alignment, NULL, NULL 40 | }); 41 | } 42 | 43 | ecs_assert(params.count <= INT32_MAX, ECS_INVALID_PARAMETER, NULL); 44 | 45 | return ecs_set(world, e, EcsArray, { element_type, (int32_t)params.count }); 46 | } 47 | 48 | ecs_entity_t ecs_meta_lookup_vector( 49 | ecs_world_t *world, 50 | ecs_entity_t e, 51 | const char *params_decl, 52 | ecs_meta_parse_ctx_t *ctx) 53 | { 54 | ecs_meta_parse_ctx_t param_ctx = { 55 | .name = ctx->name, 56 | .decl = params_decl 57 | }; 58 | 59 | ecs_meta_params_t params; 60 | ecs_meta_parse_params(params_decl, ¶ms, ¶m_ctx); 61 | if (params.is_key_value) { 62 | ecs_meta_error(ctx, params_decl, 63 | "unexpected key value parameters for vector"); 64 | } 65 | 66 | ecs_entity_t element_type = ecs_meta_lookup( 67 | world, ¶ms.type, params_decl, 1, ¶m_ctx); 68 | 69 | if (!e) { 70 | e = ecs_set(world, 0, EcsMetaType, {EcsVectorType, 0, 0, NULL, NULL}); 71 | } 72 | 73 | return ecs_set(world, e, EcsVector, { element_type }); 74 | } 75 | 76 | ecs_entity_t ecs_meta_lookup_map( 77 | ecs_world_t *world, 78 | ecs_entity_t e, 79 | const char *params_decl, 80 | ecs_meta_parse_ctx_t *ctx) 81 | { 82 | ecs_meta_parse_ctx_t param_ctx = { 83 | .name = ctx->name, 84 | .decl = params_decl 85 | }; 86 | 87 | ecs_meta_params_t params; 88 | ecs_meta_parse_params(params_decl, ¶ms, ¶m_ctx); 89 | if (!params.is_key_value) { 90 | ecs_meta_error(ctx, params_decl, 91 | "missing key type for map"); 92 | } 93 | 94 | ecs_entity_t key_type = ecs_meta_lookup( 95 | world, ¶ms.key_type, params_decl, 1, ¶m_ctx); 96 | 97 | ecs_entity_t element_type = ecs_meta_lookup( 98 | world, ¶ms.type, params_decl, 1, ¶m_ctx); 99 | 100 | if (!e) { 101 | e = ecs_set(world, 0, EcsMetaType, {EcsMapType, 0, 0, NULL, NULL}); 102 | } 103 | 104 | return ecs_set(world, e, EcsMap, { key_type, element_type }); 105 | } 106 | 107 | ecs_entity_t ecs_meta_lookup_bitmask( 108 | ecs_world_t *world, 109 | ecs_entity_t e, 110 | const char *params_decl, 111 | ecs_meta_parse_ctx_t *ctx) 112 | { 113 | (void)e; 114 | 115 | ecs_meta_parse_ctx_t param_ctx = { 116 | .name = ctx->name, 117 | .decl = params_decl 118 | }; 119 | 120 | ecs_meta_params_t params; 121 | ecs_meta_parse_params(params_decl, ¶ms, ¶m_ctx); 122 | if (params.is_key_value) { 123 | ecs_meta_error(ctx, params_decl, 124 | "unexpected key value parameters for bitmask"); 125 | } 126 | 127 | if (params.is_fixed_size) { 128 | ecs_meta_error(ctx, params_decl, 129 | "unexpected size for bitmask"); 130 | } 131 | 132 | ecs_entity_t bitmask_type = ecs_meta_lookup( 133 | world, ¶ms.type, params_decl, 1, ¶m_ctx); 134 | ecs_assert(bitmask_type != 0, ECS_INVALID_PARAMETER, NULL); 135 | 136 | #ifndef NDEBUG 137 | /* Make sure this is a bitmask type */ 138 | const EcsMetaType *type_ptr = ecs_get(world, bitmask_type, EcsMetaType); 139 | ecs_assert(type_ptr != NULL, ECS_INVALID_PARAMETER, NULL); 140 | ecs_assert(type_ptr->kind == EcsBitmaskType, ECS_INVALID_PARAMETER, NULL); 141 | #endif 142 | 143 | return bitmask_type; 144 | } 145 | 146 | ecs_entity_t ecs_meta_lookup( 147 | ecs_world_t *world, 148 | ecs_meta_type_t *token, 149 | const char *ptr, 150 | int64_t count, 151 | ecs_meta_parse_ctx_t *ctx) 152 | { 153 | ecs_assert(world != NULL, ECS_INTERNAL_ERROR, NULL); 154 | ecs_assert(token != NULL, ECS_INTERNAL_ERROR, NULL); 155 | ecs_assert(ptr != NULL, ECS_INTERNAL_ERROR, NULL); 156 | ecs_assert(ctx != NULL, ECS_INTERNAL_ERROR, NULL); 157 | 158 | const char *typename = token->type; 159 | ecs_entity_t type = 0; 160 | 161 | /* Parse vector type */ 162 | if (!strcmp(typename, "ecs_array")) { 163 | type = ecs_meta_lookup_array(world, 0, token->params, ctx); 164 | 165 | } else if (!strcmp(typename, "ecs_vector") || !strcmp(typename, "flecs::vector")) { 166 | type = ecs_meta_lookup_vector(world, 0, token->params, ctx); 167 | 168 | } else if (!strcmp(typename, "ecs_map") | !strcmp(typename, "flecs::map")) { 169 | type = ecs_meta_lookup_map(world, 0, token->params, ctx); 170 | 171 | } else if (!strcmp(typename, "flecs::bitmask")) { 172 | type = ecs_meta_lookup_bitmask(world, 0, token->params, ctx); 173 | 174 | } else if (!strcmp(typename, "flecs::byte")) { 175 | type = ecs_lookup(world, "ecs_byte_t"); 176 | 177 | } else { 178 | if (token->is_ptr && !strcmp(typename, "char")) { 179 | typename = "ecs_string_t"; 180 | } else 181 | if (token->is_ptr) { 182 | typename = "uintptr_t"; 183 | } else 184 | if (!strcmp(typename, "char*") || !strcmp(typename, "flecs::string")) { 185 | typename = "ecs_string_t"; 186 | } 187 | 188 | type = ecs_lookup_symbol(world, typename, true); 189 | if (!type) { 190 | ecs_meta_error(ctx, ptr, "unknown type '%s'", typename); 191 | return 0; 192 | } 193 | } 194 | 195 | if (count != 1) { 196 | /* If count is not 1, insert array type. First lookup EcsMetaType of the 197 | * element type to get the size and alignment. Then create a new 198 | * entity for the array type, and assign it to the member type. */ 199 | const EcsMetaType *type_ptr = ecs_get(world, type, EcsMetaType); 200 | 201 | ecs_assert(count <= INT32_MAX, ECS_INVALID_PARAMETER, NULL); 202 | 203 | type = ecs_set(world, ecs_set(world, 0, 204 | EcsMetaType, {EcsArrayType, type_ptr->size, type_ptr->alignment, NULL, NULL}), 205 | EcsArray, {type, (int32_t)count}); 206 | } 207 | 208 | return type; 209 | } 210 | -------------------------------------------------------------------------------- /src/type.h: -------------------------------------------------------------------------------- 1 | #ifndef FLECS_META_TYPE_H 2 | #define FLECS_META_TYPE_H 3 | 4 | #include "parser.h" 5 | 6 | ecs_entity_t ecs_meta_lookup_array( 7 | ecs_world_t *world, 8 | ecs_entity_t e, 9 | const char *params_decl, 10 | ecs_meta_parse_ctx_t *ctx); 11 | 12 | ecs_entity_t ecs_meta_lookup_vector( 13 | ecs_world_t *world, 14 | ecs_entity_t e, 15 | const char *params_decl, 16 | ecs_meta_parse_ctx_t *ctx); 17 | 18 | ecs_entity_t ecs_meta_lookup_map( 19 | ecs_world_t *world, 20 | ecs_entity_t e, 21 | const char *params_decl, 22 | ecs_meta_parse_ctx_t *ctx); 23 | 24 | ecs_entity_t ecs_meta_lookup_bitmask( 25 | ecs_world_t *world, 26 | ecs_entity_t e, 27 | const char *params_decl, 28 | ecs_meta_parse_ctx_t *ctx); 29 | 30 | ecs_entity_t ecs_meta_lookup( 31 | ecs_world_t *world, 32 | ecs_meta_type_t *token, 33 | const char *ptr, 34 | int64_t count, 35 | ecs_meta_parse_ctx_t *ctx); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/util.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char* ecs_chresc( 4 | char *out, 5 | char in, 6 | char delimiter) 7 | { 8 | char *bptr = out; 9 | switch(in) { 10 | case '\a': 11 | *bptr++ = '\\'; 12 | *bptr = 'a'; 13 | break; 14 | case '\b': 15 | *bptr++ = '\\'; 16 | *bptr = 'b'; 17 | break; 18 | case '\f': 19 | *bptr++ = '\\'; 20 | *bptr = 'f'; 21 | break; 22 | case '\n': 23 | *bptr++ = '\\'; 24 | *bptr = 'n'; 25 | break; 26 | case '\r': 27 | *bptr++ = '\\'; 28 | *bptr = 'r'; 29 | break; 30 | case '\t': 31 | *bptr++ = '\\'; 32 | *bptr = 't'; 33 | break; 34 | case '\v': 35 | *bptr++ = '\\'; 36 | *bptr = 'v'; 37 | break; 38 | case '\\': 39 | *bptr++ = '\\'; 40 | *bptr = '\\'; 41 | break; 42 | default: 43 | if (in == delimiter) { 44 | *bptr++ = '\\'; 45 | *bptr = delimiter; 46 | } else { 47 | *bptr = in; 48 | } 49 | break; 50 | } 51 | 52 | *(++bptr) = '\0'; 53 | 54 | return bptr; 55 | } 56 | 57 | const char* ecs_chrparse( 58 | const char *in, 59 | char *out) 60 | { 61 | const char *result = in + 1; 62 | char ch; 63 | 64 | if (in[0] == '\\') { 65 | result ++; 66 | 67 | switch(in[1]) { 68 | case 'a': 69 | ch = '\a'; 70 | break; 71 | case 'b': 72 | ch = '\b'; 73 | break; 74 | case 'f': 75 | ch = '\f'; 76 | break; 77 | case 'n': 78 | ch = '\n'; 79 | break; 80 | case 'r': 81 | ch = '\r'; 82 | break; 83 | case 't': 84 | ch = '\t'; 85 | break; 86 | case 'v': 87 | ch = '\v'; 88 | break; 89 | case '\\': 90 | ch = '\\'; 91 | break; 92 | case '"': 93 | ch = '"'; 94 | break; 95 | case '0': 96 | ch = '\0'; 97 | break; 98 | case ' ': 99 | ch = ' '; 100 | break; 101 | case '$': 102 | ch = '$'; 103 | break; 104 | default: 105 | goto error; 106 | } 107 | } else { 108 | ch = in[0]; 109 | } 110 | 111 | if (out) { 112 | *out = ch; 113 | } 114 | 115 | return result; 116 | error: 117 | return NULL; 118 | } 119 | 120 | ecs_size_t ecs_stresc( 121 | char *out, 122 | ecs_size_t n, 123 | char delimiter, 124 | const char *in) 125 | { 126 | const char *ptr = in; 127 | char ch, *bptr = out, buff[3]; 128 | ecs_size_t written = 0; 129 | while ((ch = *ptr++)) { 130 | if ((written += (ecs_size_t)(ecs_chresc(buff, ch, delimiter) - buff)) <= n) { 131 | *bptr++ = buff[0]; 132 | if ((ch = buff[1])) { 133 | *bptr = ch; 134 | bptr++; 135 | } 136 | } 137 | } 138 | 139 | if (bptr) { 140 | while (written < n) { 141 | *bptr = '\0'; 142 | bptr++; 143 | written++; 144 | } 145 | } 146 | return written; 147 | } 148 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | .bake_cache 2 | .DS_Store 3 | .vscode 4 | gcov 5 | bin 6 | -------------------------------------------------------------------------------- /test/deserializer/include/test.h: -------------------------------------------------------------------------------- 1 | #ifndef TEST_H 2 | #define TEST_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "test/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /test/deserializer/include/test/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef TEST_BAKE_CONFIG_H 18 | #define TEST_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | #ifdef __BAKE__ 24 | #include 25 | #endif 26 | #include 27 | 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /test/deserializer/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "test", 3 | "type": "application", 4 | "value": { 5 | "author": "Sander Mertens", 6 | "description": "Test project for flecs.meta", 7 | "public": false, 8 | "coverage": false, 9 | "use": [ 10 | "flecs", 11 | "flecs.meta" 12 | ] 13 | }, 14 | "test": { 15 | "testsuites": [{ 16 | "id": "Struct", 17 | "testcases": [ 18 | "struct", 19 | "struct_primitives", 20 | "struct_reassign_string", 21 | "struct_reassign_null", 22 | "nested_struct", 23 | "struct_by_name", 24 | "nested_struct_by_name", 25 | "struct_w_array", 26 | "struct_w_array_by_name", 27 | "struct_w_array_nested_struct", 28 | "struct_w_array_nested_struct_by_name", 29 | "struct_w_vector", 30 | "struct_w_vector_by_name", 31 | "struct_w_vector_nested_struct", 32 | "struct_w_vector_nested_struct_by_name", 33 | "struct_reassign_vector", 34 | "struct_reassign_smaller_vector", 35 | "struct_reassign_larger_vector", 36 | "struct_reassign_vector_null" 37 | ] 38 | }] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/deserializer/src/main.c: -------------------------------------------------------------------------------- 1 | 2 | /* A friendly warning from bake.test 3 | * ---------------------------------------------------------------------------- 4 | * This file is generated. To add/remove testcases modify the 'project.json' of 5 | * the test project. ANY CHANGE TO THIS FILE IS LOST AFTER (RE)BUILDING! 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #include 10 | 11 | // Testsuite 'Struct' 12 | void Struct_struct(void); 13 | void Struct_struct_primitives(void); 14 | void Struct_struct_reassign_string(void); 15 | void Struct_struct_reassign_null(void); 16 | void Struct_nested_struct(void); 17 | void Struct_struct_by_name(void); 18 | void Struct_nested_struct_by_name(void); 19 | void Struct_struct_w_array(void); 20 | void Struct_struct_w_array_by_name(void); 21 | void Struct_struct_w_array_nested_struct(void); 22 | void Struct_struct_w_array_nested_struct_by_name(void); 23 | void Struct_struct_w_vector(void); 24 | void Struct_struct_w_vector_by_name(void); 25 | void Struct_struct_w_vector_nested_struct(void); 26 | void Struct_struct_w_vector_nested_struct_by_name(void); 27 | void Struct_struct_reassign_vector(void); 28 | void Struct_struct_reassign_smaller_vector(void); 29 | void Struct_struct_reassign_larger_vector(void); 30 | void Struct_struct_reassign_vector_null(void); 31 | 32 | bake_test_case Struct_testcases[] = { 33 | { 34 | "struct", 35 | Struct_struct 36 | }, 37 | { 38 | "struct_primitives", 39 | Struct_struct_primitives 40 | }, 41 | { 42 | "struct_reassign_string", 43 | Struct_struct_reassign_string 44 | }, 45 | { 46 | "struct_reassign_null", 47 | Struct_struct_reassign_null 48 | }, 49 | { 50 | "nested_struct", 51 | Struct_nested_struct 52 | }, 53 | { 54 | "struct_by_name", 55 | Struct_struct_by_name 56 | }, 57 | { 58 | "nested_struct_by_name", 59 | Struct_nested_struct_by_name 60 | }, 61 | { 62 | "struct_w_array", 63 | Struct_struct_w_array 64 | }, 65 | { 66 | "struct_w_array_by_name", 67 | Struct_struct_w_array_by_name 68 | }, 69 | { 70 | "struct_w_array_nested_struct", 71 | Struct_struct_w_array_nested_struct 72 | }, 73 | { 74 | "struct_w_array_nested_struct_by_name", 75 | Struct_struct_w_array_nested_struct_by_name 76 | }, 77 | { 78 | "struct_w_vector", 79 | Struct_struct_w_vector 80 | }, 81 | { 82 | "struct_w_vector_by_name", 83 | Struct_struct_w_vector_by_name 84 | }, 85 | { 86 | "struct_w_vector_nested_struct", 87 | Struct_struct_w_vector_nested_struct 88 | }, 89 | { 90 | "struct_w_vector_nested_struct_by_name", 91 | Struct_struct_w_vector_nested_struct_by_name 92 | }, 93 | { 94 | "struct_reassign_vector", 95 | Struct_struct_reassign_vector 96 | }, 97 | { 98 | "struct_reassign_smaller_vector", 99 | Struct_struct_reassign_smaller_vector 100 | }, 101 | { 102 | "struct_reassign_larger_vector", 103 | Struct_struct_reassign_larger_vector 104 | }, 105 | { 106 | "struct_reassign_vector_null", 107 | Struct_struct_reassign_vector_null 108 | } 109 | }; 110 | 111 | static bake_test_suite suites[] = { 112 | { 113 | "Struct", 114 | NULL, 115 | NULL, 116 | 19, 117 | Struct_testcases 118 | } 119 | }; 120 | 121 | int main(int argc, char *argv[]) { 122 | ut_init(argv[0]); 123 | return bake_test_run("test", argc, argv, suites, 1); 124 | } 125 | -------------------------------------------------------------------------------- /test/serialize/include/test.h: -------------------------------------------------------------------------------- 1 | #ifndef TEST_H 2 | #define TEST_H 3 | 4 | /* This generated file contains includes for project dependencies */ 5 | #include "test/bake_config.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /test/serialize/include/test/bake_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | ) 3 | (.) 4 | .|. 5 | | | 6 | _.--| |--._ 7 | .-'; ;`-'& ; `&. 8 | \ & ; & &_/ 9 | |"""---...---"""| 10 | \ | | | | | | | / 11 | `---.|.|.|.---' 12 | 13 | * This file is generated by bake.lang.c for your convenience. Headers of 14 | * dependencies will automatically show up in this file. Include bake_config.h 15 | * in your main project file. Do not edit! */ 16 | 17 | #ifndef TEST_BAKE_CONFIG_H 18 | #define TEST_BAKE_CONFIG_H 19 | 20 | /* Headers of public dependencies */ 21 | #include 22 | #include 23 | #ifdef __BAKE__ 24 | #include 25 | #endif 26 | #include 27 | 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /test/serialize/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "test", 3 | "type": "application", 4 | "value": { 5 | "author": "Sander Mertens", 6 | "description": "Test project for flecs.meta", 7 | "public": false, 8 | "coverage": false, 9 | "use": [ 10 | "flecs", 11 | "flecs.meta" 12 | ] 13 | }, 14 | "test": { 15 | "testsuites": [{ 16 | "id": "Primitive", 17 | "testcases": [ 18 | "bool", 19 | "byte", 20 | "char", 21 | "i8", 22 | "i16", 23 | "i32", 24 | "i64", 25 | "iptr", 26 | "u8", 27 | "u16", 28 | "u32", 29 | "u64", 30 | "uptr", 31 | "float", 32 | "double", 33 | "string", 34 | "entity" 35 | ] 36 | }, { 37 | "id": "Struct", 38 | "testcases": [ 39 | "struct", 40 | "nested_struct", 41 | "struct_bool_i32", 42 | "struct_i32_bool" 43 | ] 44 | }, { 45 | "id": "Enum", 46 | "testcases": [ 47 | "enum", 48 | "enum_explicit_values", 49 | "enum_invalid_value" 50 | ] 51 | }, { 52 | "id": "Bitmask", 53 | "testcases": [ 54 | "bitmask_1", 55 | "bitmask_2", 56 | "bitmask_3", 57 | "bitmask_0_value" 58 | ] 59 | }, { 60 | "id": "Array", 61 | "testcases": [ 62 | "array_bool", 63 | "array_int", 64 | "array_string", 65 | "array_entity", 66 | "struct_array_int", 67 | "array_struct", 68 | "array_nested_struct", 69 | "array_array_int", 70 | "array_array_string", 71 | "array_array_struct", 72 | "array_array_nested_struct" 73 | ] 74 | }, { 75 | "id": "Vector", 76 | "testcases": [ 77 | "vector_bool", 78 | "vector_int", 79 | "vector_string", 80 | "vector_entity", 81 | "vector_struct", 82 | "vector_nested_struct", 83 | "vector_vector_int", 84 | "vector_vector_struct", 85 | "vector_vector_nested_struct", 86 | "vector_empty", 87 | "vector_vector_empty", 88 | "vector_null", 89 | "vector_vector_null" 90 | ] 91 | }, { 92 | "id": "Map", 93 | "testcases": [ 94 | "map_bool_bool", 95 | "map_int_bool", 96 | "map_string_bool", 97 | "map_enum_bool", 98 | "map_bitmask_bool", 99 | "map_int_int", 100 | "map_int_string", 101 | "map_int_struct", 102 | "map_int_nested_struct", 103 | "map_int_array_int", 104 | "map_int_vector_int", 105 | "map_int_map_int_bool" 106 | ] 107 | }] 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /test/serialize/src/Array.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_STRUCT(Point, { 4 | int32_t x; 5 | int32_t y; 6 | }); 7 | 8 | ECS_STRUCT(Line, { 9 | Point start; 10 | Point stop; 11 | }); 12 | 13 | ECS_STRUCT(Struct_w_array, { 14 | int32_t ints[2]; 15 | }); 16 | 17 | ECS_ARRAY(ArrayBool, bool, 2); 18 | ECS_ARRAY(ArrayInt, int32_t, 2); 19 | ECS_ARRAY(ArrayString, ecs_string_t, 2); 20 | ECS_ARRAY(ArrayEntity, ecs_entity_t, 2); 21 | ECS_ARRAY(ArrayPoint, Point, 2); 22 | ECS_ARRAY(ArrayLine, Line, 2); 23 | ECS_ARRAY(ArrayArrayInt, ArrayInt, 2); 24 | ECS_ARRAY(ArrayArrayString, ArrayString, 2); 25 | ECS_ARRAY(ArrayArrayPoint, ArrayPoint, 2); 26 | ECS_ARRAY(ArrayArrayLine, ArrayLine, 2); 27 | 28 | void Array_array_bool() { 29 | ecs_world_t *world = ecs_init(); 30 | 31 | ECS_IMPORT(world, FlecsMeta); 32 | 33 | ECS_META(world, ArrayBool); 34 | 35 | { 36 | bool value[] = {true, false}; 37 | char *str = ecs_ptr_to_str(world, ecs_id(ArrayBool), value); 38 | test_str(str, "[true, false]"); 39 | ecs_os_free(str); 40 | } 41 | 42 | ecs_fini(world); 43 | } 44 | 45 | void Array_array_int() { 46 | ecs_world_t *world = ecs_init(); 47 | 48 | ECS_IMPORT(world, FlecsMeta); 49 | 50 | ECS_META(world, ArrayInt); 51 | 52 | { 53 | int32_t value[] = {10, -20}; 54 | char *str = ecs_ptr_to_str(world, ecs_id(ArrayInt), value); 55 | test_str(str, "[10, -20]"); 56 | ecs_os_free(str); 57 | } 58 | 59 | ecs_fini(world); 60 | } 61 | 62 | void Array_array_string() { 63 | ecs_world_t *world = ecs_init(); 64 | 65 | ECS_IMPORT(world, FlecsMeta); 66 | 67 | ECS_META(world, ArrayString); 68 | 69 | { 70 | char* value[] = {"Hello", "World"}; 71 | char *str = ecs_ptr_to_str(world, ecs_id(ArrayString), value); 72 | test_str(str, "[\"Hello\", \"World\"]"); 73 | ecs_os_free(str); 74 | } 75 | 76 | { 77 | char* value[] = {"Hello", NULL}; 78 | char *str = ecs_ptr_to_str(world, ecs_id(ArrayString), value); 79 | test_str(str, "[\"Hello\", nullptr]"); 80 | ecs_os_free(str); 81 | } 82 | 83 | ecs_fini(world); 84 | } 85 | 86 | void Array_array_entity() { 87 | ecs_world_t *world = ecs_init(); 88 | 89 | ECS_IMPORT(world, FlecsMeta); 90 | 91 | ECS_META(world, ArrayEntity); 92 | 93 | ecs_entity_t e1 = 2000; 94 | ecs_entity_t e2 = ecs_set_name(world, 0, "Foo"); 95 | 96 | { 97 | ecs_entity_t value[] = {e1, e2}; 98 | char *str = ecs_ptr_to_str(world, ecs_id(ArrayEntity), value); 99 | test_str(str, "[2000, Foo]"); 100 | ecs_os_free(str); 101 | } 102 | 103 | ecs_fini(world); 104 | } 105 | 106 | void Array_struct_array_int() { 107 | ecs_world_t *world = ecs_init(); 108 | 109 | ECS_IMPORT(world, FlecsMeta); 110 | 111 | ECS_META(world, Struct_w_array); 112 | 113 | { 114 | Struct_w_array value = {{10, -20}}; 115 | char *str = ecs_ptr_to_str(world, ecs_id(Struct_w_array), &value); 116 | test_str(str, "{ints = [10, -20]}"); 117 | ecs_os_free(str); 118 | } 119 | 120 | ecs_fini(world); 121 | } 122 | 123 | void Array_array_struct() { 124 | ecs_world_t *world = ecs_init(); 125 | 126 | ECS_IMPORT(world, FlecsMeta); 127 | 128 | ECS_META(world, Point); 129 | ECS_META(world, ArrayPoint); 130 | 131 | { 132 | Point value[] = {{10, 20}, {30, 40}}; 133 | char *str = ecs_ptr_to_str(world, ecs_id(ArrayPoint), &value); 134 | test_str(str, "[{x = 10, y = 20}, {x = 30, y = 40}]"); 135 | ecs_os_free(str); 136 | } 137 | 138 | ecs_fini(world); 139 | } 140 | 141 | void Array_array_nested_struct() { 142 | ecs_world_t *world = ecs_init(); 143 | 144 | ECS_IMPORT(world, FlecsMeta); 145 | 146 | ECS_META(world, Point); 147 | ECS_META(world, Line); 148 | ECS_META(world, ArrayLine); 149 | 150 | { 151 | Line value[] = {{{10, 20}, {30, 40}}, {{50, 60}, {70, 80}}}; 152 | char *str = ecs_ptr_to_str(world, ecs_id(ArrayLine), &value); 153 | test_str(str, "[{start = {x = 10, y = 20}, stop = {x = 30, y = 40}}, {start = {x = 50, y = 60}, stop = {x = 70, y = 80}}]"); 154 | ecs_os_free(str); 155 | } 156 | 157 | ecs_fini(world); 158 | } 159 | 160 | void Array_array_array_int() { 161 | ecs_world_t *world = ecs_init(); 162 | 163 | ECS_IMPORT(world, FlecsMeta); 164 | 165 | ECS_META(world, ArrayInt); 166 | ECS_META(world, ArrayArrayInt); 167 | 168 | { 169 | int value[2][2] = {{10, 20}, {30, 40}}; 170 | char *str = ecs_ptr_to_str(world, ecs_id(ArrayArrayInt), value); 171 | test_str(str, "[[10, 20], [30, 40]]"); 172 | ecs_os_free(str); 173 | } 174 | 175 | ecs_fini(world); 176 | } 177 | 178 | void Array_array_array_string() { 179 | ecs_world_t *world = ecs_init(); 180 | 181 | ECS_IMPORT(world, FlecsMeta); 182 | 183 | ECS_META(world, ArrayString); 184 | ECS_META(world, ArrayArrayString); 185 | 186 | { 187 | char* value[2][2] = {{"Hello", "World"}, {"Foo", "Bar"}}; 188 | char *str = ecs_ptr_to_str(world, ecs_id(ArrayArrayString), value); 189 | test_str(str, "[[\"Hello\", \"World\"], [\"Foo\", \"Bar\"]]"); 190 | ecs_os_free(str); 191 | } 192 | 193 | ecs_fini(world); 194 | } 195 | 196 | void Array_array_array_struct() { 197 | ecs_world_t *world = ecs_init(); 198 | 199 | ECS_IMPORT(world, FlecsMeta); 200 | 201 | ECS_META(world, Point); 202 | ECS_META(world, ArrayPoint); 203 | ECS_META(world, ArrayArrayPoint); 204 | 205 | { 206 | Point value[2][2] = {{{10, 20}, {30, 40}}, {{50, 60}, {70, 80}}}; 207 | char *str = ecs_ptr_to_str(world, ecs_id(ArrayArrayPoint), value); 208 | test_str(str, "[[{x = 10, y = 20}, {x = 30, y = 40}], [{x = 50, y = 60}, {x = 70, y = 80}]]"); 209 | ecs_os_free(str); 210 | } 211 | 212 | ecs_fini(world); 213 | } 214 | 215 | void Array_array_array_nested_struct() { 216 | ecs_world_t *world = ecs_init(); 217 | 218 | ECS_IMPORT(world, FlecsMeta); 219 | 220 | ECS_META(world, Point); 221 | ECS_META(world, Line); 222 | ECS_META(world, ArrayLine); 223 | ECS_META(world, ArrayArrayLine); 224 | 225 | { 226 | Line l1 = {{10, 20}, {30, 40}}; 227 | Line l2 = {{50, 60}, {70, 80}}; 228 | Line l3 = {{90, 100}, {110, 120}}; 229 | Line l4 = {{130, 140}, {150, 160}}; 230 | 231 | Line value[2][2] = {{l1, l2}, {l3, l4}}; 232 | char *str = ecs_ptr_to_str(world, ecs_id(ArrayArrayLine), value); 233 | test_str(str, 234 | "[[{start = {x = 10, y = 20}, stop = {x = 30, y = 40}}, " 235 | "{start = {x = 50, y = 60}, stop = {x = 70, y = 80}}], " 236 | "[{start = {x = 90, y = 100}, stop = {x = 110, y = 120}}, " 237 | "{start = {x = 130, y = 140}, stop = {x = 150, y = 160}}]]"); 238 | ecs_os_free(str); 239 | } 240 | 241 | ecs_fini(world); 242 | } 243 | -------------------------------------------------------------------------------- /test/serialize/src/Bitmask.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_BITMASK(Toppings, { 4 | Bacon = 1, 5 | Lettuce = 2, 6 | Tomato = 4 7 | }); 8 | 9 | void Bitmask_bitmask_1() { 10 | ecs_world_t *world = ecs_init(); 11 | 12 | ECS_IMPORT(world, FlecsMeta); 13 | 14 | ECS_META(world, Toppings); 15 | 16 | { 17 | Toppings value = Bacon; 18 | char *str = ecs_ptr_to_str(world, ecs_id(Toppings), &value); 19 | test_str(str, "Bacon"); 20 | ecs_os_free(str); 21 | } 22 | 23 | ecs_fini(world); 24 | } 25 | 26 | void Bitmask_bitmask_2() { 27 | ecs_world_t *world = ecs_init(); 28 | 29 | ECS_IMPORT(world, FlecsMeta); 30 | 31 | ECS_META(world, Toppings); 32 | 33 | { 34 | Toppings value = Bacon | Lettuce; 35 | char *str = ecs_ptr_to_str(world, ecs_id(Toppings), &value); 36 | test_str(str, "Bacon | Lettuce"); 37 | ecs_os_free(str); 38 | } 39 | 40 | ecs_fini(world); 41 | } 42 | 43 | void Bitmask_bitmask_3() { 44 | ecs_world_t *world = ecs_init(); 45 | 46 | ECS_IMPORT(world, FlecsMeta); 47 | 48 | ECS_META(world, Toppings); 49 | 50 | { 51 | Toppings value = Bacon | Lettuce | Tomato; 52 | char *str = ecs_ptr_to_str(world, ecs_id(Toppings), &value); 53 | test_str(str, "Tomato | Bacon | Lettuce"); 54 | ecs_os_free(str); 55 | } 56 | 57 | ecs_fini(world); 58 | } 59 | 60 | void Bitmask_bitmask_0_value() { 61 | ecs_world_t *world = ecs_init(); 62 | 63 | ECS_IMPORT(world, FlecsMeta); 64 | 65 | ECS_META(world, Toppings); 66 | 67 | { 68 | Toppings value = 0; 69 | char *str = ecs_ptr_to_str(world, ecs_id(Toppings), &value); 70 | test_str(str, "0"); 71 | ecs_os_free(str); 72 | } 73 | 74 | ecs_fini(world); 75 | } 76 | -------------------------------------------------------------------------------- /test/serialize/src/Enum.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_ENUM(Color, { 4 | Red, 5 | Green, 6 | Blue 7 | }); 8 | 9 | ECS_ENUM(Primes, { 10 | One = 1, 11 | Two = 2, 12 | Three = 3, 13 | Five = 5, 14 | Seven = 7 15 | }); 16 | 17 | void Enum_enum() { 18 | ecs_world_t *world = ecs_init(); 19 | 20 | ECS_IMPORT(world, FlecsMeta); 21 | 22 | ECS_META(world, Color); 23 | 24 | { 25 | Color value = Red; 26 | char *str = ecs_ptr_to_str(world, ecs_id(Color), &value); 27 | test_str(str, "Red"); 28 | ecs_os_free(str); 29 | } 30 | 31 | { 32 | Color value = Green; 33 | char *str = ecs_ptr_to_str(world, ecs_id(Color), &value); 34 | test_str(str, "Green"); 35 | ecs_os_free(str); 36 | } 37 | 38 | { 39 | Color value = Blue; 40 | char *str = ecs_ptr_to_str(world, ecs_id(Color), &value); 41 | test_str(str, "Blue"); 42 | ecs_os_free(str); 43 | } 44 | 45 | ecs_fini(world); 46 | } 47 | 48 | void Enum_enum_explicit_values() { 49 | ecs_world_t *world = ecs_init(); 50 | 51 | ECS_IMPORT(world, FlecsMeta); 52 | 53 | ECS_META(world, Primes); 54 | 55 | { 56 | Primes value = One; 57 | char *str = ecs_ptr_to_str(world, ecs_id(Primes), &value); 58 | test_str(str, "One"); 59 | ecs_os_free(str); 60 | } 61 | 62 | { 63 | Primes value = Two; 64 | char *str = ecs_ptr_to_str(world, ecs_id(Primes), &value); 65 | test_str(str, "Two"); 66 | ecs_os_free(str); 67 | } 68 | 69 | { 70 | Primes value = Three; 71 | char *str = ecs_ptr_to_str(world, ecs_id(Primes), &value); 72 | test_str(str, "Three"); 73 | ecs_os_free(str); 74 | } 75 | 76 | { 77 | Primes value = Five; 78 | char *str = ecs_ptr_to_str(world, ecs_id(Primes), &value); 79 | test_str(str, "Five"); 80 | ecs_os_free(str); 81 | } 82 | 83 | { 84 | Primes value = Seven; 85 | char *str = ecs_ptr_to_str(world, ecs_id(Primes), &value); 86 | test_str(str, "Seven"); 87 | ecs_os_free(str); 88 | } 89 | 90 | ecs_fini(world); 91 | } 92 | 93 | void Enum_enum_invalid_value() { 94 | ecs_world_t *world = ecs_init(); 95 | 96 | ECS_IMPORT(world, FlecsMeta); 97 | 98 | ECS_META(world, Color); 99 | 100 | { 101 | Color value = 10; 102 | char *str = ecs_ptr_to_str(world, ecs_id(Color), &value); 103 | test_str(str, NULL); 104 | ecs_os_free(str); 105 | } 106 | 107 | ecs_fini(world); 108 | } 109 | -------------------------------------------------------------------------------- /test/serialize/src/Map.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_ENUM(Color, { 4 | Red, 5 | Green, 6 | Blue 7 | }); 8 | 9 | ECS_BITMASK(Toppings, { 10 | Bacon = 1, 11 | Lettuce = 2, 12 | Tomato = 4 13 | }); 14 | 15 | ECS_STRUCT(Point, { 16 | int32_t x; 17 | int32_t y; 18 | }); 19 | 20 | ECS_STRUCT(Line, { 21 | Point start; 22 | Point stop; 23 | }); 24 | 25 | ECS_ARRAY(ArrayInt, int32_t, 2); 26 | ECS_VECTOR(VectorInt, int32_t); 27 | 28 | ECS_MAP(MapBoolBool, bool, bool); 29 | ECS_MAP(MapIntBool, int32_t, bool); 30 | ECS_MAP(MapStringBool, ecs_string_t, bool); 31 | ECS_MAP(MapColorBool, Color, bool); 32 | ECS_MAP(MapToppingsBool, Toppings, bool); 33 | ECS_MAP(MapIntInt, int32_t, int32_t); 34 | ECS_MAP(MapIntString, int32_t, char*); 35 | ECS_MAP(MapIntPoint, int32_t, Point); 36 | ECS_MAP(MapIntLine, int32_t, Line); 37 | ECS_MAP(MapIntArrayInt, int32_t, ArrayInt); 38 | ECS_MAP(MapIntVectorInt, int32_t, VectorInt); 39 | ECS_MAP(MapIntMapIntBool, int32_t, MapIntBool); 40 | 41 | void Map_map_bool_bool() { 42 | ecs_world_t *world = ecs_init(); 43 | 44 | ECS_IMPORT(world, FlecsMeta); 45 | 46 | ECS_META(world, MapBoolBool); 47 | 48 | { 49 | ecs_map_t *value = ecs_map_new(bool, 0); 50 | ecs_map_set(value, true, &(bool){false}); 51 | ecs_map_set(value, false, &(bool){true}); 52 | char *str = ecs_ptr_to_str(world, ecs_id(MapBoolBool), &value); 53 | test_str(str, "{false = true, true = false}"); 54 | ecs_os_free(str); 55 | ecs_map_free(value); 56 | } 57 | 58 | ecs_fini(world); 59 | } 60 | 61 | void Map_map_int_bool() { 62 | ecs_world_t *world = ecs_init(); 63 | 64 | ECS_IMPORT(world, FlecsMeta); 65 | 66 | ECS_META(world, MapIntBool); 67 | 68 | { 69 | ecs_map_t *value = ecs_map_new(bool, 0); 70 | ecs_map_set(value, 1, &(bool){false}); 71 | ecs_map_set(value, 2, &(bool){true}); 72 | 73 | char *str = ecs_ptr_to_str(world, ecs_id(MapIntBool), &value); 74 | test_str(str, "{1 = false, 2 = true}"); 75 | ecs_os_free(str); 76 | ecs_map_free(value); 77 | } 78 | 79 | ecs_fini(world); 80 | } 81 | 82 | void Map_map_string_bool() { 83 | ecs_world_t *world = ecs_init(); 84 | 85 | ECS_IMPORT(world, FlecsMeta); 86 | 87 | ECS_META(world, MapStringBool); 88 | 89 | { 90 | ecs_map_t *value = ecs_map_new(bool, 0); 91 | ecs_map_set(value, "Foo", &(bool){false}); 92 | ecs_map_set(value, "Bar", &(bool){true}); 93 | char *str = ecs_ptr_to_str(world, ecs_id(MapStringBool), &value); 94 | test_str(str, "{\"Foo\" = false, \"Bar\" = true}"); 95 | ecs_os_free(str); 96 | ecs_map_free(value); 97 | } 98 | 99 | ecs_fini(world); 100 | } 101 | 102 | void Map_map_enum_bool() { 103 | ecs_world_t *world = ecs_init(); 104 | 105 | ECS_IMPORT(world, FlecsMeta); 106 | 107 | ECS_META(world, Color); 108 | ECS_META(world, MapColorBool); 109 | 110 | { 111 | ecs_map_t *value = ecs_map_new(bool, 0); 112 | ecs_map_set(value, Green, &(bool){false}); 113 | ecs_map_set(value, Blue, &(bool){true}); 114 | char *str = ecs_ptr_to_str(world, ecs_id(MapColorBool), &value); 115 | test_str(str, "{Green = false, Blue = true}"); 116 | ecs_os_free(str); 117 | ecs_map_free(value); 118 | } 119 | 120 | ecs_fini(world); 121 | } 122 | 123 | void Map_map_bitmask_bool() { 124 | ecs_world_t *world = ecs_init(); 125 | 126 | ECS_IMPORT(world, FlecsMeta); 127 | 128 | ECS_META(world, Toppings); 129 | ECS_META(world, MapToppingsBool); 130 | 131 | { 132 | ecs_map_t *value = ecs_map_new(bool, 0); 133 | ecs_map_set(value, Bacon | Lettuce, &(bool){false}); 134 | ecs_map_set(value, Bacon | Lettuce | Tomato, &(bool){true}); 135 | char *str = ecs_ptr_to_str(world, ecs_id(MapToppingsBool), &value); 136 | test_str(str, "{Bacon | Lettuce = false, Tomato | Bacon | Lettuce = true}"); 137 | ecs_os_free(str); 138 | ecs_map_free(value); 139 | } 140 | 141 | ecs_fini(world); 142 | } 143 | 144 | void Map_map_int_int() { 145 | ecs_world_t *world = ecs_init(); 146 | 147 | ECS_IMPORT(world, FlecsMeta); 148 | 149 | ECS_META(world, MapIntInt); 150 | 151 | { 152 | ecs_map_t *value = ecs_map_new(int32_t, 0); 153 | ecs_map_set(value, 1, &(int32_t){10}); 154 | ecs_map_set(value, 2, &(int32_t){20}); 155 | char *str = ecs_ptr_to_str(world, ecs_id(MapIntInt), &value); 156 | test_str(str, "{1 = 10, 2 = 20}"); 157 | ecs_os_free(str); 158 | ecs_map_free(value); 159 | } 160 | 161 | ecs_fini(world); 162 | } 163 | 164 | void Map_map_int_string() { 165 | ecs_world_t *world = ecs_init(); 166 | 167 | ECS_IMPORT(world, FlecsMeta); 168 | 169 | ECS_META(world, MapIntString); 170 | 171 | { 172 | ecs_map_t *value = ecs_map_new(char*, 0); 173 | ecs_map_set(value, 1, &(char*){"Hello"}); 174 | ecs_map_set(value, 2, &(char*){"World"}); 175 | char *str = ecs_ptr_to_str(world, ecs_id(MapIntString), &value); 176 | test_str(str, "{1 = \"Hello\", 2 = \"World\"}"); 177 | ecs_os_free(str); 178 | ecs_map_free(value); 179 | } 180 | 181 | ecs_fini(world); 182 | } 183 | 184 | void Map_map_int_struct() { 185 | ecs_world_t *world = ecs_init(); 186 | 187 | ECS_IMPORT(world, FlecsMeta); 188 | 189 | ECS_META(world, Point); 190 | ECS_META(world, MapIntPoint); 191 | 192 | { 193 | ecs_map_t *value = ecs_map_new(Point, 0); 194 | ecs_map_set(value, 1, (&(Point){10, 20})); 195 | ecs_map_set(value, 2, (&(Point){30, 40})); 196 | char *str = ecs_ptr_to_str(world, ecs_id(MapIntPoint), &value); 197 | test_str(str, "{1 = {x = 10, y = 20}, 2 = {x = 30, y = 40}}"); 198 | ecs_os_free(str); 199 | ecs_map_free(value); 200 | } 201 | 202 | ecs_fini(world); 203 | } 204 | 205 | void Map_map_int_nested_struct() { 206 | ecs_world_t *world = ecs_init(); 207 | 208 | ECS_IMPORT(world, FlecsMeta); 209 | 210 | ECS_META(world, Point); 211 | ECS_META(world, Line); 212 | ECS_META(world, MapIntLine); 213 | 214 | { 215 | ecs_map_t *value = ecs_map_new(Line, 0); 216 | ecs_map_set(value, 1, (&(Line){{10, 20}, {30, 40}})); 217 | ecs_map_set(value, 2, (&(Line){{50, 60}, {70, 80}})); 218 | char *str = ecs_ptr_to_str(world, ecs_id(MapIntLine), &value); 219 | test_str(str, "{1 = {start = {x = 10, y = 20}, stop = {x = 30, y = 40}}, 2 = {start = {x = 50, y = 60}, stop = {x = 70, y = 80}}}"); 220 | ecs_os_free(str); 221 | ecs_map_free(value); 222 | } 223 | 224 | ecs_fini(world); 225 | } 226 | 227 | void Map_map_int_array_int() { 228 | ecs_world_t *world = ecs_init(); 229 | 230 | ECS_IMPORT(world, FlecsMeta); 231 | 232 | ECS_META(world, ArrayInt); 233 | ECS_META(world, MapIntArrayInt); 234 | 235 | { 236 | ecs_map_t *value = ecs_map_new(ArrayInt, 0); 237 | ecs_map_set(value, 1, (&(int32_t[]){10, 20})); 238 | ecs_map_set(value, 2, (&(int32_t[]){30, 40})); 239 | char *str = ecs_ptr_to_str(world, ecs_id(MapIntArrayInt), &value); 240 | test_str(str, "{1 = [10, 20], 2 = [30, 40]}"); 241 | ecs_os_free(str); 242 | ecs_map_free(value); 243 | } 244 | 245 | ecs_fini(world); 246 | } 247 | 248 | void Map_map_int_vector_int() { 249 | ecs_world_t *world = ecs_init(); 250 | 251 | ECS_IMPORT(world, FlecsMeta); 252 | 253 | ECS_META(world, VectorInt); 254 | ECS_META(world, MapIntVectorInt); 255 | 256 | { 257 | ecs_vector_t *v1 = ecs_vector_from_array(int32_t, 2, ((int32_t[]){10, 20})); 258 | ecs_vector_t *v2 = ecs_vector_from_array(int32_t, 2, ((int32_t[]){30, 40})); 259 | ecs_map_t *value = ecs_map_new(ArrayInt, 0); 260 | ecs_map_set(value, 1, &v1); 261 | ecs_map_set(value, 2, &v2); 262 | char *str = ecs_ptr_to_str(world, ecs_id(MapIntVectorInt), &value); 263 | test_str(str, "{1 = [10, 20], 2 = [30, 40]}"); 264 | ecs_os_free(str); 265 | ecs_map_free(value); 266 | ecs_vector_free(v1); 267 | ecs_vector_free(v2); 268 | } 269 | 270 | ecs_fini(world); 271 | } 272 | 273 | void Map_map_int_map_int_bool() { 274 | ecs_world_t *world = ecs_init(); 275 | 276 | ECS_IMPORT(world, FlecsMeta); 277 | 278 | ECS_META(world, MapIntBool); 279 | ECS_META(world, MapIntMapIntBool); 280 | 281 | { 282 | ecs_map_t *m1 = ecs_map_new(bool, 0); 283 | ecs_map_set(m1, 1, &(bool){true}); 284 | ecs_map_set(m1, 2, &(bool){false}); 285 | 286 | ecs_map_t *m2 = ecs_map_new(bool, 0); 287 | ecs_map_set(m2, 3, &(bool){false}); 288 | ecs_map_set(m2, 4, &(bool){true}); 289 | 290 | ecs_map_t *value = ecs_map_new(ecs_map_t*, 0); 291 | ecs_map_set(value, 5, &m1); 292 | ecs_map_set(value, 6, &m2); 293 | char *str = ecs_ptr_to_str(world, ecs_id(MapIntMapIntBool), &value); 294 | test_str(str, "{5 = {1 = true, 2 = false}, 6 = {4 = true, 3 = false}}"); 295 | ecs_os_free(str); 296 | ecs_map_free(value); 297 | ecs_map_free(m1); 298 | ecs_map_free(m2); 299 | } 300 | 301 | ecs_fini(world); 302 | } 303 | -------------------------------------------------------------------------------- /test/serialize/src/Primitive.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void Primitive_bool() { 4 | ecs_world_t *world = ecs_init(); 5 | 6 | ECS_IMPORT(world, FlecsMeta); 7 | 8 | ecs_entity_t ecs_id(bool) = ecs_lookup_fullpath(world, "flecs.core.bool"); 9 | test_assert(ecs_id(bool) != 0); 10 | 11 | { 12 | bool value = true; 13 | char *str = ecs_ptr_to_str(world, ecs_id(bool), &value); 14 | test_str(str, "true"); 15 | ecs_os_free(str); 16 | } 17 | { 18 | bool value = false; 19 | char *str = ecs_ptr_to_str(world, ecs_id(bool), &value); 20 | test_str(str, "false"); 21 | ecs_os_free(str); 22 | } 23 | 24 | ecs_fini(world); 25 | } 26 | 27 | void Primitive_byte() { 28 | ecs_world_t *world = ecs_init(); 29 | 30 | ECS_IMPORT(world, FlecsMeta); 31 | ecs_entity_t ecs_id(ecs_byte_t) = ecs_lookup_fullpath(world, "flecs.core.ecs_byte_t"); 32 | test_assert(ecs_id(ecs_byte_t) != 0); 33 | 34 | { 35 | ecs_byte_t value = 0; 36 | char *str = ecs_ptr_to_str(world, ecs_id(ecs_byte_t), &value); 37 | test_str(str, "0x0"); 38 | ecs_os_free(str); 39 | } 40 | 41 | { 42 | ecs_byte_t value = 10; 43 | char *str = ecs_ptr_to_str(world, ecs_id(ecs_byte_t), &value); 44 | test_str(str, "0xa"); 45 | ecs_os_free(str); 46 | } 47 | 48 | { 49 | ecs_byte_t value = 11; 50 | char *str = ecs_ptr_to_str(world, ecs_id(ecs_byte_t), &value); 51 | test_str(str, "0xb"); 52 | ecs_os_free(str); 53 | } 54 | 55 | ecs_fini(world); 56 | } 57 | 58 | void Primitive_char() { 59 | ecs_world_t *world = ecs_init(); 60 | 61 | ECS_IMPORT(world, FlecsMeta); 62 | 63 | ecs_entity_t ecs_id(char) = ecs_lookup_fullpath(world, "flecs.core.char"); 64 | test_assert(ecs_id(char) != 0); 65 | 66 | { 67 | char value = 'a'; 68 | char *str = ecs_ptr_to_str(world, ecs_id(char), &value); 69 | test_str(str, "'a'"); 70 | ecs_os_free(str); 71 | } 72 | 73 | { 74 | char value = 0; 75 | char *str = ecs_ptr_to_str(world, ecs_id(char), &value); 76 | test_str(str, "''"); 77 | ecs_os_free(str); 78 | } 79 | 80 | { 81 | char value = '\n'; 82 | char *str = ecs_ptr_to_str(world, ecs_id(char), &value); 83 | test_str(str, "'\\n'"); 84 | ecs_os_free(str); 85 | } 86 | 87 | ecs_fini(world); 88 | } 89 | 90 | void Primitive_i8() { 91 | ecs_world_t *world = ecs_init(); 92 | 93 | ECS_IMPORT(world, FlecsMeta); 94 | 95 | ecs_entity_t ecs_id(int8_t) = ecs_lookup_fullpath(world, "flecs.core.int8_t"); 96 | test_assert(ecs_id(int8_t) != 0); 97 | 98 | { 99 | int8_t value = 0; 100 | char *str = ecs_ptr_to_str(world, ecs_id(int8_t), &value); 101 | test_str(str, "0"); 102 | ecs_os_free(str); 103 | } 104 | 105 | { 106 | int8_t value = 10; 107 | char *str = ecs_ptr_to_str(world, ecs_id(int8_t), &value); 108 | test_str(str, "10"); 109 | ecs_os_free(str); 110 | } 111 | 112 | { 113 | int8_t value = -10; 114 | char *str = ecs_ptr_to_str(world, ecs_id(int8_t), &value); 115 | test_str(str, "-10"); 116 | ecs_os_free(str); 117 | } 118 | 119 | { 120 | int8_t value = ECS_MAX_I8; 121 | char *str = ecs_ptr_to_str(world, ecs_id(int8_t), &value); 122 | test_str(str, ECS_MAX_I8_STR); 123 | ecs_os_free(str); 124 | } 125 | 126 | { 127 | int8_t value = ECS_MIN_I8; 128 | char *str = ecs_ptr_to_str(world, ecs_id(int8_t), &value); 129 | test_str(str, ECS_MIN_I8_STR); 130 | ecs_os_free(str); 131 | } 132 | 133 | ecs_fini(world); 134 | } 135 | 136 | void Primitive_i16() { 137 | ecs_world_t *world = ecs_init(); 138 | 139 | ECS_IMPORT(world, FlecsMeta); 140 | 141 | ecs_entity_t ecs_id(int16_t) = ecs_lookup_fullpath(world, "flecs.core.int16_t"); 142 | test_assert(ecs_id(int16_t) != 0); 143 | 144 | { 145 | int16_t value = 0; 146 | char *str = ecs_ptr_to_str(world, ecs_id(int16_t), &value); 147 | test_str(str, "0"); 148 | ecs_os_free(str); 149 | } 150 | 151 | { 152 | int16_t value = 10; 153 | char *str = ecs_ptr_to_str(world, ecs_id(int16_t), &value); 154 | test_str(str, "10"); 155 | ecs_os_free(str); 156 | } 157 | 158 | { 159 | int16_t value = -10; 160 | char *str = ecs_ptr_to_str(world, ecs_id(int16_t), &value); 161 | test_str(str, "-10"); 162 | ecs_os_free(str); 163 | } 164 | 165 | { 166 | int16_t value = ECS_MAX_I16; 167 | char *str = ecs_ptr_to_str(world, ecs_id(int16_t), &value); 168 | test_str(str, ECS_MAX_I16_STR); 169 | ecs_os_free(str); 170 | } 171 | 172 | { 173 | int16_t value = ECS_MIN_I16; 174 | char *str = ecs_ptr_to_str(world, ecs_id(int16_t), &value); 175 | test_str(str, ECS_MIN_I16_STR); 176 | ecs_os_free(str); 177 | } 178 | 179 | ecs_fini(world); 180 | } 181 | 182 | void Primitive_i32() { 183 | ecs_world_t *world = ecs_init(); 184 | 185 | ECS_IMPORT(world, FlecsMeta); 186 | 187 | ecs_entity_t ecs_id(int32_t) = ecs_lookup_fullpath(world, "flecs.core.int32_t"); 188 | test_assert(ecs_id(int32_t) != 0); 189 | 190 | { 191 | int32_t value = 0; 192 | char *str = ecs_ptr_to_str(world, ecs_id(int32_t), &value); 193 | test_str(str, "0"); 194 | ecs_os_free(str); 195 | } 196 | 197 | { 198 | int32_t value = 10; 199 | char *str = ecs_ptr_to_str(world, ecs_id(int32_t), &value); 200 | test_str(str, "10"); 201 | ecs_os_free(str); 202 | } 203 | 204 | { 205 | int32_t value = -10; 206 | char *str = ecs_ptr_to_str(world, ecs_id(int32_t), &value); 207 | test_str(str, "-10"); 208 | ecs_os_free(str); 209 | } 210 | 211 | { 212 | int32_t value = ECS_MAX_I32; 213 | char *str = ecs_ptr_to_str(world, ecs_id(int32_t), &value); 214 | test_str(str, ECS_MAX_I32_STR); 215 | ecs_os_free(str); 216 | } 217 | 218 | { 219 | int32_t value = ECS_MIN_I32; 220 | char *str = ecs_ptr_to_str(world, ecs_id(int32_t), &value); 221 | test_str(str, ECS_MIN_I32_STR); 222 | ecs_os_free(str); 223 | } 224 | 225 | ecs_fini(world); 226 | } 227 | 228 | void Primitive_i64() { 229 | ecs_world_t *world = ecs_init(); 230 | 231 | ECS_IMPORT(world, FlecsMeta); 232 | 233 | ecs_entity_t ecs_id(int64_t) = ecs_lookup_fullpath(world, "flecs.core.int64_t"); 234 | test_assert(ecs_id(int64_t) != 0); 235 | 236 | { 237 | int64_t value = 0; 238 | char *str = ecs_ptr_to_str(world, ecs_id(int64_t), &value); 239 | test_str(str, "0"); 240 | ecs_os_free(str); 241 | } 242 | 243 | { 244 | int64_t value = 10; 245 | char *str = ecs_ptr_to_str(world, ecs_id(int64_t), &value); 246 | test_str(str, "10"); 247 | ecs_os_free(str); 248 | } 249 | 250 | { 251 | int64_t value = -10; 252 | char *str = ecs_ptr_to_str(world, ecs_id(int64_t), &value); 253 | test_str(str, "-10"); 254 | ecs_os_free(str); 255 | } 256 | 257 | { 258 | int64_t value = ECS_MAX_I64; 259 | char *str = ecs_ptr_to_str(world, ecs_id(int64_t), &value); 260 | test_str(str, ECS_MAX_I64_STR); 261 | ecs_os_free(str); 262 | } 263 | 264 | { 265 | int64_t value = ECS_MIN_I64; 266 | char *str = ecs_ptr_to_str(world, ecs_id(int64_t), &value); 267 | test_str(str, ECS_MIN_I64_STR); 268 | ecs_os_free(str); 269 | } 270 | 271 | ecs_fini(world); 272 | } 273 | 274 | void Primitive_iptr() { 275 | ecs_world_t *world = ecs_init(); 276 | 277 | ECS_IMPORT(world, FlecsMeta); 278 | 279 | ecs_entity_t ecs_id(intptr_t) = ecs_lookup_fullpath(world, "flecs.core.intptr_t"); 280 | test_assert(ecs_id(intptr_t) != 0); 281 | 282 | { 283 | intptr_t value = 0; 284 | char *str = ecs_ptr_to_str(world, ecs_id(intptr_t), &value); 285 | test_str(str, "0"); 286 | ecs_os_free(str); 287 | } 288 | 289 | { 290 | intptr_t value = 10; 291 | char *str = ecs_ptr_to_str(world, ecs_id(intptr_t), &value); 292 | test_str(str, "10"); 293 | ecs_os_free(str); 294 | } 295 | 296 | { 297 | intptr_t value = -10; 298 | char *str = ecs_ptr_to_str(world, ecs_id(intptr_t), &value); 299 | test_str(str, "-10"); 300 | ecs_os_free(str); 301 | } 302 | 303 | ecs_fini(world); 304 | } 305 | 306 | void Primitive_u8() { 307 | ecs_world_t *world = ecs_init(); 308 | 309 | ECS_IMPORT(world, FlecsMeta); 310 | 311 | ecs_entity_t ecs_id(uint8_t) = ecs_lookup_fullpath(world, "flecs.core.uint8_t"); 312 | test_assert(ecs_id(uint8_t) != 0); 313 | 314 | { 315 | uint8_t value = 0; 316 | char *str = ecs_ptr_to_str(world, ecs_id(uint8_t), &value); 317 | test_str(str, "0"); 318 | ecs_os_free(str); 319 | } 320 | 321 | { 322 | uint8_t value = 10; 323 | char *str = ecs_ptr_to_str(world, ecs_id(uint8_t), &value); 324 | test_str(str, "10"); 325 | ecs_os_free(str); 326 | } 327 | 328 | { 329 | uint8_t value = ECS_MAX_U8; 330 | char *str = ecs_ptr_to_str(world, ecs_id(uint8_t), &value); 331 | test_str(str, ECS_MAX_U8_STR); 332 | ecs_os_free(str); 333 | } 334 | 335 | ecs_fini(world); 336 | } 337 | 338 | void Primitive_u16() { 339 | ecs_world_t *world = ecs_init(); 340 | 341 | ECS_IMPORT(world, FlecsMeta); 342 | 343 | ecs_entity_t ecs_id(uint16_t) = ecs_lookup_fullpath(world, "flecs.core.uint16_t"); 344 | test_assert(ecs_id(uint16_t) != 0); 345 | 346 | { 347 | uint16_t value = 0; 348 | char *str = ecs_ptr_to_str(world, ecs_id(uint16_t), &value); 349 | test_str(str, "0"); 350 | ecs_os_free(str); 351 | } 352 | 353 | { 354 | uint16_t value = 10; 355 | char *str = ecs_ptr_to_str(world, ecs_id(uint16_t), &value); 356 | test_str(str, "10"); 357 | ecs_os_free(str); 358 | } 359 | 360 | { 361 | uint16_t value = ECS_MAX_U16; 362 | char *str = ecs_ptr_to_str(world, ecs_id(uint16_t), &value); 363 | test_str(str, ECS_MAX_U16_STR); 364 | ecs_os_free(str); 365 | } 366 | 367 | ecs_fini(world); 368 | } 369 | 370 | void Primitive_u32() { 371 | ecs_world_t *world = ecs_init(); 372 | 373 | ECS_IMPORT(world, FlecsMeta); 374 | 375 | ecs_entity_t ecs_id(uint32_t) = ecs_lookup_fullpath(world, "flecs.core.uint32_t"); 376 | test_assert(ecs_id(uint32_t) != 0); 377 | 378 | { 379 | uint32_t value = 0; 380 | char *str = ecs_ptr_to_str(world, ecs_id(uint32_t), &value); 381 | test_str(str, "0"); 382 | ecs_os_free(str); 383 | } 384 | 385 | { 386 | uint32_t value = 10; 387 | char *str = ecs_ptr_to_str(world, ecs_id(uint32_t), &value); 388 | test_str(str, "10"); 389 | ecs_os_free(str); 390 | } 391 | 392 | { 393 | uint32_t value = ECS_MAX_U32; 394 | char *str = ecs_ptr_to_str(world, ecs_id(uint32_t), &value); 395 | test_str(str, ECS_MAX_U32_STR); 396 | ecs_os_free(str); 397 | } 398 | 399 | ecs_fini(world); 400 | } 401 | 402 | void Primitive_u64() { 403 | ecs_world_t *world = ecs_init(); 404 | 405 | ECS_IMPORT(world, FlecsMeta); 406 | 407 | ecs_entity_t ecs_id(uint64_t) = ecs_lookup_fullpath(world, "flecs.core.uint64_t"); 408 | test_assert(ecs_id(uint64_t) != 0); 409 | 410 | { 411 | uint64_t value = 0; 412 | char *str = ecs_ptr_to_str(world, ecs_id(uint64_t), &value); 413 | test_str(str, "0"); 414 | ecs_os_free(str); 415 | } 416 | 417 | { 418 | uint64_t value = 10; 419 | char *str = ecs_ptr_to_str(world, ecs_id(uint64_t), &value); 420 | test_str(str, "10"); 421 | ecs_os_free(str); 422 | } 423 | 424 | { 425 | uint64_t value = ECS_MAX_U64; 426 | char *str = ecs_ptr_to_str(world, ecs_id(uint64_t), &value); 427 | test_str(str, ECS_MAX_U64_STR); 428 | ecs_os_free(str); 429 | } 430 | 431 | ecs_fini(world); 432 | } 433 | 434 | void Primitive_uptr() { 435 | ecs_world_t *world = ecs_init(); 436 | 437 | ECS_IMPORT(world, FlecsMeta); 438 | 439 | ecs_entity_t ecs_id(uintptr_t) = ecs_lookup_fullpath(world, "flecs.core.uintptr_t"); 440 | test_assert(ecs_id(uintptr_t) != 0); 441 | 442 | { 443 | uintptr_t value = 0; 444 | char *str = ecs_ptr_to_str(world, ecs_id(uintptr_t), &value); 445 | test_str(str, "0"); 446 | ecs_os_free(str); 447 | } 448 | 449 | { 450 | uintptr_t value = 10; 451 | char *str = ecs_ptr_to_str(world, ecs_id(uintptr_t), &value); 452 | test_str(str, "10"); 453 | ecs_os_free(str); 454 | } 455 | 456 | ecs_fini(world); 457 | } 458 | 459 | void Primitive_float() { 460 | ecs_world_t *world = ecs_init(); 461 | 462 | ECS_IMPORT(world, FlecsMeta); 463 | 464 | ecs_entity_t ecs_id(float) = ecs_lookup_fullpath(world, "flecs.core.float"); 465 | test_assert(ecs_id(float) != 0); 466 | 467 | { 468 | float value = 0; 469 | char *str = ecs_ptr_to_str(world, ecs_id(float), &value); 470 | test_str(str, "0.000000"); 471 | ecs_os_free(str); 472 | } 473 | 474 | { 475 | float value = 10; 476 | char *str = ecs_ptr_to_str(world, ecs_id(float), &value); 477 | test_str(str, "10.000000"); 478 | ecs_os_free(str); 479 | } 480 | 481 | { 482 | float value = 10.5; 483 | char *str = ecs_ptr_to_str(world, ecs_id(float), &value); 484 | test_str(str, "10.500000"); 485 | ecs_os_free(str); 486 | } 487 | 488 | { 489 | float value = -10.5; 490 | char *str = ecs_ptr_to_str(world, ecs_id(float), &value); 491 | test_str(str, "-10.500000"); 492 | ecs_os_free(str); 493 | } 494 | 495 | 496 | ecs_fini(world); 497 | } 498 | 499 | void Primitive_double() { 500 | ecs_world_t *world = ecs_init(); 501 | 502 | ECS_IMPORT(world, FlecsMeta); 503 | 504 | ecs_entity_t ecs_id(double) = ecs_lookup_fullpath(world, "flecs.core.double"); 505 | test_assert(ecs_id(double) != 0); 506 | 507 | { 508 | double value = 0; 509 | char *str = ecs_ptr_to_str(world, ecs_id(double), &value); 510 | test_str(str, "0.000000"); 511 | ecs_os_free(str); 512 | } 513 | 514 | { 515 | double value = 10; 516 | char *str = ecs_ptr_to_str(world, ecs_id(double), &value); 517 | test_str(str, "10.000000"); 518 | ecs_os_free(str); 519 | } 520 | 521 | { 522 | double value = 10.5; 523 | char *str = ecs_ptr_to_str(world, ecs_id(double), &value); 524 | test_str(str, "10.500000"); 525 | ecs_os_free(str); 526 | } 527 | 528 | { 529 | double value = -10.5; 530 | char *str = ecs_ptr_to_str(world, ecs_id(double), &value); 531 | test_str(str, "-10.500000"); 532 | ecs_os_free(str); 533 | } 534 | 535 | ecs_fini(world); 536 | } 537 | 538 | void Primitive_string() { 539 | ecs_world_t *world = ecs_init(); 540 | 541 | ECS_IMPORT(world, FlecsMeta); 542 | 543 | ecs_entity_t ecs_id(ecs_string_t) = ecs_lookup_fullpath(world, "flecs.core.ecs_string_t"); 544 | test_assert(ecs_id(ecs_string_t) != 0); 545 | 546 | { 547 | ecs_string_t value = "Hello World"; 548 | char *str = ecs_ptr_to_str(world, ecs_id(ecs_string_t), &value); 549 | test_str(str, "\"Hello World\""); 550 | ecs_os_free(str); 551 | } 552 | 553 | { 554 | ecs_string_t value = NULL; 555 | char *str = ecs_ptr_to_str(world, ecs_id(ecs_string_t), &value); 556 | test_str(str, "nullptr"); 557 | ecs_os_free(str); 558 | } 559 | 560 | { 561 | ecs_string_t value = "\""; 562 | char *str = ecs_ptr_to_str(world, ecs_id(ecs_string_t), &value); 563 | test_str(str, "\"\\\"\""); 564 | ecs_os_free(str); 565 | } 566 | 567 | { 568 | ecs_string_t value = "\n"; 569 | char *str = ecs_ptr_to_str(world, ecs_id(ecs_string_t), &value); 570 | test_str(str, "\"\\n\""); 571 | ecs_os_free(str); 572 | } 573 | 574 | ecs_fini(world); 575 | } 576 | 577 | void Primitive_entity() { 578 | ecs_world_t *world = ecs_init(); 579 | 580 | ECS_IMPORT(world, FlecsMeta); 581 | 582 | ecs_entity_t ecs_id(ecs_entity_t) = ecs_lookup_fullpath(world, "flecs.core.ecs_entity_t"); 583 | test_assert(ecs_id(ecs_entity_t) != 0); 584 | 585 | { 586 | ecs_entity_t value = 2000; 587 | char *str = ecs_ptr_to_str(world, ecs_id(ecs_entity_t), &value); 588 | test_str(str, "2000"); 589 | ecs_os_free(str); 590 | } 591 | 592 | { 593 | ecs_entity_t value = ecs_set_name(world, 10, "Foo"); 594 | char *str = ecs_ptr_to_str(world, ecs_id(ecs_entity_t), &value); 595 | test_str(str, "Foo"); 596 | ecs_os_free(str); 597 | } 598 | 599 | ecs_fini(world); 600 | } 601 | -------------------------------------------------------------------------------- /test/serialize/src/Struct.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_STRUCT(Point, { 4 | int32_t x; 5 | int32_t y; 6 | }); 7 | 8 | ECS_STRUCT(Line, { 9 | Point start; 10 | Point stop; 11 | }); 12 | 13 | ECS_STRUCT(bool_i32, { 14 | bool b; 15 | int32_t i; 16 | }); 17 | 18 | ECS_STRUCT(i32_bool, { 19 | int32_t i; 20 | bool b; 21 | }); 22 | 23 | void Struct_struct() { 24 | ecs_world_t *world = ecs_init(); 25 | 26 | ECS_IMPORT(world, FlecsMeta); 27 | 28 | ECS_META(world, Point); 29 | 30 | { 31 | Point value = {10, 20}; 32 | char *str = ecs_ptr_to_str(world, ecs_id(Point), &value); 33 | test_str(str, "{x = 10, y = 20}"); 34 | ecs_os_free(str); 35 | } 36 | 37 | ecs_fini(world); 38 | } 39 | 40 | void Struct_nested_struct() { 41 | ecs_world_t *world = ecs_init(); 42 | 43 | ECS_IMPORT(world, FlecsMeta); 44 | 45 | ECS_META(world, Point); 46 | ECS_META(world, Line); 47 | 48 | { 49 | Line value = {{10, 20}, {30, 40}}; 50 | char *str = ecs_ptr_to_str(world, ecs_id(Line), &value); 51 | test_str(str, "{start = {x = 10, y = 20}, stop = {x = 30, y = 40}}"); 52 | ecs_os_free(str); 53 | } 54 | 55 | ecs_fini(world); 56 | } 57 | 58 | void Struct_struct_bool_i32() { 59 | ecs_world_t *world = ecs_init(); 60 | 61 | ECS_IMPORT(world, FlecsMeta); 62 | 63 | ECS_META(world, bool_i32); 64 | 65 | { 66 | bool_i32 value = {false, 10}; 67 | char *str = ecs_ptr_to_str(world, ecs_id(bool_i32), &value); 68 | test_str(str, "{b = false, i = 10}"); 69 | ecs_os_free(str); 70 | } 71 | 72 | ecs_fini(world); 73 | } 74 | 75 | void Struct_struct_i32_bool() { 76 | ecs_world_t *world = ecs_init(); 77 | 78 | ECS_IMPORT(world, FlecsMeta); 79 | 80 | ECS_META(world, i32_bool); 81 | 82 | { 83 | i32_bool value = {10, false}; 84 | char *str = ecs_ptr_to_str(world, ecs_id(i32_bool), &value); 85 | test_str(str, "{i = 10, b = false}"); 86 | ecs_os_free(str); 87 | } 88 | 89 | ecs_fini(world); 90 | } 91 | -------------------------------------------------------------------------------- /test/serialize/src/Vector.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECS_STRUCT(Point, { 4 | int32_t x; 5 | int32_t y; 6 | }); 7 | 8 | ECS_STRUCT(Line, { 9 | Point start; 10 | Point stop; 11 | }); 12 | 13 | ECS_VECTOR(VectorBool, bool); 14 | ECS_VECTOR(VectorInt, int32_t); 15 | ECS_VECTOR(VectorString, ecs_string_t); 16 | ECS_VECTOR(VectorEntity, ecs_entity_t); 17 | ECS_VECTOR(VectorPoint, Point); 18 | ECS_VECTOR(VectorLine, Line); 19 | ECS_VECTOR(VectorVectorInt, VectorInt); 20 | ECS_VECTOR(VectorVectorPoint, VectorPoint); 21 | ECS_VECTOR(VectorVectorLine, VectorLine); 22 | 23 | void Vector_vector_bool() { 24 | ecs_world_t *world = ecs_init(); 25 | 26 | ECS_IMPORT(world, FlecsMeta); 27 | 28 | ECS_META(world, VectorBool); 29 | 30 | { 31 | ecs_vector_t *value = ecs_vector_from_array(bool, 2, ((bool[]){true, false})); 32 | char *str = ecs_ptr_to_str(world, ecs_id(VectorBool), &value); 33 | test_str(str, "[true, false]"); 34 | ecs_os_free(str); 35 | ecs_vector_free(value); 36 | } 37 | 38 | ecs_fini(world); 39 | } 40 | 41 | void Vector_vector_int() { 42 | ecs_world_t *world = ecs_init(); 43 | 44 | ECS_IMPORT(world, FlecsMeta); 45 | 46 | ECS_META(world, VectorInt); 47 | 48 | { 49 | ecs_vector_t *value = ecs_vector_from_array(int32_t, 2, ((int32_t[]){10, -10})); 50 | char *str = ecs_ptr_to_str(world, ecs_id(VectorInt), &value); 51 | test_str(str, "[10, -10]"); 52 | ecs_os_free(str); 53 | ecs_vector_free(value); 54 | } 55 | 56 | ecs_fini(world); 57 | } 58 | 59 | void Vector_vector_string() { 60 | ecs_world_t *world = ecs_init(); 61 | 62 | ECS_IMPORT(world, FlecsMeta); 63 | 64 | ECS_META(world, VectorString); 65 | 66 | { 67 | ecs_vector_t *value = ecs_vector_from_array(char*, 2, ((char*[]){"Hello", "World"})); 68 | char *str = ecs_ptr_to_str(world, ecs_id(VectorString), &value); 69 | test_str(str, "[\"Hello\", \"World\"]"); 70 | ecs_os_free(str); 71 | ecs_vector_free(value); 72 | } 73 | 74 | ecs_fini(world); 75 | } 76 | 77 | void Vector_vector_entity() { 78 | ecs_world_t *world = ecs_init(); 79 | 80 | ECS_IMPORT(world, FlecsMeta); 81 | 82 | ECS_META(world, VectorEntity); 83 | 84 | ecs_entity_t e = ecs_set_name(world, 0, "Foo"); 85 | 86 | { 87 | ecs_vector_t *value = ecs_vector_from_array(ecs_entity_t, 3, ((ecs_entity_t[]){0, 1000, e})); 88 | char *str = ecs_ptr_to_str(world, ecs_id(VectorEntity), &value); 89 | test_str(str, "[0, 1000, Foo]"); 90 | ecs_os_free(str); 91 | ecs_vector_free(value); 92 | } 93 | 94 | ecs_fini(world); 95 | } 96 | 97 | void Vector_vector_struct() { 98 | ecs_world_t *world = ecs_init(); 99 | 100 | ECS_IMPORT(world, FlecsMeta); 101 | 102 | ECS_META(world, Point); 103 | ECS_META(world, VectorPoint); 104 | 105 | { 106 | ecs_vector_t *value = ecs_vector_from_array(Point, 2, ((Point[]){{10, 20}, {30, 40}})); 107 | char *str = ecs_ptr_to_str(world, ecs_id(VectorPoint), &value); 108 | test_str(str, "[{x = 10, y = 20}, {x = 30, y = 40}]"); 109 | ecs_os_free(str); 110 | ecs_vector_free(value); 111 | } 112 | 113 | ecs_fini(world); 114 | } 115 | 116 | void Vector_vector_nested_struct() { 117 | ecs_world_t *world = ecs_init(); 118 | 119 | ECS_IMPORT(world, FlecsMeta); 120 | 121 | ECS_META(world, Point); 122 | ECS_META(world, Line); 123 | ECS_META(world, VectorLine); 124 | 125 | { 126 | ecs_vector_t *value = ecs_vector_from_array(Line, 2, ((Line[]){ 127 | {{10, 20}, {30, 40}}, 128 | {{50, 60}, {70, 80}} 129 | })); 130 | char *str = ecs_ptr_to_str(world, ecs_id(VectorLine), &value); 131 | test_str(str, "[{start = {x = 10, y = 20}, stop = {x = 30, y = 40}}, {start = {x = 50, y = 60}, stop = {x = 70, y = 80}}]"); 132 | ecs_os_free(str); 133 | ecs_vector_free(value); 134 | } 135 | 136 | ecs_fini(world); 137 | } 138 | 139 | void Vector_vector_vector_int() { 140 | ecs_world_t *world = ecs_init(); 141 | 142 | ECS_IMPORT(world, FlecsMeta); 143 | 144 | ECS_META(world, VectorInt); 145 | ECS_META(world, VectorVectorInt); 146 | 147 | { 148 | ecs_vector_t *v1 = ecs_vector_new(int32_t, 2); 149 | *ecs_vector_add(&v1, int32_t) = 10; 150 | *ecs_vector_add(&v1, int32_t) = -20; 151 | 152 | ecs_vector_t *v2 = ecs_vector_new(int32_t, 2); 153 | *ecs_vector_add(&v2, int32_t) = 30; 154 | *ecs_vector_add(&v2, int32_t) = -40; 155 | 156 | ecs_vector_t *value = ecs_vector_from_array(ecs_vector_t*, 2, ((ecs_vector_t*[]){v1, v2})); 157 | char *str = ecs_ptr_to_str(world, ecs_id(VectorVectorInt), &value); 158 | test_str(str, "[[10, -20], [30, -40]]"); 159 | ecs_os_free(str); 160 | ecs_vector_free(value); 161 | ecs_vector_free(v1); 162 | ecs_vector_free(v2); 163 | } 164 | 165 | ecs_fini(world); 166 | } 167 | 168 | void Vector_vector_vector_struct() { 169 | ecs_world_t *world = ecs_init(); 170 | 171 | ECS_IMPORT(world, FlecsMeta); 172 | 173 | ECS_META(world, Point); 174 | ECS_META(world, VectorPoint); 175 | ECS_META(world, VectorVectorPoint); 176 | 177 | { 178 | ecs_vector_t *v1 = ecs_vector_new(Point, 2); 179 | *ecs_vector_add(&v1, Point) = (Point){10, -20}; 180 | *ecs_vector_add(&v1, Point) = (Point){30, -40}; 181 | 182 | ecs_vector_t *v2 = ecs_vector_new(Point, 2); 183 | *ecs_vector_add(&v2, Point) = (Point){50, -60}; 184 | *ecs_vector_add(&v2, Point) = (Point){70, -80}; 185 | 186 | ecs_vector_t *value = ecs_vector_from_array(ecs_vector_t*, 2, ((ecs_vector_t*[]){v1, v2})); 187 | char *str = ecs_ptr_to_str(world, ecs_id(VectorVectorPoint), &value); 188 | test_str(str, "[[{x = 10, y = -20}, {x = 30, y = -40}], [{x = 50, y = -60}, {x = 70, y = -80}]]"); 189 | ecs_os_free(str); 190 | ecs_vector_free(value); 191 | ecs_vector_free(v1); 192 | ecs_vector_free(v2); 193 | } 194 | 195 | ecs_fini(world); 196 | } 197 | 198 | void Vector_vector_vector_nested_struct() { 199 | ecs_world_t *world = ecs_init(); 200 | 201 | ECS_IMPORT(world, FlecsMeta); 202 | 203 | ECS_META(world, Point); 204 | ECS_META(world, Line); 205 | ECS_META(world, VectorLine); 206 | ECS_META(world, VectorVectorLine); 207 | 208 | { 209 | Line l1 = {{10, 20}, {30, 40}}; 210 | Line l2 = {{50, 60}, {70, 80}}; 211 | Line l3 = {{90, 100}, {110, 120}}; 212 | Line l4 = {{130, 140}, {150, 160}}; 213 | 214 | ecs_vector_t *v1 = ecs_vector_new(Line, 2); 215 | *ecs_vector_add(&v1, Line) = l1; 216 | *ecs_vector_add(&v1, Line) = l2; 217 | 218 | ecs_vector_t *v2 = ecs_vector_new(Line, 2); 219 | *ecs_vector_add(&v2, Line) = l3; 220 | *ecs_vector_add(&v2, Line) = l4; 221 | 222 | ecs_vector_t *value = ecs_vector_from_array(ecs_vector_t*, 2, ((ecs_vector_t*[]){v1, v2})); 223 | char *str = ecs_ptr_to_str(world, ecs_id(VectorVectorLine), &value); 224 | test_str(str, 225 | "[[{start = {x = 10, y = 20}, stop = {x = 30, y = 40}}, " 226 | "{start = {x = 50, y = 60}, stop = {x = 70, y = 80}}], " 227 | "[{start = {x = 90, y = 100}, stop = {x = 110, y = 120}}, " 228 | "{start = {x = 130, y = 140}, stop = {x = 150, y = 160}}]]"); 229 | 230 | ecs_os_free(str); 231 | ecs_vector_free(value); 232 | ecs_vector_free(v1); 233 | ecs_vector_free(v2); 234 | } 235 | 236 | ecs_fini(world); 237 | } 238 | 239 | void Vector_vector_null() { 240 | ecs_world_t *world = ecs_init(); 241 | 242 | ECS_IMPORT(world, FlecsMeta); 243 | 244 | ECS_META(world, VectorBool); 245 | 246 | { 247 | ecs_vector_t *value = NULL; 248 | char *str = ecs_ptr_to_str(world, ecs_id(VectorBool), &value); 249 | test_str(str, "nullptr"); 250 | ecs_os_free(str); 251 | ecs_vector_free(value); 252 | } 253 | 254 | ecs_fini(world); 255 | } 256 | 257 | void Vector_vector_vector_null() { 258 | ecs_world_t *world = ecs_init(); 259 | 260 | ECS_IMPORT(world, FlecsMeta); 261 | 262 | ECS_META(world, VectorInt); 263 | ECS_META(world, VectorVectorInt); 264 | 265 | { 266 | ecs_vector_t *value = ecs_vector_from_array(ecs_vector_t*, 2, ((ecs_vector_t*[]){NULL, NULL})); 267 | char *str = ecs_ptr_to_str(world, ecs_id(VectorVectorInt), &value); 268 | test_str(str, "[nullptr, nullptr]"); 269 | ecs_os_free(str); 270 | ecs_vector_free(value); 271 | } 272 | 273 | ecs_fini(world); 274 | } 275 | 276 | void Vector_vector_empty() { 277 | ecs_world_t *world = ecs_init(); 278 | 279 | ECS_IMPORT(world, FlecsMeta); 280 | 281 | ECS_META(world, VectorInt); 282 | ECS_META(world, VectorVectorInt); 283 | 284 | { 285 | ecs_vector_t *value = ecs_vector_new(ecs_vector_t*, 2); 286 | char *str = ecs_ptr_to_str(world, ecs_id(VectorVectorInt), &value); 287 | test_str(str, "[]"); 288 | ecs_os_free(str); 289 | ecs_vector_free(value); 290 | } 291 | 292 | ecs_fini(world); 293 | } 294 | 295 | void Vector_vector_vector_empty() { 296 | ecs_world_t *world = ecs_init(); 297 | 298 | ECS_IMPORT(world, FlecsMeta); 299 | 300 | ECS_META(world, VectorInt); 301 | ECS_META(world, VectorVectorInt); 302 | 303 | { 304 | ecs_vector_t *v1 = ecs_vector_new(int32_t, 0); 305 | ecs_vector_t *v2 = ecs_vector_new(int32_t, 0); 306 | ecs_vector_t *value = ecs_vector_from_array(ecs_vector_t*, 2, ((ecs_vector_t*[]){v1, v2})); 307 | char *str = ecs_ptr_to_str(world, ecs_id(VectorVectorInt), &value); 308 | test_str(str, "[[], []]"); 309 | ecs_os_free(str); 310 | ecs_vector_free(value); 311 | ecs_vector_free(v1); 312 | ecs_vector_free(v2); 313 | } 314 | 315 | ecs_fini(world); 316 | } 317 | 318 | -------------------------------------------------------------------------------- /test/serialize/src/main.c: -------------------------------------------------------------------------------- 1 | 2 | /* A friendly warning from bake.test 3 | * ---------------------------------------------------------------------------- 4 | * This file is generated. To add/remove testcases modify the 'project.json' of 5 | * the test project. ANY CHANGE TO THIS FILE IS LOST AFTER (RE)BUILDING! 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #include 10 | 11 | // Testsuite 'Primitive' 12 | void Primitive_bool(void); 13 | void Primitive_byte(void); 14 | void Primitive_char(void); 15 | void Primitive_i8(void); 16 | void Primitive_i16(void); 17 | void Primitive_i32(void); 18 | void Primitive_i64(void); 19 | void Primitive_iptr(void); 20 | void Primitive_u8(void); 21 | void Primitive_u16(void); 22 | void Primitive_u32(void); 23 | void Primitive_u64(void); 24 | void Primitive_uptr(void); 25 | void Primitive_float(void); 26 | void Primitive_double(void); 27 | void Primitive_string(void); 28 | void Primitive_entity(void); 29 | 30 | // Testsuite 'Struct' 31 | void Struct_struct(void); 32 | void Struct_nested_struct(void); 33 | void Struct_struct_bool_i32(void); 34 | void Struct_struct_i32_bool(void); 35 | 36 | // Testsuite 'Enum' 37 | void Enum_enum(void); 38 | void Enum_enum_explicit_values(void); 39 | void Enum_enum_invalid_value(void); 40 | 41 | // Testsuite 'Bitmask' 42 | void Bitmask_bitmask_1(void); 43 | void Bitmask_bitmask_2(void); 44 | void Bitmask_bitmask_3(void); 45 | void Bitmask_bitmask_0_value(void); 46 | 47 | // Testsuite 'Array' 48 | void Array_array_bool(void); 49 | void Array_array_int(void); 50 | void Array_array_string(void); 51 | void Array_array_entity(void); 52 | void Array_struct_array_int(void); 53 | void Array_array_struct(void); 54 | void Array_array_nested_struct(void); 55 | void Array_array_array_int(void); 56 | void Array_array_array_string(void); 57 | void Array_array_array_struct(void); 58 | void Array_array_array_nested_struct(void); 59 | 60 | // Testsuite 'Vector' 61 | void Vector_vector_bool(void); 62 | void Vector_vector_int(void); 63 | void Vector_vector_string(void); 64 | void Vector_vector_entity(void); 65 | void Vector_vector_struct(void); 66 | void Vector_vector_nested_struct(void); 67 | void Vector_vector_vector_int(void); 68 | void Vector_vector_vector_struct(void); 69 | void Vector_vector_vector_nested_struct(void); 70 | void Vector_vector_empty(void); 71 | void Vector_vector_vector_empty(void); 72 | void Vector_vector_null(void); 73 | void Vector_vector_vector_null(void); 74 | 75 | // Testsuite 'Map' 76 | void Map_map_bool_bool(void); 77 | void Map_map_int_bool(void); 78 | void Map_map_string_bool(void); 79 | void Map_map_enum_bool(void); 80 | void Map_map_bitmask_bool(void); 81 | void Map_map_int_int(void); 82 | void Map_map_int_string(void); 83 | void Map_map_int_struct(void); 84 | void Map_map_int_nested_struct(void); 85 | void Map_map_int_array_int(void); 86 | void Map_map_int_vector_int(void); 87 | void Map_map_int_map_int_bool(void); 88 | 89 | bake_test_case Primitive_testcases[] = { 90 | { 91 | "bool", 92 | Primitive_bool 93 | }, 94 | { 95 | "byte", 96 | Primitive_byte 97 | }, 98 | { 99 | "char", 100 | Primitive_char 101 | }, 102 | { 103 | "i8", 104 | Primitive_i8 105 | }, 106 | { 107 | "i16", 108 | Primitive_i16 109 | }, 110 | { 111 | "i32", 112 | Primitive_i32 113 | }, 114 | { 115 | "i64", 116 | Primitive_i64 117 | }, 118 | { 119 | "iptr", 120 | Primitive_iptr 121 | }, 122 | { 123 | "u8", 124 | Primitive_u8 125 | }, 126 | { 127 | "u16", 128 | Primitive_u16 129 | }, 130 | { 131 | "u32", 132 | Primitive_u32 133 | }, 134 | { 135 | "u64", 136 | Primitive_u64 137 | }, 138 | { 139 | "uptr", 140 | Primitive_uptr 141 | }, 142 | { 143 | "float", 144 | Primitive_float 145 | }, 146 | { 147 | "double", 148 | Primitive_double 149 | }, 150 | { 151 | "string", 152 | Primitive_string 153 | }, 154 | { 155 | "entity", 156 | Primitive_entity 157 | } 158 | }; 159 | 160 | bake_test_case Struct_testcases[] = { 161 | { 162 | "struct", 163 | Struct_struct 164 | }, 165 | { 166 | "nested_struct", 167 | Struct_nested_struct 168 | }, 169 | { 170 | "struct_bool_i32", 171 | Struct_struct_bool_i32 172 | }, 173 | { 174 | "struct_i32_bool", 175 | Struct_struct_i32_bool 176 | } 177 | }; 178 | 179 | bake_test_case Enum_testcases[] = { 180 | { 181 | "enum", 182 | Enum_enum 183 | }, 184 | { 185 | "enum_explicit_values", 186 | Enum_enum_explicit_values 187 | }, 188 | { 189 | "enum_invalid_value", 190 | Enum_enum_invalid_value 191 | } 192 | }; 193 | 194 | bake_test_case Bitmask_testcases[] = { 195 | { 196 | "bitmask_1", 197 | Bitmask_bitmask_1 198 | }, 199 | { 200 | "bitmask_2", 201 | Bitmask_bitmask_2 202 | }, 203 | { 204 | "bitmask_3", 205 | Bitmask_bitmask_3 206 | }, 207 | { 208 | "bitmask_0_value", 209 | Bitmask_bitmask_0_value 210 | } 211 | }; 212 | 213 | bake_test_case Array_testcases[] = { 214 | { 215 | "array_bool", 216 | Array_array_bool 217 | }, 218 | { 219 | "array_int", 220 | Array_array_int 221 | }, 222 | { 223 | "array_string", 224 | Array_array_string 225 | }, 226 | { 227 | "array_entity", 228 | Array_array_entity 229 | }, 230 | { 231 | "struct_array_int", 232 | Array_struct_array_int 233 | }, 234 | { 235 | "array_struct", 236 | Array_array_struct 237 | }, 238 | { 239 | "array_nested_struct", 240 | Array_array_nested_struct 241 | }, 242 | { 243 | "array_array_int", 244 | Array_array_array_int 245 | }, 246 | { 247 | "array_array_string", 248 | Array_array_array_string 249 | }, 250 | { 251 | "array_array_struct", 252 | Array_array_array_struct 253 | }, 254 | { 255 | "array_array_nested_struct", 256 | Array_array_array_nested_struct 257 | } 258 | }; 259 | 260 | bake_test_case Vector_testcases[] = { 261 | { 262 | "vector_bool", 263 | Vector_vector_bool 264 | }, 265 | { 266 | "vector_int", 267 | Vector_vector_int 268 | }, 269 | { 270 | "vector_string", 271 | Vector_vector_string 272 | }, 273 | { 274 | "vector_entity", 275 | Vector_vector_entity 276 | }, 277 | { 278 | "vector_struct", 279 | Vector_vector_struct 280 | }, 281 | { 282 | "vector_nested_struct", 283 | Vector_vector_nested_struct 284 | }, 285 | { 286 | "vector_vector_int", 287 | Vector_vector_vector_int 288 | }, 289 | { 290 | "vector_vector_struct", 291 | Vector_vector_vector_struct 292 | }, 293 | { 294 | "vector_vector_nested_struct", 295 | Vector_vector_vector_nested_struct 296 | }, 297 | { 298 | "vector_empty", 299 | Vector_vector_empty 300 | }, 301 | { 302 | "vector_vector_empty", 303 | Vector_vector_vector_empty 304 | }, 305 | { 306 | "vector_null", 307 | Vector_vector_null 308 | }, 309 | { 310 | "vector_vector_null", 311 | Vector_vector_vector_null 312 | } 313 | }; 314 | 315 | bake_test_case Map_testcases[] = { 316 | { 317 | "map_bool_bool", 318 | Map_map_bool_bool 319 | }, 320 | { 321 | "map_int_bool", 322 | Map_map_int_bool 323 | }, 324 | { 325 | "map_string_bool", 326 | Map_map_string_bool 327 | }, 328 | { 329 | "map_enum_bool", 330 | Map_map_enum_bool 331 | }, 332 | { 333 | "map_bitmask_bool", 334 | Map_map_bitmask_bool 335 | }, 336 | { 337 | "map_int_int", 338 | Map_map_int_int 339 | }, 340 | { 341 | "map_int_string", 342 | Map_map_int_string 343 | }, 344 | { 345 | "map_int_struct", 346 | Map_map_int_struct 347 | }, 348 | { 349 | "map_int_nested_struct", 350 | Map_map_int_nested_struct 351 | }, 352 | { 353 | "map_int_array_int", 354 | Map_map_int_array_int 355 | }, 356 | { 357 | "map_int_vector_int", 358 | Map_map_int_vector_int 359 | }, 360 | { 361 | "map_int_map_int_bool", 362 | Map_map_int_map_int_bool 363 | } 364 | }; 365 | 366 | static bake_test_suite suites[] = { 367 | { 368 | "Primitive", 369 | NULL, 370 | NULL, 371 | 17, 372 | Primitive_testcases 373 | }, 374 | { 375 | "Struct", 376 | NULL, 377 | NULL, 378 | 4, 379 | Struct_testcases 380 | }, 381 | { 382 | "Enum", 383 | NULL, 384 | NULL, 385 | 3, 386 | Enum_testcases 387 | }, 388 | { 389 | "Bitmask", 390 | NULL, 391 | NULL, 392 | 4, 393 | Bitmask_testcases 394 | }, 395 | { 396 | "Array", 397 | NULL, 398 | NULL, 399 | 11, 400 | Array_testcases 401 | }, 402 | { 403 | "Vector", 404 | NULL, 405 | NULL, 406 | 13, 407 | Vector_testcases 408 | }, 409 | { 410 | "Map", 411 | NULL, 412 | NULL, 413 | 12, 414 | Map_testcases 415 | } 416 | }; 417 | 418 | int main(int argc, char *argv[]) { 419 | ut_init(argv[0]); 420 | return bake_test_run("test", argc, argv, suites, 7); 421 | } 422 | --------------------------------------------------------------------------------