├── .cargo └── config.toml ├── .gitattributes ├── .github └── workflows │ ├── ci.yml │ └── deploy-book.yml ├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── Cargo.toml ├── LICENSE ├── Makefile.toml ├── README.md ├── _typos.toml ├── assets └── hyperion.png ├── flecs_ecs ├── .cargo │ └── config.toml ├── Cargo.toml ├── LICENSE ├── README.md ├── assets │ └── flecs_rust_logo.png ├── doc │ └── flecs │ │ ├── book.toml │ │ ├── src │ │ ├── SUMMARY.md │ │ ├── docreplace │ │ ├── img │ │ │ ├── component_lifecycle_flow.png │ │ │ ├── explorer.png │ │ │ ├── filter_diagram.png │ │ │ ├── flecs-quickstart-overview.png │ │ │ ├── logo.png │ │ │ ├── logo_small.png │ │ │ ├── logo_small_dark.png │ │ │ ├── playground.png │ │ │ ├── projects │ │ │ │ ├── after_sun.png │ │ │ │ ├── age_of_respair.png │ │ │ │ ├── city.png │ │ │ │ ├── equilibrium_engine.png │ │ │ │ ├── extermination_shock.png │ │ │ │ ├── hyperion.png │ │ │ │ ├── hytale.png │ │ │ │ ├── resistance_is_brutal.jpg │ │ │ │ ├── sol_survivor.png │ │ │ │ ├── tempest_rising.png │ │ │ │ ├── territory_control.jpg │ │ │ │ ├── the_forge.jpg │ │ │ │ ├── tome_tumble.png │ │ │ │ └── tower_defense.png │ │ │ ├── query_instancing.png │ │ │ ├── relationship_traversal.png │ │ │ └── script_tutorial │ │ │ │ ├── tut_playground.png │ │ │ │ ├── tut_playground_assembly.png │ │ │ │ ├── tut_playground_assembly_error.png │ │ │ │ ├── tut_playground_bar.png │ │ │ │ ├── tut_playground_box.png │ │ │ │ ├── tut_playground_component.png │ │ │ │ ├── tut_playground_empty.png │ │ │ │ ├── tut_playground_entity.png │ │ │ │ ├── tut_playground_fence.png │ │ │ │ ├── tut_playground_grid.png │ │ │ │ ├── tut_playground_grids.png │ │ │ │ ├── tut_playground_half_box.png │ │ │ │ ├── tut_playground_hierarchy.png │ │ │ │ ├── tut_playground_inspector.png │ │ │ │ ├── tut_playground_instance.png │ │ │ │ ├── tut_playground_pasture.png │ │ │ │ ├── tut_playground_pasture_2.png │ │ │ │ ├── tut_playground_pillar_grid.png │ │ │ │ ├── tut_playground_pillars.png │ │ │ │ ├── tut_playground_plane.png │ │ │ │ ├── tut_playground_plane_rotated.png │ │ │ │ ├── tut_playground_plane_wrong.png │ │ │ │ ├── tut_playground_prefab.png │ │ │ │ ├── tut_playground_preview.png │ │ │ │ ├── tut_playground_town.png │ │ │ │ ├── tut_playground_two_instances.png │ │ │ │ └── tut_playground_vars.png │ │ └── quickstart.md │ │ └── theme │ │ ├── ayu-highlight.css │ │ ├── book.js │ │ ├── css │ │ ├── chrome.css │ │ ├── general.css │ │ ├── print.css │ │ └── variables.css │ │ ├── favicon.png │ │ ├── favicon.svg │ │ ├── fonts │ │ ├── OPEN-SANS-LICENSE.txt │ │ ├── SOURCE-CODE-PRO-LICENSE.txt │ │ ├── fonts.css │ │ ├── open-sans-v17-all-charsets-300.woff2 │ │ ├── open-sans-v17-all-charsets-300italic.woff2 │ │ ├── open-sans-v17-all-charsets-600.woff2 │ │ ├── open-sans-v17-all-charsets-600italic.woff2 │ │ ├── open-sans-v17-all-charsets-700.woff2 │ │ ├── open-sans-v17-all-charsets-700italic.woff2 │ │ ├── open-sans-v17-all-charsets-800.woff2 │ │ ├── open-sans-v17-all-charsets-800italic.woff2 │ │ ├── open-sans-v17-all-charsets-italic.woff2 │ │ ├── open-sans-v17-all-charsets-regular.woff2 │ │ └── source-code-pro-v11-all-charsets-500.woff2 │ │ ├── highlight.css │ │ ├── highlight.js │ │ ├── index.hbs │ │ ├── mdbook-admonish.css │ │ ├── tabs.css │ │ └── tabs.js ├── examples │ └── flecs │ │ ├── entities │ │ ├── entity_basics.rs │ │ ├── entity_hierarchy.rs │ │ ├── entity_hooks.rs │ │ ├── entity_iterate_components.rs │ │ ├── entity_prefab.rs │ │ └── mod.rs │ │ ├── game_mechanics │ │ ├── inventory_system.rs │ │ └── mod.rs │ │ ├── hello_world.rs │ │ ├── observers │ │ ├── mod.rs │ │ ├── observer_basics.rs │ │ ├── observer_custom_event.rs │ │ ├── observer_entity_event.rs │ │ ├── observer_monitor.rs │ │ ├── observer_propagate.rs │ │ ├── observer_two_components.rs │ │ └── observer_yield_existing.rs │ │ ├── prefabs │ │ ├── mod.rs │ │ ├── prefab_basics.rs │ │ ├── prefab_hierarchy.rs │ │ ├── prefab_nested.rs │ │ ├── prefab_override.rs │ │ ├── prefab_slots.rs │ │ ├── prefab_typed.rs │ │ └── prefab_variant.rs │ │ ├── queries │ │ ├── mod.rs │ │ ├── query_basics.rs │ │ ├── query_chaining_queries.rs │ │ ├── query_change_tracking_1.rs │ │ ├── query_change_tracking_2.rs │ │ ├── query_component_inheritance.rs │ │ ├── query_cyclic_variables.rs │ │ ├── query_facts.rs │ │ ├── query_find_entity.rs │ │ ├── query_group_by.rs │ │ ├── query_group_by_callbacks.rs │ │ ├── query_group_by_custom.rs │ │ ├── query_group_iter.rs │ │ ├── query_hierarchy.rs │ │ ├── query_pass_query_to_system.rs │ │ ├── query_run.rs │ │ ├── query_setting_variables.rs │ │ ├── query_singleton.rs │ │ ├── query_sorting.rs │ │ ├── query_transitive_queries.rs │ │ ├── query_variables.rs │ │ ├── query_wildcard.rs │ │ ├── query_with.rs │ │ ├── query_without.rs │ │ └── query_world_query.rs │ │ ├── reflection │ │ ├── entity_type.rs │ │ ├── member_ranges.rs │ │ ├── mod.rs │ │ ├── reflection_basics.rs │ │ ├── reflection_basics_bitmask.rs │ │ ├── reflection_basics_deserialize.rs │ │ ├── reflection_basics_json.rs │ │ ├── reflection_basics_simple_enum.rs │ │ ├── reflection_nested_set_member.rs │ │ ├── reflection_nested_struct.rs │ │ ├── reflection_query_to_custom_json.rs │ │ ├── reflection_query_to_json.rs │ │ ├── reflection_runtime_component.rs │ │ ├── reflection_runtime_nested_component.rs │ │ ├── reflection_ser_opaque_type.rs │ │ ├── reflection_ser_std_string.rs │ │ ├── reflection_ser_std_vector_builtin_types.rs │ │ ├── reflection_ser_std_vector_custom_types.rs │ │ └── reflection_world_ser_deser.rs │ │ ├── relationships │ │ ├── mod.rs │ │ ├── relationships_basics.rs │ │ ├── relationships_component_data.rs │ │ ├── relationships_enum.rs │ │ ├── relationships_exclusive.rs │ │ ├── relationships_symmetric.rs │ │ └── relationships_union.rs │ │ ├── script │ │ ├── anonymous_entity.flecs │ │ ├── docs.flecs │ │ ├── expressions.flecs │ │ ├── hello_world.flecs │ │ ├── prefabs.flecs │ │ ├── reflection.flecs │ │ ├── strings.flecs │ │ └── with.flecs │ │ ├── systems │ │ ├── mod.rs │ │ ├── system_basics.rs │ │ ├── system_ctx.rs │ │ ├── system_custom_phases.rs │ │ ├── system_custom_phases_no_builtin.rs │ │ ├── system_custom_pipeline.rs │ │ ├── system_custom_runner.rs │ │ ├── system_delta_time.rs │ │ ├── system_immediate.rs │ │ ├── system_mutate_entity.rs │ │ ├── system_mutate_entity_handle.rs │ │ ├── system_pipeline.rs │ │ ├── system_startup_system.rs │ │ ├── system_sync_point.rs │ │ ├── system_sync_point_delete.rs │ │ ├── system_target_fps.rs │ │ └── system_time_interval.rs │ │ ├── z_ignore_main_test.rs │ │ ├── z_ignore_test_common.rs │ │ └── z_ignore_test_snapshots │ │ ├── test@entity_basics.snap │ │ ├── test@entity_hierarchy.snap │ │ ├── test@entity_hooks.snap │ │ ├── test@entity_iterate_components.snap │ │ ├── test@entity_prefab.snap │ │ ├── test@hello world.snap │ │ ├── test@observer_basics.snap │ │ ├── test@observer_custom_event.snap │ │ ├── test@observer_entity_event.snap │ │ ├── test@observer_monitor.snap │ │ ├── test@observer_propagate.snap │ │ ├── test@observer_two_components.snap │ │ ├── test@observer_yield_existing.snap │ │ ├── test@prefab_basics.snap │ │ ├── test@prefab_hierarchy.snap │ │ ├── test@prefab_nested.snap │ │ ├── test@prefab_override.snap │ │ ├── test@prefab_slots.snap │ │ ├── test@prefab_typed.snap │ │ ├── test@prefab_variant.snap │ │ ├── test@query_basics.snap │ │ ├── test@query_chaining_queries.snap │ │ ├── test@query_change_tracking_1.snap │ │ ├── test@query_change_tracking_2.snap │ │ ├── test@query_component_inheritance.snap │ │ ├── test@query_cyclic_variables.snap │ │ ├── test@query_facts.snap │ │ ├── test@query_find_entity.snap │ │ ├── test@query_group_by.snap │ │ ├── test@query_group_by_callbacks.snap │ │ ├── test@query_group_by_custom.snap │ │ ├── test@query_group_iter.snap │ │ ├── test@query_hierarchy.snap │ │ ├── test@query_pass_query_to_system.snap │ │ ├── test@query_run_iter.snap │ │ ├── test@query_setting_variables.snap │ │ ├── test@query_singleton.snap │ │ ├── test@query_sorting.snap │ │ ├── test@query_transitive_queries.snap │ │ ├── test@query_variables.snap │ │ ├── test@query_wildcard.snap │ │ ├── test@query_with.snap │ │ ├── test@query_without.snap │ │ ├── test@query_world_query.snap │ │ ├── test@reflection_basics.snap │ │ ├── test@reflection_basics_json.snap │ │ ├── test@reflection_basics_simple_enum.snap │ │ ├── test@reflection_bitmask.snap │ │ ├── test@reflection_deserialize.snap │ │ ├── test@reflection_nested_set_member.snap │ │ ├── test@reflection_nested_struct.snap │ │ ├── test@reflection_query_to_custom_json.snap │ │ ├── test@reflection_query_to_json.snap │ │ ├── test@reflection_runtime_component.snap │ │ ├── test@reflection_runtime_nested_component.snap │ │ ├── test@reflection_ser_opaque_type.snap │ │ ├── test@reflection_ser_std_string.snap │ │ ├── test@reflection_ser_std_vector_builtin_types.snap │ │ ├── test@reflection_ser_std_vector_custom_types.snap │ │ ├── test@reflection_world_ser_deser.snap │ │ ├── test@relationships_basics.snap │ │ ├── test@relationships_exclusive.snap │ │ ├── test@relationships_symmetric.snap │ │ ├── test@relationships_union.snap │ │ ├── test@system_basics.snap │ │ ├── test@system_custom_phases.snap │ │ ├── test@system_custom_phases_no_builtin.snap │ │ ├── test@system_custom_pipeline.snap │ │ ├── test@system_custom_runner.snap │ │ ├── test@system_pipeline.snap │ │ └── test@system_startup_system.snap ├── src │ ├── addons │ │ ├── alerts │ │ │ ├── alert_builder.rs │ │ │ ├── mod.rs │ │ │ ├── module.rs │ │ │ └── types.rs │ │ ├── app.rs │ │ ├── doc.rs │ │ ├── json │ │ │ └── mod.rs │ │ ├── meta │ │ │ ├── builtin.rs │ │ │ ├── component_id_fetcher.rs │ │ │ ├── cursor.rs │ │ │ ├── declarations.rs │ │ │ ├── impl_bindings.rs │ │ │ ├── impl_primitives.rs │ │ │ ├── macros │ │ │ │ ├── macro_component.rs │ │ │ │ ├── macro_meta_register_vector.rs │ │ │ │ └── mod.rs │ │ │ ├── meta_functions.rs │ │ │ ├── meta_traits.rs │ │ │ ├── mod.rs │ │ │ └── opaque.rs │ │ ├── metrics │ │ │ ├── metric_builder.rs │ │ │ ├── mod.rs │ │ │ ├── module.rs │ │ │ └── types.rs │ │ ├── mod.rs │ │ ├── module.rs │ │ ├── pipeline │ │ │ ├── mod.rs │ │ │ └── pipeline_builder.rs │ │ ├── script │ │ │ ├── mod.rs │ │ │ ├── script_builder.rs │ │ │ ├── script_entity_view.rs │ │ │ └── unmanaged_script.rs │ │ ├── stats.rs │ │ ├── system │ │ │ ├── mod.rs │ │ │ ├── system_builder.rs │ │ │ └── system_runner_fluent.rs │ │ ├── timer.rs │ │ └── units │ │ │ ├── mod.rs │ │ │ └── types.rs │ ├── core │ │ ├── archetype.rs │ │ ├── builder.rs │ │ ├── c_types.rs │ │ ├── cloned_tuple.rs │ │ ├── component_registration │ │ │ ├── helpers.rs │ │ │ ├── mod.rs │ │ │ ├── registration.rs │ │ │ ├── registration_traits.rs │ │ │ └── registration_types.rs │ │ ├── components │ │ │ ├── cached_ref.rs │ │ │ ├── component.rs │ │ │ ├── component_binding.rs │ │ │ ├── component_untyped.rs │ │ │ ├── lifecycle_traits.rs │ │ │ └── mod.rs │ │ ├── ecs_os_api.rs │ │ ├── entity.rs │ │ ├── entity_view │ │ │ ├── bulk_entity_builder.rs │ │ │ ├── entity_view_const.rs │ │ │ ├── entity_view_impl.rs │ │ │ ├── entity_view_mut.rs │ │ │ ├── macros.rs │ │ │ └── mod.rs │ │ ├── event.rs │ │ ├── fields_tuple.rs │ │ ├── flecs.rs │ │ ├── get_tuple.rs │ │ ├── id.rs │ │ ├── id_view.rs │ │ ├── mod.rs │ │ ├── observer.rs │ │ ├── observer_builder.rs │ │ ├── query.rs │ │ ├── query_builder.rs │ │ ├── query_iter.rs │ │ ├── query_tuple.rs │ │ ├── table │ │ │ ├── field.rs │ │ │ ├── iter.rs │ │ │ └── mod.rs │ │ ├── term.rs │ │ ├── utility │ │ │ ├── errors.rs │ │ │ ├── functions.rs │ │ │ ├── id.rs │ │ │ ├── id_map.rs │ │ │ ├── log.rs │ │ │ ├── mod.rs │ │ │ ├── traits │ │ │ │ ├── id_operations.rs │ │ │ │ ├── inout_oper.rs │ │ │ │ ├── into_component_id.rs │ │ │ │ ├── into_entity.rs │ │ │ │ ├── into_id.rs │ │ │ │ ├── into_table.rs │ │ │ │ ├── mod.rs │ │ │ │ ├── query_api.rs │ │ │ │ ├── system_api.rs │ │ │ │ └── world_provider.rs │ │ │ └── types.rs │ │ ├── world.rs │ │ └── world_ctx.rs │ ├── decision_reasoning.txt │ ├── lib.rs │ └── prelude.rs └── tests │ ├── ecs_os_api │ └── main.rs │ └── flecs │ ├── clone_default_impl_test.rs │ ├── common_test.rs │ ├── component_lifecycle_test.rs │ ├── component_test.rs │ ├── entity_bulk_rust_test.rs │ ├── entity_rust_test.rs │ ├── entity_test.rs │ ├── enum_test.rs │ ├── eq_test.rs │ ├── flecs_docs_test.rs │ ├── is_ref_test.rs │ ├── main.rs │ ├── meta_macro_test.rs │ ├── meta_test.rs │ ├── meta_test_rust.rs │ ├── meta_trait_test.rs │ ├── observer_rust_test.rs │ ├── observer_test.rs │ ├── query_builder_test.rs │ ├── query_rust_test.rs │ ├── query_test.rs │ ├── system_test.rs │ └── world_test.rs ├── flecs_ecs_derive ├── Cargo.toml ├── LICENSE └── src │ └── lib.rs ├── flecs_ecs_sys ├── Cargo.toml ├── LICENSE ├── build.rs ├── src │ ├── bindings.rs │ ├── extensions.rs │ ├── flecs.c │ ├── flecs.h │ ├── flecs_rust.c │ ├── flecs_rust.h │ ├── lib.rs │ └── mbindings.rs └── tests │ └── check_for_changes.rs ├── scripts ├── fbench_log.sh └── filter_bench_log.sh └── test_crash_handler ├── Cargo.toml └── src └── lib.rs /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.wasm32-unknown-unknown] 2 | rustflags = ['--cfg', 'getrandom_backend="wasm_js"'] 3 | 4 | [alias] 5 | fbench = "criterion --plotting-backend disabled" -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.c linguist-detectable=false 2 | *.h linguist-detectable=false -------------------------------------------------------------------------------- /.github/workflows/deploy-book.yml: -------------------------------------------------------------------------------- 1 | name: Deploy mdBook 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | jobs: 10 | deploy: 11 | runs-on: ubuntu-latest 12 | permissions: 13 | contents: write 14 | concurrency: 15 | group: ${{ github.workflow }}-${{ github.ref }} 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | - name: Setup mdBook 20 | uses: peaceiris/actions-mdbook@v1 21 | with: 22 | mdbook-version: 'latest' 23 | 24 | - name: Install mdbook-admonish 25 | uses: taiki-e/install-action@v2 26 | with: 27 | tool: mdbook-admonish 28 | 29 | - name: Build Book 30 | run: | 31 | cd flecs_ecs/doc/flecs 32 | mdbook build 33 | 34 | - name: Deploy 35 | uses: peaceiris/actions-gh-pages@v3 36 | if: ${{ github.ref == 'refs/heads/main' }} 37 | with: 38 | github_token: ${{ secrets.GITHUB_TOKEN }} 39 | publish_dir: ./flecs_ecs/doc/flecs/book -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /Cargo.lock 3 | flecs_ecs/rustfmt.toml 4 | rustfmt.toml 5 | .DS_Store 6 | .idea 7 | flecs_ecs/src/main.rs 8 | flecs_ecs_test/ 9 | flecs_ecs/benches/fbench_log/ 10 | flecs_ecs/src/old_cached_code/ 11 | flecs_ecs/doc/flecs/docreplace 12 | flecs_ecs/doc/flecs/book/ 13 | flecs_ecs/doc/flecs/src/cheatsheet.md 14 | docreplace/ -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | 5 | { 6 | "name": "(Windows) Launch", 7 | "type": "lldb", 8 | "request": "launch", 9 | "program": "${workspaceFolder}/target/debug/flecs_ecs", 10 | "args": [], 11 | "cwd": "${fileDirname}", 12 | "console": "externalTerminal" 13 | }, 14 | // { 15 | // "type": "lldb", 16 | // "request": "launch", 17 | // "name": "Debug", 18 | // "program": "${workspaceFolder}/target/x86_64-pc-windows-msvc/debug/flecs_ecs.exe", 19 | // "args": [], 20 | // "cwd": "${workspaceFolder}", 21 | // "sourceLanguages": [ 22 | // "rust" 23 | // ], 24 | // "env": { 25 | // "RUSTFLAGS": "-C debuginfo=2" 26 | // }, 27 | // "sourceMap": { 28 | // "/rustc/eb26296b556cef10fb713a38f3d16b9886080f26": "C:/Users/IndradB/.rustup/toolchains/stable-x86_64-pc-windows-msvc/lib/rustlib/src/rust" 29 | // } 30 | // } 31 | ] 32 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | // "rust-analyzer.linkedProjects": [ 3 | // "./flecs_ecs/Cargo.toml" 4 | // ], 5 | // "rust-analyzer.showUnlinkedFileNotification": false 6 | } 7 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = ["flecs_ecs", "flecs_ecs_derive", "flecs_ecs_sys", "test_crash_handler"] 3 | resolver = "2" 4 | 5 | exclude = [ 6 | "flecs_ecs_test", 7 | "docreplace" 8 | ] 9 | 10 | [workspace.package] 11 | edition = "2024" 12 | license = "MIT" 13 | repository = "https://github.com/Indra-db/Flecs-Rust" 14 | # When changing this, update the CI as well. 15 | rust-version = "1.85" 16 | 17 | [workspace.lints.clippy] 18 | doc_markdown = "warn" 19 | float_cmp = "warn" 20 | float_cmp_const = "warn" 21 | print_stderr = "warn" 22 | print_stdout = "warn" 23 | semicolon_if_nothing_returned = "warn" 24 | manual_let_else = "warn" 25 | redundant_closure_for_method_calls = "warn" 26 | redundant_else = "warn" 27 | unwrap_or_default = "warn" 28 | too_many_arguments = "allow" 29 | std_instead_of_core = "warn" 30 | std_instead_of_alloc = "warn" 31 | alloc_instead_of_core = "warn" 32 | 33 | [workspace.lints] 34 | rust.unused_lifetimes = "warn" 35 | 36 | [workspace.dependencies] 37 | flecs_ecs = { version = "0.1.2", path = "flecs_ecs" } 38 | flecs_ecs_derive = { version = "0.1.0", path = "flecs_ecs_derive" } 39 | flecs_ecs_sys = { version = "0.1.2", path = "flecs_ecs_sys" } 40 | libc = "0.2.169" 41 | 42 | [profile.release] 43 | lto = true 44 | codegen-units = 1 45 | panic = "abort" 46 | 47 | [profile.dev.package] 48 | insta.opt-level = 3 49 | similar.opt-level = 3 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Indra de Backere 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 | -------------------------------------------------------------------------------- /_typos.toml: -------------------------------------------------------------------------------- 1 | [files] 2 | extend-exclude = [ 3 | "flecs_ecs_sys/**/*", 4 | "target/**/*", 5 | "flecs_ecs/examples/flecs/z_ignore_test_snapshots/**/*", 6 | "flecs_ecs/doc/flecs/theme/**/*", 7 | "flecs_ecs/doc/flecs/book/**/*", 8 | ] 9 | 10 | [default.extend-words] 11 | fo = "fo" 12 | -------------------------------------------------------------------------------- /assets/hyperion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/assets/hyperion.png -------------------------------------------------------------------------------- /flecs_ecs/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | #[unstable] 2 | #build-std = ["core", "alloc", "std"] 3 | 4 | #[build] 5 | #target = "x86_64-pc-windows-msvc" 6 | 7 | [alias] 8 | fbench = "criterion --plotting-backend disabled" 9 | -------------------------------------------------------------------------------- /flecs_ecs/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Indra de Backere 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 | -------------------------------------------------------------------------------- /flecs_ecs/assets/flecs_rust_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/assets/flecs_rust_logo.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | name = "Flecs Rust" 3 | authors = ["Indradb"] 4 | description = "Documentation for the Rust bindings of Flecs ECS" 5 | language = "en" 6 | multilingual = false 7 | src = "src" 8 | title = "Flecs Rust" 9 | 10 | [output.html] 11 | git-repository-url = "https://github.com/Indra-db/Flecs-Rust" 12 | edit-url-template = "https://github.com/Indra-db/Flecs-Rust/edit/main/flecs_ecs/doc/{path}" 13 | additional-css = ["theme/tabs.css", "theme/mdbook-admonish.css", "theme/mdbook-admonish.css"] 14 | additional-js = ["theme/tabs.js"] 15 | default-theme = "ayu" 16 | 17 | [output.html.playground] 18 | runnable = false 19 | 20 | [preprocessor.tabs] 21 | 22 | [preprocessor.admonish] 23 | command = "mdbook-admonish" 24 | assets_version = "3.0.3" # do not edit: managed by `mdbook-admonish install` 25 | -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | - [quickstart](./quickstart.md) 4 | -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/docreplace: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/docreplace -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/component_lifecycle_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/component_lifecycle_flow.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/explorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/explorer.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/filter_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/filter_diagram.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/flecs-quickstart-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/flecs-quickstart-overview.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/logo.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/logo_small.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/logo_small_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/logo_small_dark.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/playground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/playground.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/projects/after_sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/projects/after_sun.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/projects/age_of_respair.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/projects/age_of_respair.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/projects/city.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/projects/city.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/projects/equilibrium_engine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/projects/equilibrium_engine.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/projects/extermination_shock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/projects/extermination_shock.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/projects/hyperion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/projects/hyperion.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/projects/hytale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/projects/hytale.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/projects/resistance_is_brutal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/projects/resistance_is_brutal.jpg -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/projects/sol_survivor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/projects/sol_survivor.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/projects/tempest_rising.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/projects/tempest_rising.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/projects/territory_control.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/projects/territory_control.jpg -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/projects/the_forge.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/projects/the_forge.jpg -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/projects/tome_tumble.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/projects/tome_tumble.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/projects/tower_defense.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/projects/tower_defense.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/query_instancing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/query_instancing.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/relationship_traversal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/relationship_traversal.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_assembly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_assembly.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_assembly_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_assembly_error.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_bar.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_box.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_component.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_empty.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_entity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_entity.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_fence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_fence.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_grid.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_grids.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_grids.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_half_box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_half_box.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_hierarchy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_hierarchy.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_inspector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_inspector.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_instance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_instance.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_pasture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_pasture.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_pasture_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_pasture_2.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_pillar_grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_pillar_grid.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_pillars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_pillars.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_plane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_plane.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_plane_rotated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_plane_rotated.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_plane_wrong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_plane_wrong.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_prefab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_prefab.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_preview.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_town.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_town.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_two_instances.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_two_instances.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_vars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/src/img/script_tutorial/tut_playground_vars.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/css/print.css: -------------------------------------------------------------------------------- 1 | 2 | #sidebar, 3 | #menu-bar, 4 | .nav-chapters, 5 | .mobile-nav-chapters { 6 | display: none; 7 | } 8 | 9 | #page-wrapper.page-wrapper { 10 | transform: none !important; 11 | margin-inline-start: 0px; 12 | overflow-y: initial; 13 | } 14 | 15 | #content { 16 | max-width: none; 17 | margin: 0; 18 | padding: 0; 19 | } 20 | 21 | .page { 22 | overflow-y: initial; 23 | } 24 | 25 | code { 26 | direction: ltr !important; 27 | } 28 | 29 | pre > .buttons { 30 | z-index: 2; 31 | } 32 | 33 | a, a:visited, a:active, a:hover { 34 | color: #4183c4; 35 | text-decoration: none; 36 | } 37 | 38 | h1, h2, h3, h4, h5, h6 { 39 | page-break-inside: avoid; 40 | page-break-after: avoid; 41 | } 42 | 43 | pre, code { 44 | page-break-inside: avoid; 45 | white-space: pre-wrap; 46 | } 47 | 48 | .fa { 49 | display: none !important; 50 | } 51 | -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/theme/favicon.png -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-300.woff2 -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-300italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-300italic.woff2 -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-600.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-600.woff2 -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-600italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-600italic.woff2 -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-700.woff2 -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-700italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-700italic.woff2 -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-800.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-800.woff2 -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-800italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-800italic.woff2 -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-italic.woff2 -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/theme/fonts/open-sans-v17-all-charsets-regular.woff2 -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/fonts/source-code-pro-v11-all-charsets-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Indra-db/Flecs-Rust/6558f44610fea67a1a105d854a49d9b71ac02f7c/flecs_ecs/doc/flecs/theme/fonts/source-code-pro-v11-all-charsets-500.woff2 -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/highlight.css: -------------------------------------------------------------------------------- 1 | /* 2 | * An increased contrast highlighting scheme loosely based on the 3 | * "Base16 Atelier Dune Light" theme by Bram de Haan 4 | * (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) 5 | * Original Base16 color scheme by Chris Kempson 6 | * (https://github.com/chriskempson/base16) 7 | */ 8 | 9 | /* Comment */ 10 | .hljs-comment, 11 | .hljs-quote { 12 | color: #575757; 13 | } 14 | 15 | /* Red */ 16 | .hljs-variable, 17 | .hljs-template-variable, 18 | .hljs-attribute, 19 | .hljs-attr, 20 | .hljs-tag, 21 | .hljs-name, 22 | .hljs-regexp, 23 | .hljs-link, 24 | .hljs-name, 25 | .hljs-selector-id, 26 | .hljs-selector-class { 27 | color: #d70025; 28 | } 29 | 30 | /* Orange */ 31 | .hljs-number, 32 | .hljs-meta, 33 | .hljs-built_in, 34 | .hljs-builtin-name, 35 | .hljs-literal, 36 | .hljs-type, 37 | .hljs-params { 38 | color: #b21e00; 39 | } 40 | 41 | /* Green */ 42 | .hljs-string, 43 | .hljs-symbol, 44 | .hljs-bullet { 45 | color: #008200; 46 | } 47 | 48 | /* Blue */ 49 | .hljs-title, 50 | .hljs-section { 51 | color: #0030f2; 52 | } 53 | 54 | /* Purple */ 55 | .hljs-keyword, 56 | .hljs-selector-tag { 57 | color: #9d00ec; 58 | } 59 | 60 | .hljs { 61 | display: block; 62 | overflow-x: auto; 63 | background: #f6f7f6; 64 | color: #000; 65 | } 66 | 67 | .hljs-emphasis { 68 | font-style: italic; 69 | } 70 | 71 | .hljs-strong { 72 | font-weight: bold; 73 | } 74 | 75 | .hljs-addition { 76 | color: #22863a; 77 | background-color: #f0fff4; 78 | } 79 | 80 | .hljs-deletion { 81 | color: #b31d28; 82 | background-color: #ffeef0; 83 | } -------------------------------------------------------------------------------- /flecs_ecs/doc/flecs/theme/tabs.css: -------------------------------------------------------------------------------- 1 | .mdbook-tabs { 2 | display: flex; 3 | } 4 | 5 | .mdbook-tab { 6 | background-color: var(--table-alternate-bg); 7 | padding: 0.5rem 1rem; 8 | cursor: pointer; 9 | border: none; 10 | font-size: 1.6rem; 11 | line-height: 1.45em; 12 | } 13 | 14 | .mdbook-tab.active { 15 | background-color: var(--table-header-bg); 16 | font-weight: bold; 17 | } 18 | 19 | .mdbook-tab-content { 20 | padding: 1rem 0rem; 21 | } 22 | 23 | .mdbook-tab-content table { 24 | margin: unset; 25 | } -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/entities/entity_hooks.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | pub struct Position { 7 | pub x: f32, 8 | pub y: f32, 9 | } 10 | 11 | #[derive(Component)] 12 | pub struct Tag; 13 | 14 | fn main() { 15 | let world = World::new(); 16 | 17 | world 18 | .component::() 19 | .on_add(|entity, _pos| { 20 | println!("added Position to {:?}", entity.name()); 21 | }) 22 | .on_remove(|entity, pos| { 23 | println!("removed {:?} from {:?}", pos, entity.name()); 24 | }) 25 | .on_set(|entity, pos| { 26 | println!("set {:?} for {:?}", pos, entity.name()); 27 | }); 28 | 29 | let entity = world.entity_named("Bob"); 30 | 31 | entity.set(Position { x: 10.0, y: 20.0 }); 32 | 33 | // This operation changes the entity's archetype, which invokes a move 34 | // add is used for adding tags. 35 | entity.add(id::()); 36 | 37 | entity.destruct(); 38 | 39 | // Output: 40 | // added Position { x: 0.0, y: 0.0 } to "Bob" 41 | // set Position { x: 10.0, y: 20.0 } for "Bob" 42 | // removed Position { x: 10.0, y: 20.0 } from "Bob" 43 | } 44 | 45 | #[cfg(feature = "flecs_nightly_tests")] 46 | #[test] 47 | fn test() { 48 | let output_capture = OutputCapture::capture().unwrap(); 49 | main(); 50 | output_capture.test("entity_hooks".to_string()); 51 | } 52 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/entities/mod.rs: -------------------------------------------------------------------------------- 1 | mod entity_basics; 2 | mod entity_hierarchy; 3 | mod entity_hooks; 4 | mod entity_iterate_components; 5 | mod entity_prefab; 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/game_mechanics/mod.rs: -------------------------------------------------------------------------------- 1 | mod inventory_system; 2 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/observers/mod.rs: -------------------------------------------------------------------------------- 1 | mod observer_basics; 2 | mod observer_custom_event; 3 | mod observer_entity_event; 4 | mod observer_monitor; 5 | mod observer_propagate; 6 | mod observer_two_components; 7 | mod observer_yield_existing; 8 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/observers/observer_basics.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | pub struct Position { 7 | pub x: f32, 8 | pub y: f32, 9 | } 10 | 11 | fn main() { 12 | let world = World::new(); 13 | 14 | world 15 | .observer::() 16 | .with(id::()) 17 | .each_iter(|it, index, _| { 18 | // We use .with(id::()) because we cannot safely access the component 19 | // value here. The component value is uninitialized when the OnAdd event 20 | // is emitted, which is UB in Rust. To work around this, we use .with:: 21 | println!( 22 | " - OnAdd: {}: {}", 23 | it.event_id().to_str(), 24 | it.entity(index).unwrap() 25 | ); 26 | }); 27 | 28 | // Create an observer for three events 29 | world 30 | .observer::() 31 | .add_event(id::()) 32 | .each_iter(|it, index, pos| { 33 | println!( 34 | " - {}: {}: {}: with {:?}", 35 | it.event().name(), 36 | it.event_id().to_str(), 37 | it.entity(index).unwrap(), 38 | pos 39 | ); 40 | }); 41 | 42 | // Create entity, set Position (emits EcsOnAdd and EcsOnSet) 43 | let entity = world.entity_named("e1").set(Position { x: 10.0, y: 20.0 }); 44 | 45 | // Remove Position (emits EcsOnRemove) 46 | entity.remove(id::()); 47 | 48 | // Remove Position again (no event emitted) 49 | entity.remove(id::()); 50 | 51 | // Output: 52 | // - OnAdd: Position: e1 53 | // - OnSet: Position: e1: with Position { x: 10.0, y: 20.0 } 54 | // - OnRemove: Position: e1: with Position { x: 10.0, y: 20.0 } 55 | } 56 | 57 | #[cfg(feature = "flecs_nightly_tests")] 58 | #[test] 59 | fn test() { 60 | let output_capture = OutputCapture::capture().unwrap(); 61 | main(); 62 | output_capture.test("observer_basics".to_string()); 63 | } 64 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/observers/observer_custom_event.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | pub struct Position { 7 | pub x: f32, 8 | pub y: f32, 9 | } 10 | 11 | #[derive(Component)] 12 | struct MyEvent; 13 | 14 | fn main() { 15 | let world = World::new(); 16 | 17 | // Create an observer for the custom event 18 | world 19 | .observer::() 20 | .each_iter(|it, index, _pos| { 21 | println!( 22 | " - {}: {}: {}", 23 | it.event().name(), 24 | it.event_id().to_str(), 25 | it.entity(index).unwrap() 26 | ); 27 | }); 28 | 29 | // The observer query can be matched against the entity, so make sure it 30 | // has the Position component before emitting the event. This does not 31 | // trigger the observer yet. 32 | let entity = world.entity_named("e1").set(Position { x: 10.0, y: 20.0 }); 33 | 34 | // Emit the custom event. This triggers the observer. 35 | world 36 | .event() 37 | .add(id::()) 38 | .entity(entity) 39 | .emit(&MyEvent); 40 | 41 | // Output: 42 | // - MyEvent: Position: e1 43 | } 44 | 45 | #[cfg(feature = "flecs_nightly_tests")] 46 | #[test] 47 | fn test() { 48 | let output_capture = OutputCapture::capture().unwrap(); 49 | main(); 50 | output_capture.test("observer_custom_event".to_string()); 51 | } 52 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/observers/observer_monitor.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | pub struct Position { 7 | pub x: f32, 8 | pub y: f32, 9 | } 10 | 11 | #[derive(Debug, Component)] 12 | pub struct Velocity { 13 | pub x: f32, 14 | pub y: f32, 15 | } 16 | 17 | // A monitor observer triggers when an entity starts/stop matching the observer 18 | // query. The observer communicates whether an entity is "entering/leaving" the 19 | // monitor by setting ecs_iter_t::event to EcsOnAdd (for entering) or 20 | // EcsOnRemove (for leaving). 21 | // 22 | // To specify that an observer is a monitor observer, the EcsMonitor tag must be 23 | // provided as event. No additional event kinds should be provided for a monitor 24 | // observer. 25 | 26 | fn main() { 27 | let world = World::new(); 28 | 29 | // Create observer for custom event 30 | world 31 | .observer::() 32 | .each_iter(|it, index, (_pos, _vel)| { 33 | if it.event() == flecs::OnAdd::ID { 34 | println!( 35 | " - Enter: {}: {}", 36 | it.event_id().to_str(), 37 | it.entity(index).unwrap().name() 38 | ); 39 | } else if it.event() == flecs::OnRemove::ID { 40 | println!( 41 | " - Leave: {}: {}", 42 | it.event_id().to_str(), 43 | it.entity(index).unwrap().name() 44 | ); 45 | } 46 | }); 47 | 48 | // Create entity 49 | let entity = world.entity_named("e"); 50 | 51 | // This does not yet trigger the monitor, as the entity does not yet match. 52 | entity.set(Position { x: 10.0, y: 20.0 }); 53 | 54 | // This triggers the monitor with EcsOnAdd, as the entity now matches. 55 | entity.set(Velocity { x: 1.0, y: 2.0 }); 56 | 57 | // This triggers the monitor with EcsOnRemove, as the entity no longer matches. 58 | entity.remove(id::()); 59 | 60 | // Output: 61 | // - Enter: Velocity: e 62 | // - Leave: Position: e 63 | } 64 | 65 | #[cfg(feature = "flecs_nightly_tests")] 66 | #[test] 67 | fn test() { 68 | let output_capture = OutputCapture::capture().unwrap(); 69 | main(); 70 | output_capture.test("observer_monitor".to_string()); 71 | } 72 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/observers/observer_propagate.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | pub struct Position { 7 | pub x: f32, 8 | pub y: f32, 9 | } 10 | 11 | // Events are propagated along relationship edges. This means that observers can 12 | // listen for events from a parent or prefab, like triggering when a component 13 | // inherited from a prefab was set. 14 | // 15 | // Event propagation happens automatically when an observer contains a query 16 | // with the EcsUp flag set (indicating upwards traversal). Observers use the 17 | // same matching logic as queries: if a query with upwards traversal matches an 18 | // entity, so will an observer. 19 | // 20 | // Events are only propagated along traversable relationship edges. 21 | 22 | fn main() { 23 | let world = World::new(); 24 | 25 | // Create observer that listens for events from both self and parent 26 | world 27 | .observer::() 28 | .term_at(1) 29 | .parent() 30 | .each_iter(|it, index, (pos_self, pos_parent)| { 31 | println!( 32 | " - {}: {}: {}: self: {{ {}, {} }}, parent: {{ {}, {} }}", 33 | it.event().name(), 34 | it.event_id().to_str(), 35 | it.entity(index).unwrap().name(), 36 | pos_self.x, 37 | pos_self.y, 38 | pos_parent.x, 39 | pos_parent.y 40 | ); 41 | }); 42 | 43 | // Create entity and parent 44 | let parent = world.entity_named("p"); 45 | let entity = world.entity_named("e").child_of(parent); 46 | 47 | // Set Position on entity. This doesn't trigger the observer yet, since the 48 | // parent doesn't have Position yet. 49 | entity.set(Position { x: 10.0, y: 20.0 }); 50 | 51 | // Set Position on parent. This event will be propagated and trigger the 52 | // observer, as the observer query now matches. 53 | parent.set(Position { x: 1.0, y: 2.0 }); 54 | 55 | // Output: 56 | // - OnSet: Position: e: self: { 10, 20 }, parent: { 1, 2 } 57 | } 58 | 59 | #[cfg(feature = "flecs_nightly_tests")] 60 | #[test] 61 | fn test() { 62 | let output_capture = OutputCapture::capture().unwrap(); 63 | main(); 64 | output_capture.test("observer_propagate".to_string()); 65 | } 66 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/observers/observer_two_components.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | pub struct Position { 7 | pub x: f32, 8 | pub y: f32, 9 | } 10 | 11 | #[derive(Debug, Component)] 12 | pub struct Velocity { 13 | pub x: f32, 14 | pub y: f32, 15 | } 16 | 17 | // An observer can match multiple components/tags. Only entities that match the 18 | // entire observer query will be forwarded to the callback. For example, an 19 | // observer for Position,Velocity won't match an entity that only has Position. 20 | 21 | fn main() { 22 | let world = World::new(); 23 | 24 | // Create observer for custom event 25 | world 26 | .observer::() 27 | .each_iter(|it, index, (pos, vel)| { 28 | println!( 29 | " - {}: {}: {}: p: {{ {}, {} }}, v: {{ {}, {} }}", 30 | it.event().name(), 31 | it.event_id().to_str(), 32 | it.entity(index).unwrap().name(), 33 | pos.x, 34 | pos.y, 35 | vel.x, 36 | vel.y 37 | ); 38 | }); 39 | 40 | // Create entity, set Position (emits EcsOnSet, does not yet match observer) 41 | let entity = world.entity_named("e").set(Position { x: 10.0, y: 20.0 }); 42 | 43 | // Set Velocity (emits EcsOnSet, matches observer) 44 | entity.set(Velocity { x: 1.0, y: 2.0 }); 45 | 46 | // Output: 47 | // - OnSet: Velocity: e: p: { 10, 20 }, v: { 1, 2 } 48 | } 49 | 50 | #[cfg(feature = "flecs_nightly_tests")] 51 | #[test] 52 | fn test() { 53 | let output_capture = OutputCapture::capture().unwrap(); 54 | main(); 55 | output_capture.test("observer_two_components".to_string()); 56 | } 57 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/observers/observer_yield_existing.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | pub struct Position { 7 | pub x: f32, 8 | pub y: f32, 9 | } 10 | 11 | // Observers can enable a "yield_existing" feature that upon creation of the 12 | // observer produces events for all entities that match the observer query. The 13 | // feature is only implemented for the builtin EcsOnAdd and EcsOnSet events. 14 | 15 | fn main() { 16 | let world = World::new(); 17 | 18 | // Create existing entities with Position component 19 | world.entity_named("e1").set(Position { x: 10.0, y: 20.0 }); 20 | world.entity_named("e2").set(Position { x: 20.0, y: 30.0 }); 21 | 22 | // Create an observer for three events 23 | world 24 | .observer::() 25 | .yield_existing() 26 | .each_iter(|it, index, pos| { 27 | println!( 28 | " - {}: {}: {}: {{ {}, {} }}", 29 | it.event().name(), 30 | it.event_id().to_str(), 31 | it.entity(index).unwrap(), 32 | pos.x, 33 | pos.y 34 | ); 35 | }); 36 | 37 | // Output: 38 | // - OnSet: Position: e1: { 10, 20 } 39 | // - OnSet: Position: e2: { 20, 30 } 40 | } 41 | 42 | #[cfg(feature = "flecs_nightly_tests")] 43 | #[test] 44 | fn test() { 45 | let output_capture = OutputCapture::capture().unwrap(); 46 | main(); 47 | output_capture.test("observer_yield_existing".to_string()); 48 | } 49 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/prefabs/mod.rs: -------------------------------------------------------------------------------- 1 | mod prefab_basics; 2 | mod prefab_hierarchy; 3 | mod prefab_nested; 4 | mod prefab_override; 5 | mod prefab_slots; 6 | mod prefab_typed; 7 | mod prefab_variant; 8 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/prefabs/prefab_hierarchy.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | // When a prefab has children, they are instantiated for an instance when the 5 | // IsA relationship to the prefab is added. 6 | 7 | fn main() { 8 | let world = World::new(); 9 | 10 | // Create a prefab hierarchy. 11 | let spaceship = world.prefab_named("SpaceShip"); 12 | world.prefab_named("Engine").child_of(spaceship); 13 | world.prefab_named("Cockpit").child_of(spaceship); 14 | 15 | // Instantiate the prefab. This also creates an Engine and Cockpit child 16 | // for the instance. 17 | let inst = world.entity_named("my_spaceship").is_a(spaceship); 18 | 19 | // Because of the IsA relationship, the instance now has the Engine and Cockpit 20 | // children of the prefab. This means that the instance can look up the Engine 21 | // and Cockpit entities. 22 | if let Some(inst_engine) = inst.try_lookup_recursive("Engine") { 23 | if let Some(inst_cockpit) = inst.try_lookup_recursive("Cockpit") { 24 | println!("instance engine: {:?}", inst_engine.path().unwrap()); 25 | println!("instance cockpit: {:?}", inst_cockpit.path().unwrap()); 26 | } else { 27 | println!("entity lookup failed"); 28 | } 29 | } 30 | 31 | // Output: 32 | // instance engine: "::my_spaceship::Engine" 33 | // instance cockpit: "::my_spaceship::Cockpit" 34 | } 35 | 36 | #[cfg(feature = "flecs_nightly_tests")] 37 | #[test] 38 | fn test() { 39 | let output_capture = OutputCapture::capture().unwrap(); 40 | main(); 41 | output_capture.test("prefab_hierarchy".to_string()); 42 | } 43 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/queries/mod.rs: -------------------------------------------------------------------------------- 1 | mod query_basics; 2 | mod query_chaining_queries; 3 | mod query_change_tracking_1; 4 | mod query_change_tracking_2; 5 | mod query_component_inheritance; 6 | mod query_cyclic_variables; 7 | mod query_facts; 8 | mod query_find_entity; 9 | mod query_group_by; 10 | mod query_group_by_callbacks; 11 | mod query_group_by_custom; 12 | mod query_group_iter; 13 | mod query_hierarchy; 14 | mod query_pass_query_to_system; 15 | mod query_run; 16 | mod query_setting_variables; 17 | mod query_singleton; 18 | mod query_sorting; 19 | mod query_transitive_queries; 20 | mod query_variables; 21 | mod query_wildcard; 22 | mod query_with; 23 | mod query_without; 24 | mod query_world_query; 25 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/queries/query_component_inheritance.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | // This example shows how queries can be used to match simple inheritance trees. 5 | 6 | #[derive(Component)] 7 | struct Unit; 8 | 9 | #[derive(Component)] 10 | struct CombatUnit; 11 | 12 | #[derive(Component)] 13 | struct MeleeUnit; 14 | 15 | #[derive(Component)] 16 | struct RangedUnit; 17 | 18 | #[derive(Component)] 19 | struct Warrior; 20 | 21 | #[derive(Component)] 22 | struct Wizard; 23 | 24 | #[derive(Component)] 25 | struct Marksman; 26 | 27 | #[derive(Component)] 28 | struct BuilderX; 29 | 30 | fn main() { 31 | let world = World::new(); 32 | 33 | // Make the ECS aware of the inheritance relationships. Note that IsA 34 | // relationship used here is the same as in the prefab example. 35 | world.component::().is_a(id::()); 36 | world.component::().is_a(id::()); 37 | world.component::().is_a(id::()); 38 | 39 | world.component::().is_a(id::()); 40 | world.component::().is_a(id::()); 41 | world.component::().is_a(id::()); 42 | world.component::().is_a(id::()); 43 | 44 | // Create a few units 45 | world.entity_named("warrior_1").add(id::()); 46 | world.entity_named("warrior_2").add(id::()); 47 | 48 | world.entity_named("marksman_1").add(id::()); 49 | world.entity_named("marksman_2").add(id::()); 50 | 51 | world.entity_named("wizard_1").add(id::()); 52 | world.entity_named("wizard_2").add(id::()); 53 | 54 | world.entity_named("builder_1").add(id::()); 55 | world.entity_named("builder_2").add(id::()); 56 | 57 | // Create a rule to find all ranged units 58 | let r = world.query::<()>().with(id::()).build(); 59 | 60 | // Iterate the rule 61 | r.each_entity(|e, rangedunit| { 62 | println!("Unit {} found", e.name()); 63 | }); 64 | 65 | // Output: 66 | // Unit wizard_1 found 67 | // Unit wizard_2 found 68 | // Unit marksman_1 found 69 | // Unit marksman_2 found 70 | } 71 | 72 | #[cfg(feature = "flecs_nightly_tests")] 73 | #[test] 74 | fn test() { 75 | let output_capture = OutputCapture::capture().unwrap(); 76 | main(); 77 | output_capture.test("query_component_inheritance".to_string()); 78 | } 79 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/queries/query_find_entity.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | pub struct Position { 7 | pub x: f32, 8 | pub y: f32, 9 | } 10 | 11 | fn main() { 12 | let world = World::new(); 13 | // Create a few test entities for a Position query 14 | world.entity_named("e1").set(Position { x: 10.0, y: 20.0 }); 15 | 16 | world.entity_named("e2").set(Position { x: 20.0, y: 30.0 }); 17 | 18 | // Create a simple query for component Position 19 | let query = world.new_query::<&Position>(); 20 | 21 | let entity: Option = query.find(|pos| (pos.x - 20.0).abs() < f32::EPSILON); 22 | 23 | if let Some(entity) = entity { 24 | println!("Entity found: {:?}", entity.path().unwrap()); 25 | } else { 26 | println!("Entity not found"); 27 | } 28 | 29 | // Output: 30 | // Entity found: "::e2" 31 | } 32 | 33 | #[cfg(feature = "flecs_nightly_tests")] 34 | #[test] 35 | fn test() { 36 | let output_capture = OutputCapture::capture().unwrap(); 37 | main(); 38 | output_capture.test("query_find_entity".to_string()); 39 | } 40 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/queries/query_pass_query_to_system.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component, Default)] 6 | pub struct Position { 7 | pub x: i32, 8 | pub y: i32, 9 | } 10 | 11 | #[derive(Debug, Component, Default)] 12 | pub struct Velocity { 13 | pub x: i32, 14 | pub y: i32, 15 | } 16 | 17 | fn main() { 18 | let world = World::new(); 19 | 20 | world.set(Position { x: 1, y: 2 }); 21 | 22 | let query = world 23 | .query::<(&Position, &Velocity)>() 24 | .term_at(0) 25 | .singleton() 26 | // setting it cached is important! otherwise the query will go out of scope since it's not associated with an entity 27 | // uncached queries are meant to be shortlived, but faster to create in general. More dynamic in nature. 28 | .set_cached() 29 | .build(); 30 | 31 | world.entity().set(Velocity { x: 590, y: 20 }); 32 | 33 | // by using move, we can pass the query directly to the system because queries 34 | // do not hold a lifetime, instead they are reference counted to give us the ability to pass them around. 35 | let sys = world.system::<()>().run(move |it| { 36 | let world = it.world(); 37 | query.run(|mut it| { 38 | while it.next() { 39 | let pos = &it.field::<&Position>(0).unwrap()[0]; //singleton 40 | let vel = it.field::<&Velocity>(1).unwrap(); 41 | for i in it.iter() { 42 | println!("{:?}, {:?}", pos, vel[i]); 43 | } 44 | } 45 | }); 46 | }); 47 | 48 | sys.run(); 49 | 50 | // Output: 51 | // Position { x: 1.0, y: 2.0 }, Velocity { x: 590.0, y: 20.0 } 52 | } 53 | 54 | #[cfg(feature = "flecs_nightly_tests")] 55 | #[test] 56 | fn test() { 57 | let output_capture = OutputCapture::capture().unwrap(); 58 | main(); 59 | output_capture.test("query_pass_query_to_system".to_string()); 60 | } 61 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/queries/query_singleton.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | #[derive(Debug, Component)] 5 | struct Gravity { 6 | value: f32, 7 | } 8 | 9 | #[derive(Debug, Component)] 10 | pub struct Velocity { 11 | pub x: f32, 12 | pub y: f32, 13 | } 14 | 15 | fn main() { 16 | let world = World::new(); 17 | 18 | // Set singleton 19 | world.set(Gravity { value: 9.81 }); 20 | 21 | // Set Velocity 22 | world.entity_named("e1").set(Velocity { x: 0.0, y: 0.0 }); 23 | world.entity_named("e2").set(Velocity { x: 0.0, y: 1.0 }); 24 | world.entity_named("e3").set(Velocity { x: 0.0, y: 2.0 }); 25 | 26 | // Create query that matches Gravity as singleton 27 | let query = world 28 | .query::<(&mut Velocity, &Gravity)>() 29 | .term_at(1) 30 | .singleton() 31 | .build(); 32 | 33 | // In a query string expression you can use the $ shortcut for singletons: 34 | // Velocity, Gravity($) 35 | 36 | query.each_entity(|entity, (velocity, gravity)| { 37 | velocity.y += gravity.value; 38 | println!("Entity {} has {:?}", entity.path().unwrap(), velocity); 39 | }); 40 | 41 | // Output: 42 | // Entity ::e1 has Velocity { x: 0.0, y: 9.81 } 43 | // Entity ::e2 has Velocity { x: 0.0, y: 10.81 } 44 | // Entity ::e3 has Velocity { x: 0.0, y: 11.81 } 45 | } 46 | 47 | #[cfg(feature = "flecs_nightly_tests")] 48 | #[test] 49 | fn test() { 50 | let output_capture = OutputCapture::capture().unwrap(); 51 | main(); 52 | output_capture.test("query_singleton".to_string()); 53 | } 54 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/queries/query_wildcard.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | pub use flecs_ecs::{core::*, macros::Component}; 5 | 6 | #[derive(Component)] 7 | pub struct EatsAmount { 8 | pub amount: i32, 9 | } 10 | 11 | #[derive(Component)] 12 | pub struct Apples; 13 | 14 | #[derive(Component)] 15 | pub struct Pears; 16 | 17 | fn main() { 18 | let world = World::new(); 19 | 20 | // Create a query that matches edible components 21 | let query = world.new_query::<&(EatsAmount, flecs::Wildcard)>(); 22 | 23 | // Create a few entities that match the query 24 | world 25 | .entity_named("Bob") 26 | .set_pair::(EatsAmount { amount: 10 }) 27 | .set_pair::(EatsAmount { amount: 5 }); 28 | 29 | world 30 | .entity_named("Alice") 31 | .set_pair::(EatsAmount { amount: 4 }); 32 | 33 | // Iterate the query with a flecs::iter. This makes it possible to inspect 34 | // the pair that we are currently matched with. 35 | query.each_iter(|it, index, eats| { 36 | let entity = it.entity(index).unwrap(); 37 | let pair = it.pair(0).unwrap(); 38 | let food = pair.second_id(); 39 | 40 | println!("{} eats {} {}", entity, eats.amount, food); 41 | }); 42 | 43 | // Output: 44 | // Alice eats 4 Apples 45 | // Bob eats 10 Apples 46 | // Bob eats 5 Pears 47 | } 48 | 49 | #[cfg(feature = "flecs_nightly_tests")] 50 | #[test] 51 | fn test() { 52 | let output_capture = OutputCapture::capture().unwrap(); 53 | main(); 54 | output_capture.test("query_wildcard".to_string()); 55 | } 56 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/queries/query_with.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | pub struct Position { 7 | pub x: f32, 8 | pub y: f32, 9 | } 10 | 11 | #[derive(Component)] 12 | struct Npc; 13 | 14 | fn main() { 15 | let world = World::new(); 16 | 17 | // Create a query for Position, Npc. By adding the Npc component using the 18 | // "with" method, the component is not a part of the query type, and as a 19 | // result does not become part of the function signatures of each and iter. 20 | // This is useful for things like tags, which because they don't have a 21 | // value are less useful to pass to the each/iter functions as argument. 22 | let query = world.query::<&Position>().with(id::<&Npc>()).build(); 23 | 24 | // Create a few test entities for the Position, Npc query 25 | world 26 | .entity_named("e1") 27 | .set(Position { x: 10.0, y: 20.0 }) 28 | .add(id::()); 29 | 30 | world 31 | .entity_named("e2") 32 | .set(Position { x: 10.0, y: 20.0 }) 33 | .add(id::()); 34 | 35 | // This entity will not match as it does not have Position, Npc 36 | world.entity_named("e3").set(Position { x: 10.0, y: 20.0 }); 37 | 38 | // Note how the Npc tag is not part of the each signature 39 | query.each_entity(|entity, pos| { 40 | println!("Entity {}: {:?}", entity.name(), pos); 41 | }); 42 | 43 | // Output: 44 | // Entity e1: Position { x: 10.0, y: 20.0 } 45 | // Entity e2: Position { x: 10.0, y: 20.0 } 46 | } 47 | 48 | #[cfg(feature = "flecs_nightly_tests")] 49 | #[test] 50 | fn test() { 51 | let output_capture = OutputCapture::capture().unwrap(); 52 | main(); 53 | output_capture.test("query_with".to_string()); 54 | } 55 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/queries/query_without.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | pub struct Position { 7 | pub x: f32, 8 | pub y: f32, 9 | } 10 | 11 | #[derive(Component)] 12 | struct Npc; 13 | 14 | fn main() { 15 | let world = World::new(); 16 | 17 | // Create a query for Position, !Npc. By adding the Npc component using the 18 | // "without" method, the component is not a part of the query type, and as a 19 | // result does not become part of the function signatures of each and iter. 20 | // This is useful for things like tags, which because they don't have a 21 | // value are less useful to pass to the each/iter functions as argument. 22 | // 23 | // The without method is short for: 24 | // .term().not_() 25 | let query = world.query::<&Position>().without(id::()).build(); 26 | 27 | // Create a few test entities for the Position query 28 | world.entity_named("e1").set(Position { x: 10.0, y: 20.0 }); 29 | 30 | world.entity_named("e2").set(Position { x: 10.0, y: 20.0 }); 31 | 32 | // This entity will not match as it has Npc 33 | world 34 | .entity_named("e3") 35 | .set(Position { x: 10.0, y: 20.0 }) 36 | .add(id::()); 37 | 38 | // Note how the Npc tag is not part of the each signature 39 | query.each_entity(|entity, pos| { 40 | println!("Entity {}: {:?}", entity.name(), pos); 41 | }); 42 | 43 | // Output: 44 | // Entity e1: Position { x: 10.0, y: 20.0 } 45 | // Entity e2: Position { x: 10.0, y: 20.0 } 46 | } 47 | 48 | #[cfg(feature = "flecs_nightly_tests")] 49 | #[test] 50 | fn test() { 51 | let output_capture = OutputCapture::capture().unwrap(); 52 | main(); 53 | output_capture.test("query_without".to_string()); 54 | } 55 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/queries/query_world_query.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | pub struct Position { 7 | pub x: f32, 8 | pub y: f32, 9 | } 10 | 11 | #[derive(Debug, Component)] 12 | pub struct Velocity { 13 | pub x: f32, 14 | pub y: f32, 15 | } 16 | 17 | fn main() { 18 | let world = World::new(); 19 | 20 | // Create a few test entities for a Position, Velocity query 21 | world 22 | .entity_named("e1") 23 | .set(Position { x: 10.0, y: 20.0 }) 24 | .set(Velocity { x: 1.0, y: 2.0 }); 25 | 26 | world 27 | .entity_named("e2") 28 | .set(Position { x: 10.0, y: 20.0 }) 29 | .set(Velocity { x: 3.0, y: 4.0 }); 30 | 31 | // This entity will not match as it does not have Position, Velocity 32 | world.entity_named("e3").set(Position { x: 10.0, y: 20.0 }); 33 | 34 | // Ad hoc queries are bit slower to iterate than flecs::query, but are 35 | // faster to create, and in most cases require no allocations. Under the 36 | // hood this API uses flecs::query, which can be used directly for more 37 | // complex queries. 38 | 39 | world.each_entity::<(&mut Position, &Velocity)>(|entity, (pos, vel)| { 40 | pos.x += vel.x; 41 | pos.y += vel.y; 42 | println!("Entity {}: {:?}", entity.name(), pos); 43 | }); 44 | 45 | // Output: 46 | // Entity e1: Position { x: 11.0, y: 22.0 } 47 | // Entity e2: Position { x: 13.0, y: 24.0 } 48 | } 49 | 50 | #[cfg(feature = "flecs_nightly_tests")] 51 | #[test] 52 | fn test() { 53 | let output_capture = OutputCapture::capture().unwrap(); 54 | main(); 55 | output_capture.test("query_world_query".to_string()); 56 | } 57 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/entity_type.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Component)] 6 | #[meta] 7 | pub struct TypeWithEntity { 8 | pub e: Entity, 9 | } 10 | 11 | fn main() { 12 | let mut world = World::new(); 13 | 14 | // Using Entity directly would resolve to a u64 datatype, so 15 | // use flecs::meta::Entity instead. 16 | world.component::().meta(); 17 | 18 | /* Alternatively, you can do it manually like so (without the derive macro) 19 | .member(id::(),"e", 1, core::mem::offset_of!(TypeWithEntity, e)); 20 | */ 21 | 22 | let bar = world.entity_named("bar"); 23 | 24 | // Create a new entity with the TypeWithEntity component 25 | let e = world.entity().set(TypeWithEntity { e: bar.into() }); 26 | 27 | // Convert TypeWithEntity component to flecs expression string 28 | e.get::<&TypeWithEntity>(|p| { 29 | let expr: String = world.to_expr(p); 30 | println!("TypeWithEntity: {}", expr); 31 | }); 32 | 33 | // Output: 34 | // TypeWithEntity: {e: foo} 35 | } 36 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/member_ranges.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Component)] 6 | #[meta] 7 | pub struct CpuUtilization { 8 | pub value: f64, 9 | } 10 | 11 | fn main() { 12 | let mut world = World::new(); 13 | 14 | world 15 | .component::() 16 | .meta() 17 | .range(0.0, 100.0) // Specifics values that the member can assume 18 | .warning_range(0.0, 60.0) // Values outside this range are considered a warning 19 | .error_range(0.0, 80.0); // Values outside this range are considered an error 20 | 21 | world 22 | .entity_named("MachineA") 23 | .set(CpuUtilization { value: 50.0 }); 24 | world 25 | .entity_named("MachineB") 26 | .set(CpuUtilization { value: 75.0 }); 27 | world 28 | .entity_named("MachineC") 29 | .set(CpuUtilization { value: 90.0 }); 30 | 31 | // Uncomment this line and open 32 | // https://www.flecs.dev/explorer?show=query&query=CpuUtilization 33 | // to see how ranges affect visualization: 34 | // world.app().enable_rest(0).run(); 35 | } 36 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/mod.rs: -------------------------------------------------------------------------------- 1 | mod entity_type; 2 | mod member_ranges; 3 | mod reflection_basics; 4 | mod reflection_basics_bitmask; 5 | mod reflection_basics_deserialize; 6 | mod reflection_basics_json; 7 | mod reflection_basics_simple_enum; 8 | mod reflection_nested_set_member; 9 | mod reflection_nested_struct; 10 | mod reflection_query_to_custom_json; 11 | mod reflection_query_to_json; 12 | mod reflection_runtime_component; 13 | mod reflection_runtime_nested_component; 14 | mod reflection_ser_opaque_type; 15 | mod reflection_ser_std_string; 16 | mod reflection_ser_std_vector_builtin_types; 17 | mod reflection_ser_std_vector_custom_types; 18 | 19 | mod reflection_world_ser_deser; 20 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/reflection_basics.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | #[meta] 7 | pub struct Position { 8 | pub x: f32, 9 | pub y: f32, 10 | } 11 | 12 | fn main() { 13 | let mut world = World::new(); 14 | 15 | // Register the Position component 16 | world.component::().meta(); 17 | 18 | /* Alternatively, you can do it manually like so (without the derive macro) 19 | .member(id::(),"x", 1 /* count */, core::mem::offset_of!(Position, x)) 20 | .member(id::(),"y", 1, core::mem::offset_of!(Position, y)); 21 | */ 22 | 23 | // Create a new entity 24 | let e = world.entity().set(Position { x: 2.0, y: 4.0 }); 25 | 26 | // Convert position component to flecs expression string 27 | e.get::<&Position>(|p| { 28 | let expr: String = world.to_expr(p); 29 | println!("Position: {}", expr); 30 | }); 31 | 32 | // Output: 33 | // Position: {x: 2, y: 4} 34 | } 35 | 36 | #[cfg(feature = "flecs_nightly_tests")] 37 | #[test] 38 | fn test() { 39 | let output_capture = OutputCapture::capture().unwrap(); 40 | main(); 41 | output_capture.test("reflection_basics".to_string()); 42 | } 43 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/reflection_basics_bitmask.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Component)] 6 | struct Toppings { 7 | value: u32, 8 | } 9 | 10 | impl Toppings { 11 | const BACON: u32 = 0x1; 12 | const LETTUCE: u32 = 0x2; 13 | const TOMATO: u32 = 0x4; 14 | 15 | fn new() -> Self { 16 | Toppings { value: 0 } 17 | } 18 | 19 | fn add(&mut self, topping: u32) { 20 | self.value |= topping; 21 | } 22 | 23 | fn remove(&mut self, topping: u32) { 24 | self.value &= !topping; 25 | } 26 | 27 | fn has(&self, topping: u32) -> bool { 28 | self.value & topping != 0 29 | } 30 | } 31 | 32 | #[derive(Component)] 33 | struct Sandwich { 34 | toppings: Toppings, 35 | } 36 | 37 | impl Sandwich { 38 | fn new() -> Self { 39 | Sandwich { 40 | toppings: Toppings::new(), 41 | } 42 | } 43 | 44 | fn add_topping(&mut self, topping: u32) { 45 | self.toppings.add(topping); 46 | } 47 | 48 | fn remove_topping(&mut self, topping: u32) { 49 | self.toppings.remove(topping); 50 | } 51 | 52 | fn has_topping(&self, topping: u32) -> bool { 53 | self.toppings.has(topping) 54 | } 55 | } 56 | 57 | fn main() { 58 | let world = World::new(); 59 | 60 | world 61 | .component::() 62 | .bit("bacon", Toppings::BACON) 63 | .bit("lettuce", Toppings::LETTUCE) 64 | .bit("tomato", Toppings::TOMATO); 65 | 66 | world 67 | .component::() 68 | .member(id::(), "toppings"); 69 | 70 | // Create entity with Sandwich 71 | let e = world.entity().set(Sandwich { 72 | toppings: Toppings { 73 | value: Toppings::BACON | Toppings::LETTUCE, 74 | }, 75 | }); 76 | 77 | // Convert Sandwidth component to flecs expression string 78 | e.get::<&Sandwich>(|val| { 79 | println!("{}", world.to_expr(val)); 80 | }); 81 | 82 | // Output: 83 | // {toppings: lettuce|bacon} 84 | } 85 | 86 | #[cfg(feature = "flecs_nightly_tests")] 87 | #[test] 88 | fn test() { 89 | let output_capture = OutputCapture::capture().unwrap(); 90 | main(); 91 | output_capture.test("reflection_bitmask".to_string()); 92 | } 93 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/reflection_basics_deserialize.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Default, Component)] 6 | #[meta] 7 | pub struct Position { 8 | pub x: f32, 9 | pub y: f32, 10 | } 11 | 12 | fn main() { 13 | let world = World::new(); 14 | 15 | // Register the Position component with reflection data 16 | world.component::().meta(); 17 | 18 | /* Alternatively, you can do it manually like so (without the derive macro) 19 | .member(id::(),"x", 1 /* count */, core::mem::offset_of!(Position, x)) 20 | .member(id::(),"y", 1, core::mem::offset_of!(Position, y)); 21 | */ 22 | 23 | // Create a new entity, set value of position using reflection API 24 | let e = world.entity().add(id::()); 25 | 26 | e.get::<&mut Position>(|pos| { 27 | let mut cur = world.cursor::(pos); 28 | cur.push(); // { 29 | cur.set_float(10.0); // 10 30 | cur.next(); // , 31 | cur.set_float(20.0); // 20 32 | cur.pop(); // } 33 | 34 | println!("{}", world.to_expr(pos)); 35 | }); 36 | 37 | // Use member names before assigning values 38 | e.get::<&mut Position>(|pos| { 39 | let mut cur = world.cursor::(pos); 40 | cur.push(); // { 41 | cur.member("y"); // y: 42 | cur.set_float(10.0); // 10 43 | cur.member("x"); // x: 44 | cur.set_float(20.0); // 20 45 | cur.pop(); // } 46 | 47 | println!("{}", world.to_expr(pos)); 48 | }); 49 | 50 | // Output: 51 | // {x: 10, y: 20} 52 | // {x: 20, y: 10} 53 | } 54 | 55 | #[cfg(feature = "flecs_nightly_tests")] 56 | #[test] 57 | fn test() { 58 | let output_capture = OutputCapture::capture().unwrap(); 59 | main(); 60 | output_capture.test("reflection_deserialize".to_string()); 61 | } 62 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/reflection_basics_json.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | #[meta] 7 | pub struct Position { 8 | pub x: f32, 9 | pub y: f32, 10 | } 11 | 12 | fn main() { 13 | let mut world = World::new(); 14 | 15 | // Register the Position component with reflection data 16 | world.component::().meta(); 17 | 18 | /* Alternatively, you can do it manually like so (without the derive macro) 19 | .member(id::(),"x", 1 /* count */, core::mem::offset_of!(Position, x)) 20 | .member(id::(),"y", 1, core::mem::offset_of!(Position, y)); 21 | */ 22 | 23 | // Create a new entity with the Position component 24 | let e = world.entity().set(Position { x: 2.0, y: 4.0 }); 25 | 26 | // Convert position component to JSON string 27 | e.get::<&Position>(|p| { 28 | let expr: String = world.to_json::(p); 29 | println!("Position: {}", expr); 30 | }); 31 | 32 | // Output: 33 | // Position: {x: 2, y: 4} 34 | 35 | // Convert entity to JSON string 36 | println!("Entity: {}", e.to_json(None)); 37 | 38 | // Output: 39 | // Entity: {"name":"#547", "components":{"Position":{"x":2, "y":4}}} 40 | } 41 | 42 | #[cfg(feature = "flecs_nightly_tests")] 43 | #[test] 44 | fn test() { 45 | let output_capture = OutputCapture::capture().unwrap(); 46 | main(); 47 | output_capture.test("reflection_basics_json".to_string()); 48 | } 49 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/reflection_basics_simple_enum.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | #[repr(C)] 7 | #[meta] 8 | pub enum Color { 9 | Red, 10 | Green, 11 | Blue, 12 | } 13 | 14 | #[derive(Debug, Component)] 15 | #[meta] 16 | pub struct TypeWithEnum { 17 | pub color: Color, 18 | } 19 | 20 | fn main() { 21 | let mut world = World::new(); 22 | 23 | // Register the Color component 24 | world.component::().meta(); 25 | /* Alternatively, you can do it manually like so (without the derive macro) 26 | .constant("Red", Color::Red as i32) 27 | .constant("Green", Color::Green as i32) 28 | .constant("Blue", Color::Blue as i32); 29 | */ 30 | 31 | // Register the TypeWithEnum component 32 | world.component::().meta(); 33 | 34 | /* Alternatively, you can do it manually like so (without the derive macro) 35 | .member(id::(),"color", 1, core::mem::offset_of!(TypeWithEnum, color)); 36 | */ 37 | 38 | // Create a new entity 39 | let e = world.entity().set(TypeWithEnum { 40 | color: Color::Green, 41 | }); 42 | 43 | // Convert TypeWithEnum component to flecs expression string 44 | e.get::<&TypeWithEnum>(|p| { 45 | let expr: String = world.to_expr(p); 46 | println!("TypeWithEnum: {}", expr); 47 | }); 48 | 49 | // Output: 50 | // TypeWithEnum: {color: Green} 51 | } 52 | 53 | #[cfg(feature = "flecs_nightly_tests")] 54 | #[test] 55 | fn test() { 56 | let output_capture = OutputCapture::capture().unwrap(); 57 | main(); 58 | output_capture.test("reflection_basics_simple_enum".to_string()); 59 | } 60 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/reflection_nested_set_member.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Default, Component)] 6 | #[meta] 7 | pub struct Point { 8 | pub x: f32, 9 | pub y: f32, 10 | } 11 | 12 | #[derive(Default, Component)] 13 | #[meta] 14 | pub struct Line { 15 | pub start: Point, 16 | pub stop: Point, 17 | } 18 | 19 | fn main() { 20 | let world = World::new(); 21 | 22 | world.component::().meta(); 23 | 24 | world.component::().meta(); 25 | 26 | // Create entity, set value of Line using reflection API 27 | let e = world.entity().add(id::()); 28 | 29 | e.get::<&mut Line>(|line| { 30 | let mut cur = world.cursor(line); 31 | 32 | cur.push(); // { 33 | cur.member("start"); // start: 34 | cur.push(); // { 35 | cur.member("x"); // x: 36 | cur.set_float(10.0); // 10 37 | cur.member("y"); // y: 38 | cur.set_float(20.0); // 20 39 | cur.pop(); // } 40 | cur.member("stop"); // stop: 41 | cur.push(); // { 42 | cur.member("x"); // x: 43 | cur.set_float(30.0); // 30 44 | cur.member("y"); // y: 45 | cur.set_float(40.0); // 40 46 | cur.pop(); // } 47 | cur.pop(); // } 48 | 49 | // Convert component to string 50 | println!("{}", world.to_expr(line)); 51 | }); 52 | 53 | // Output: 54 | // {start: {x: 10, y: 20}, stop: {x: 30, y: 40}} 55 | } 56 | 57 | #[cfg(feature = "flecs_nightly_tests")] 58 | #[test] 59 | fn test() { 60 | let output_capture = OutputCapture::capture().unwrap(); 61 | main(); 62 | output_capture.test("reflection_nested_set_member".to_string()); 63 | } 64 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/reflection_nested_struct.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Default, Component)] 6 | #[meta] 7 | pub struct Point { 8 | pub x: f32, 9 | pub y: f32, 10 | } 11 | 12 | #[derive(Default, Component)] 13 | #[meta] 14 | pub struct Line { 15 | pub start: Point, 16 | pub stop: Point, 17 | } 18 | 19 | fn main() { 20 | let world = World::new(); 21 | 22 | world.component::().meta(); 23 | world.component::().meta(); 24 | 25 | // Create entity, set Line component 26 | let e = world.entity().set(Line { 27 | start: Point { x: 10.0, y: 20.0 }, 28 | stop: Point { x: 30.0, y: 40.0 }, 29 | }); 30 | 31 | // Convert Line component to flecs expression string 32 | e.get::<&mut Line>(|line| { 33 | // Convert component to string 34 | println!("{}", world.to_expr(line)); 35 | }); 36 | 37 | // Output: 38 | // {start: {x: 10, y: 20}, stop: {x: 30, y: 40}} 39 | } 40 | 41 | #[cfg(feature = "flecs_nightly_tests")] 42 | #[test] 43 | fn test() { 44 | let output_capture = OutputCapture::capture().unwrap(); 45 | main(); 46 | output_capture.test("reflection_nested_struct".to_string()); 47 | } 48 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/reflection_runtime_component.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | fn main() { 6 | let world = World::new(); 7 | 8 | let position = world 9 | .component_untyped_named("Position") 10 | .member(id::(), "x") 11 | .member(id::(), "y"); 12 | 13 | // Create entity 14 | let e = world.entity(); 15 | 16 | // unchecked add id due to position being uninitialized and not having a ctor. 17 | unsafe { 18 | e.add_id_unchecked(position); 19 | } 20 | 21 | // set value of position using reflection API 22 | let ptr = e.get_untyped_mut(position); 23 | 24 | let mut cur = world.cursor_id(position, ptr); 25 | cur.push(); 26 | cur.set_float(10.0); 27 | cur.next(); 28 | cur.set_float(20.0); 29 | cur.pop(); 30 | 31 | // Convert component to string 32 | println!("{:?}", world.to_expr_id(position, ptr)); 33 | 34 | // Output 35 | // {x: 10, y: 20} 36 | } 37 | 38 | #[cfg(feature = "flecs_nightly_tests")] 39 | #[test] 40 | fn test() { 41 | let output_capture = OutputCapture::capture().unwrap(); 42 | main(); 43 | output_capture.test("reflection_runtime_component".to_string()); 44 | } 45 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/reflection_runtime_nested_component.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | fn main() { 6 | let world = World::new(); 7 | 8 | let point = world 9 | .component_untyped_named("Point") 10 | .member(id::(), "x") 11 | .member(id::(), "y"); 12 | 13 | let line = world 14 | .component_untyped_named("Line") 15 | .member(point, "start") 16 | .member(point, "stop"); 17 | 18 | // Create entity, set value of line using reflection API 19 | let e = world.entity().add(line); 20 | 21 | let ptr = e.get_untyped_mut(line); 22 | 23 | let mut cur = world.cursor_id(line, ptr); 24 | 25 | #[rustfmt::skip] 26 | fn cursor(cur: &mut Cursor) { 27 | cur.push(); // { 28 | cur.push(); // { 29 | cur.set_float(10.0); // 10 30 | cur.next(); // , 31 | cur.set_float(20.0); // 20 32 | cur.pop(); // } 33 | cur.next(); // , 34 | cur.push(); // { 35 | cur.set_float(30.0); // 30 36 | cur.next(); // , 37 | cur.set_float(40.0); // 40 38 | cur.pop(); // } 39 | cur.pop(); // } 40 | } 41 | 42 | // we use a function to format skip the comments for better understanding. 43 | // in normal cases, you can just write the code directly. 44 | cursor(&mut cur); 45 | 46 | // Convert component to string 47 | println!("{:?}", world.to_expr_id(line, ptr)); 48 | 49 | // Output 50 | // {start: {x: 10.00, y: 20.00}, stop: {x: 30.00, y: 40.00}} 51 | } 52 | 53 | #[cfg(feature = "flecs_nightly_tests")] 54 | #[test] 55 | fn test() { 56 | let output_capture = OutputCapture::capture().unwrap(); 57 | main(); 58 | output_capture.test("reflection_runtime_nested_component".to_string()); 59 | } 60 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/reflection_ser_opaque_type.rs: -------------------------------------------------------------------------------- 1 | use core::ffi::c_char; 2 | 3 | use crate::z_ignore_test_common::*; 4 | 5 | use flecs_ecs::prelude::*; 6 | 7 | // Use opaque reflection support to add a computed 'result' member to type 8 | #[derive(Component)] 9 | struct Sum { 10 | a: i32, 11 | b: i32, 12 | } 13 | 14 | fn main() { 15 | let world = World::new(); 16 | 17 | // Register serialization support for opaque type 18 | world 19 | .component::() 20 | // Serialize as struct 21 | .opaque_id( 22 | world 23 | .component_untyped() 24 | .member(id::(), "a") 25 | .member(id::(), "b") 26 | .member(id::(), "result"), 27 | ) 28 | // Forward struct members to serializer 29 | .serialize(|s: &Serializer, data: &Sum| { 30 | s.member("a"); 31 | s.value(&data.a); 32 | s.member("b"); 33 | s.value(&data.b); 34 | 35 | s.member("result"); 36 | s.value(&(data.a + data.b)); // Serialize fake member 37 | 0 38 | }) 39 | // Return address for requested member 40 | .ensure_member(|dst: &mut Sum, member: *const c_char| { 41 | let member = unsafe { core::ffi::CStr::from_ptr(member) }; 42 | if member != c"a" { 43 | &mut dst.a as *mut i32 as *mut core::ffi::c_void 44 | } else if member != c"b" { 45 | &mut dst.b as *mut i32 as *mut core::ffi::c_void 46 | } else { 47 | core::ptr::null_mut() // We can't serialize into fake result member 48 | } 49 | }); 50 | 51 | // Serialize value of Sum to JSON 52 | let mut v = Sum { a: 10, b: 20 }; 53 | println!("{:?}", world.to_json::(&v)); 54 | 55 | // Deserialize new value into Sum 56 | world.from_json::(&mut v, "{\"a\": 20, \"b\": 22}", None); 57 | 58 | // Serialize value again 59 | println!("{:?}", world.to_json::(&v)); 60 | 61 | // Output 62 | // {"a":10, "b":20, "result":30} 63 | // {"a":22, "b":20, "result":42} 64 | } 65 | 66 | #[cfg(feature = "flecs_nightly_tests")] 67 | #[test] 68 | fn test() { 69 | let output_capture = OutputCapture::capture().unwrap(); 70 | main(); 71 | output_capture.test("reflection_ser_opaque_type".to_string()); 72 | } 73 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/reflection_ser_std_string.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | // This example shows how to serialize a component with an std::string 6 | 7 | // std::String is already registered in the Rust Meta framework (unlike in CPP) 8 | // in case you wish to see how, find it in `src/addons/meta/builtin.rs` 9 | // thus serializing components with String is already supported out of the box 10 | 11 | #[derive(Component, Debug)] 12 | #[meta] 13 | struct StringComponent { 14 | a: String, 15 | b: String, 16 | } 17 | 18 | fn main() { 19 | let world = World::new(); 20 | 21 | // Register component with std::string members 22 | world.component::().meta(); 23 | 24 | // Create value & serialize it 25 | let mut v = StringComponent { 26 | a: "foo".to_string(), 27 | b: "bar".to_string(), 28 | }; 29 | 30 | println!("{:?}", world.to_json::(&v)); 31 | 32 | // Deserialize new strings into value 33 | world.from_json::(&mut v, "{\"a\": \"hello\", \"b\": \"world\"}", None); 34 | println!("{:?}", v); 35 | 36 | // Output: 37 | // {"a": "foo", "b": "bar"} 38 | // {a: "hello", b: "world"} 39 | } 40 | 41 | #[cfg(feature = "flecs_nightly_tests")] 42 | #[test] 43 | fn test() { 44 | let output_capture = OutputCapture::capture().unwrap(); 45 | main(); 46 | output_capture.test("reflection_ser_std_string".to_string()); 47 | } 48 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/reflection_ser_std_vector_builtin_types.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | // This example shows how to serialize a component with std::vectors 6 | 7 | // Flecs Rust Meta framework pre-registers vector types of primitives. 8 | // see `src/addons/meta/builtin.rs` for more information on what types exactly. 9 | 10 | #[derive(Component, Debug)] 11 | #[meta] 12 | struct VectorComponent { 13 | ints: Vec, 14 | strings: Vec, 15 | } 16 | 17 | fn main() { 18 | let world = World::new(); 19 | 20 | // Register component with std::vector members 21 | world.component::().meta(); 22 | 23 | // Create value & serialize it to JSON 24 | let mut v = VectorComponent { 25 | ints: vec![1, 2, 3], 26 | strings: vec!["foo".to_string(), "bar".to_string()], 27 | }; 28 | 29 | println!("{:?}", world.to_json::(&v)); 30 | 31 | // Deserialize new values from JSON into value 32 | world.from_json::( 33 | &mut v, 34 | "{\"ints\": [4, 5], \"strings\":[\"hello\", \"flecs\", \"reflection\"]}", 35 | None, 36 | ); 37 | 38 | // Serialize again 39 | println!("{:?}", world.to_json::(&v)); 40 | 41 | // Output: 42 | // {"ints":[1, 2, 3], "strings":["foo", "bar"]} 43 | // {"ints":[4, 5], "strings":["hello", "flecs", "reflection"]} 44 | } 45 | 46 | #[cfg(feature = "flecs_nightly_tests")] 47 | #[test] 48 | fn test() { 49 | let output_capture = OutputCapture::capture().unwrap(); 50 | main(); 51 | output_capture.test("reflection_ser_std_vector_builtin_types".to_string()); 52 | } 53 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/reflection/reflection_ser_std_vector_custom_types.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | // This example shows how to serialize a component with std::vectors 6 | 7 | // Flecs Rust Meta framework pre-registers vector types of primitives. 8 | // see `src/addons/meta/builtin.rs` for more information on what types exactly. 9 | 10 | #[derive(Component, Debug)] 11 | #[meta] 12 | struct Point { 13 | x: f32, 14 | y: f32, 15 | } 16 | 17 | #[derive(Component, Debug)] 18 | #[meta] 19 | struct VectorComponent { 20 | points: Vec, 21 | strings: Vec, 22 | } 23 | 24 | fn main() { 25 | let world = World::new(); 26 | 27 | //register point component with meta 28 | world.component::().meta(); 29 | 30 | // String and vec are already pre-registered by the meta framework 31 | 32 | // register vec component with meta 33 | // we have to pass a default value for the Point struct that 34 | // will be used to create new elements in the vector 35 | meta_register_vector_type!(&world, Point { x: 0.0, y: 0.0 }); 36 | 37 | // Register component with std::vector members 38 | world.component::().meta(); 39 | 40 | // Create value & serialize it to JSON 41 | let mut v = VectorComponent { 42 | points: vec![Point { x: 1.0, y: 2.0 }, Point { x: 3.0, y: 4.0 }], 43 | strings: vec!["foo".to_string(), "bar".to_string()], 44 | }; 45 | 46 | println!("{:?}", world.to_json::(&v)); 47 | 48 | // Deserialize new values from JSON into value 49 | world.from_json::( 50 | &mut v, 51 | "{\"points\": [{\"x\": 4.0, \"y\": 5.0}, {\"x\": 6.0, \"y\": 7.0}], \"strings\":[\"hello\", \"flecs\", \"reflection\"]}", 52 | None, 53 | ); 54 | 55 | // Serialize again 56 | println!("{:?}", world.to_json::(&v)); 57 | 58 | // Output: 59 | // "{"points":[{"x":1, "y":2}, {"x":3, "y":4}], "strings":["foo", "bar"]}" 60 | // "{"points":[{"x":4, "y":5}, {"x":6, "y":7}, {"x":0, "y":0}], "strings":["hello", "flecs", "reflection", ""]}" 61 | } 62 | 63 | #[cfg(feature = "flecs_nightly_tests")] 64 | #[test] 65 | fn test() { 66 | let output_capture = OutputCapture::capture().unwrap(); 67 | main(); 68 | output_capture.test("reflection_ser_std_vector_custom_types".to_string()); 69 | } 70 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/relationships/mod.rs: -------------------------------------------------------------------------------- 1 | mod relationships_basics; 2 | mod relationships_component_data; 3 | mod relationships_enum; 4 | mod relationships_exclusive; 5 | mod relationships_symmetric; 6 | mod relationships_union; 7 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/relationships/relationships_exclusive.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | // Type for Platoon relationship 5 | #[derive(Component)] 6 | struct Platoon; 7 | 8 | fn main() { 9 | let world = World::new(); 10 | 11 | // Register Platoon as exclusive relationship. This ensures that an entity 12 | // can only belong to a single Platoon. 13 | world.component::().add(id::()); 14 | 15 | // Create two platoons 16 | let platoon_1 = world.entity(); 17 | let platoon_2 = world.entity(); 18 | 19 | // Create a unit 20 | let unit = world.entity(); 21 | 22 | // Add unit to platoon 1 23 | unit.add((id::(), platoon_1)); 24 | 25 | // Log platoon of unit 26 | println!( 27 | "Unit in platoon 1: {}", 28 | unit.has((id::(), platoon_1)) 29 | ); // true 30 | println!( 31 | "Unit in platoon 2: {}", 32 | unit.has((id::(), platoon_2)) 33 | ); // false 34 | 35 | println!(); 36 | 37 | // Add unit to platoon 2. Because Platoon is an exclusive relationship, this 38 | // both removes (Platoon, platoon_1) and adds (Platoon, platoon_2) in a 39 | // single operation. 40 | unit.add((id::(), platoon_2)); 41 | 42 | // Log platoon of unit 43 | println!( 44 | "Unit in platoon 1: {}", 45 | unit.has((id::(), platoon_1)) 46 | ); // false 47 | println!( 48 | "Unit in platoon 2: {}", 49 | unit.has((id::(), platoon_2)) 50 | ); // true 51 | 52 | // Output: 53 | // Unit in platoon 1: true 54 | // Unit in platoon 2: false 55 | // 56 | // Unit in platoon 1: false 57 | // Unit in platoon 2: true 58 | } 59 | 60 | #[cfg(feature = "flecs_nightly_tests")] 61 | #[test] 62 | fn test() { 63 | let output_capture = OutputCapture::capture().unwrap(); 64 | main(); 65 | output_capture.test("relationships_exclusive".to_string()); 66 | } 67 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/relationships/relationships_symmetric.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | #[derive(Component)] 5 | struct TradesWith; 6 | 7 | fn main() { 8 | let world = World::new(); 9 | 10 | // Register TradesWith as symmetric relationship. Symmetric relationships 11 | // go both ways, adding (R, B) to A will also add (R, A) to B. 12 | world 13 | .component::() 14 | .add(id::()); 15 | 16 | // Create two players 17 | let player_1 = world.entity(); 18 | let player_2 = world.entity(); 19 | 20 | // Add (TradesWith, player_2) to player_1. This also adds 21 | // (TradesWith, player_1) to player_2. 22 | player_1.add((id::(), player_2)); 23 | 24 | // Log platoon of unit 25 | println!( 26 | "Player 1 trades with Player 2: {}", 27 | player_1.has((id::(), player_2)) 28 | ); // true 29 | println!( 30 | "Player 2 trades with Player 1: {}", 31 | player_2.has((id::(), player_1)) 32 | ); // true 33 | 34 | // Output: 35 | // Player 1 trades with Player 2: true 36 | // Player 2 trades with Player 1: true 37 | } 38 | 39 | #[cfg(feature = "flecs_nightly_tests")] 40 | #[test] 41 | fn test() { 42 | let output_capture = OutputCapture::capture().unwrap(); 43 | main(); 44 | output_capture.test("relationships_symmetric".to_string()); 45 | } 46 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/script/anonymous_entity.flecs: -------------------------------------------------------------------------------- 1 | // To see what the result of parsing this file looks like, copy the code and 2 | // paste it into the editor at https://flecs.dev/explorer 3 | // 4 | // To load this file yourself, call `World::run_file("anonymous_entity.flecs");` 5 | 6 | // To create an entity without a name, use the _ character 7 | _ { 8 | SpaceShip 9 | } 10 | 11 | // Anonymous entities can be used as parents and children 12 | SpaceShip _ { 13 | _ { Engine } 14 | } 15 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/script/docs.flecs: -------------------------------------------------------------------------------- 1 | // To see what the result of parsing this file looks like, copy the code and 2 | // paste it into the editor at https://flecs.dev/explorer 3 | // 4 | // To load this file yourself, call `World::run_file("docs.flecs");` 5 | 6 | // Flecs script files can be used to annotate entities and components with 7 | // documentation. These annotations use the flecs.doc addon. 8 | 9 | @brief A brief description of planet Earth 10 | @name The Earth 11 | Earth { 12 | Planet 13 | } 14 | 15 | // Annotations can be created for entities definfed elsewhere. This makes it 16 | // possible to have a file separate from source code where you annotate your 17 | // prefabs, components and entities with documentation 18 | 19 | @brief The Position component 20 | Position 21 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/script/expressions.flecs: -------------------------------------------------------------------------------- 1 | // To see what the result of parsing this file looks like, copy the code and 2 | // paste it into the editor at https://flecs.dev/explorer 3 | // 4 | // To load this file yourself, call `World::run_file("expressions.flecs");` 5 | 6 | using flecs.meta 7 | 8 | // Create component types, see reflection example 9 | struct Position { 10 | x = f32 11 | y = f32 12 | } 13 | 14 | struct Rectangle { 15 | width = f32 16 | height = f32 17 | } 18 | 19 | // Flecs script files can contain variables that can be referenced later on when 20 | // assigning values to components 21 | const width = 5 22 | 23 | // Variables and components can be assigned using expressions. Most arithmetic 24 | // and conditional operators are supported. 25 | const height = $width * 2 26 | 27 | e { 28 | Position: {0, -($height / 2)} 29 | Rectangle: {$width, $height} 30 | } 31 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/script/hello_world.flecs: -------------------------------------------------------------------------------- 1 | // Flecs script is a simple language for loading entities into flecs. It has as 2 | // advantage that it natively integrates with Flecs features such as the 3 | // reflection addon (meta), prefabs, hierarchies and relationships. 4 | // 5 | // The syntax has been designed to make it convenient for use cases like: 6 | // - configuration files 7 | // - asset descriptions (such as prefabs) 8 | // - entity hierarchies/scene graphs 9 | // 10 | // To see what the result of parsing this file looks like, copy the code and 11 | // paste it into the editor at https://flecs.dev/explorer 12 | // 13 | // To load this file yourself, call `World::run_file("hello_world.flecs");` 14 | 15 | // This creates an entity my_spaceship with the SpaceShip tag. Note how neither 16 | // the entity nor tag need to be defined in advance, if an entity did not yet 17 | // exist, it will be created on the spot. 18 | my_spaceship { SpaceShip } 19 | 20 | // An entity can be declared in advance, which can be useful to ensure it is 21 | // placed in a specific scope. To do this just specify the name with a scope: 22 | Engine {} 23 | 24 | // By opening a scope multiple components/tags can be added to the same entity 25 | // without having to repeat the entity name. 26 | my_spaceship { 27 | Freighter 28 | (Faction, Earth) // Relationships use the same syntax as the query DSL 29 | } 30 | 31 | // A scope can also be used to add child entities. Child entities and components 32 | // can be added in the same scope. 33 | my_spaceship { 34 | FasterThanLight 35 | 36 | // This creates an engine entity with my_spaceship as parent 37 | engine { 38 | Engine // The Engine tag is added to my_spaceship.engine 39 | } 40 | } 41 | 42 | // The dot notation can be used to refer to nested entities 43 | my_spaceship.engine { 44 | Ftl 45 | } 46 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/script/prefabs.flecs: -------------------------------------------------------------------------------- 1 | // To see what the result of parsing this file looks like, copy the code and 2 | // paste it into the editor at https://flecs.dev/explorer 3 | // 4 | // To load this file yourself, call `World::run_file("prefabs.flecs");` 5 | 6 | // Create a component types (see reflection.flecs example) 7 | using flecs.meta 8 | 9 | struct Attack { 10 | value : f32 11 | } 12 | 13 | struct Defense { 14 | value : f32 15 | } 16 | 17 | // To create a prefab, you can create an entity with the Prefab tag: 18 | SpaceShip { 19 | prefab 20 | } 21 | 22 | // Alternatively you can use the shorthand declaration syntax which has the same 23 | // result, and allows you to open a scope after the statement: 24 | prefab SpaceShip { 25 | Attack: {50} 26 | Defense: {50} 27 | } 28 | 29 | // To create a prefab that inherits from SpaceShip, we can use the : operator 30 | prefab Freighter : SpaceShip { 31 | Defense: {100} 32 | } 33 | 34 | // We can create a prefab instance with the same : operator. 35 | my_spaceship : Freighter { 36 | Attack: {75} // Override component from SpaceShip 37 | } 38 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/script/reflection.flecs: -------------------------------------------------------------------------------- 1 | // To see what the result of parsing this file looks like, copy the code and 2 | // paste it into the editor at https://flecs.dev/explorer 3 | // 4 | // To load this file yourself, call `World::run_file("reflection.flecs");` 5 | 6 | // It is possible to set component values in a Flecs script file as long as the 7 | // component is described with reflection data. Since we don't have a component 8 | // yet, we'll first have to create one. 9 | 10 | // Flecs script does not have dedicated syntax for describing types, but since the 11 | // reflection addon (flecs.meta) uses regular entities and components to store 12 | // reflection data, we can use existing Flecs script syntax to create a type. 13 | 14 | // First we'll add flecs.meta to the list of namespaces to search. This is not 15 | // strictly necessary, but lets us write Struct instead of flecs.meta.Struct 16 | using flecs.meta 17 | 18 | // We can now create a struct like this. "Struct Position" is the shorthand 19 | // declaration syntax for "Position :- Struct", and has as benefit that we can 20 | // open a scope after the statement 21 | struct Position { 22 | // Add two child entities with the Member component 23 | x { member: {type: f32} } 24 | y { member: {type: f32} } 25 | } 26 | 27 | // Flecs script has a feature which makes it possible to specify a default type for a 28 | // scope. The Struct component has Member as default type. This means we can 29 | // also create a type like this, which is a bit shorter: 30 | struct Mass { 31 | value = f32 // 'type' can be omitted since it's the first member 32 | } 33 | 34 | // Similarly we can also define an enumeration type. The default scope type for 35 | // Enum is Constant, which ensures amongst others that the child entities will 36 | // be assigned with an incrementing constant value automatically. 37 | enum Color { 38 | Red, 39 | Green, 40 | Blue 41 | } 42 | 43 | // We can now create an entity that uses the types 44 | my_entity { 45 | Position: {x: 10, y: 20} 46 | Mass: {100} // Member names are optional 47 | Color: {Green} // Green will be automatically looked up in the Color scope 48 | } 49 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/script/strings.flecs: -------------------------------------------------------------------------------- 1 | // To see what the result of parsing this file looks like, copy the code and 2 | // paste it into the editor at https://flecs.dev/explorer 3 | // 4 | // To load this file yourself, call `World::run_file("strings.flecs");` 5 | 6 | // Flecs script component values can be populated with strings. To see how this works, 7 | // we first need to create a component type (see reflection example). 8 | using flecs.meta 9 | 10 | struct Shader { 11 | filename = string 12 | code = string 13 | } 14 | 15 | // Create component values with strings 16 | my_pipeline { 17 | (Shader, Vertex): { 18 | // Normal string 19 | filename: "vert.glsl", 20 | 21 | // Multiline string 22 | code: ` 23 | void main() { 24 | gl_Position = pos; 25 | }` 26 | } 27 | 28 | (Shader, Fragment): { 29 | filename: "frag.glsl", 30 | code: ` 31 | void main() { 32 | frag_color = color; 33 | }` 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/script/with.flecs: -------------------------------------------------------------------------------- 1 | // To see what the result of parsing this file looks like, copy the code and 2 | // paste it into the editor at https://flecs.dev/explorer 3 | // 4 | // To load this file yourself, call `World::run_file("with.flecs");` 5 | 6 | // Sometimes you want to add the same component to a lot of entities. To avoid 7 | // repeating yourself, you can use the "with" keyword: 8 | with Planet { 9 | // With statements can be nested, which adds to the list of components to add 10 | with InnerPlanet { 11 | Mercury {} 12 | Venus {} 13 | Earth { 14 | // A with scope contains regular statements so we can do anything we can 15 | // do normally, like assign components and open scopes. 16 | SupportsLife 17 | } 18 | Mars {} 19 | } 20 | with OuterPlanet { 21 | Jupiter {} 22 | Saturn {} 23 | Neptune {} 24 | Uranus {} 25 | } 26 | } 27 | 28 | // A with statement may be placed inside of a scope 29 | Jupiter { 30 | with Moon { 31 | Io {} 32 | Europa {} 33 | Ganymede {} 34 | Callisto {} 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/systems/mod.rs: -------------------------------------------------------------------------------- 1 | mod system_basics; 2 | mod system_ctx; 3 | mod system_custom_phases; 4 | mod system_custom_phases_no_builtin; 5 | mod system_custom_pipeline; 6 | mod system_custom_runner; 7 | mod system_delta_time; 8 | mod system_immediate; 9 | mod system_mutate_entity; 10 | mod system_mutate_entity_handle; 11 | mod system_pipeline; 12 | mod system_startup_system; 13 | mod system_sync_point; 14 | mod system_sync_point_delete; 15 | mod system_target_fps; 16 | mod system_time_interval; 17 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/systems/system_basics.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | pub struct Position { 7 | pub x: f32, 8 | pub y: f32, 9 | } 10 | 11 | #[derive(Debug, Component)] 12 | pub struct Velocity { 13 | pub x: f32, 14 | pub y: f32, 15 | } 16 | 17 | fn main() { 18 | let world = World::new(); 19 | 20 | // Create a system for Position, Velocity. Systems are like queries (see 21 | // queries) with a function that can be ran or scheduled (see pipeline). 22 | 23 | let s = world 24 | .system::<(&mut Position, &Velocity)>() 25 | .each_entity(|e, (p, v)| { 26 | p.x += v.x; 27 | p.y += v.y; 28 | println!("{}: {{ {}, {} }}", e.name(), p.x, p.y); 29 | }); 30 | 31 | // Create a few test entities for a Position, Velocity query 32 | world 33 | .entity_named("e1") 34 | .set(Position { x: 10.0, y: 20.0 }) 35 | .set(Velocity { x: 1.0, y: 2.0 }); 36 | 37 | world 38 | .entity_named("e2") 39 | .set(Position { x: 10.0, y: 20.0 }) 40 | .set(Velocity { x: 3.0, y: 4.0 }); 41 | 42 | // This entity will not match as it does not have Position, Velocity 43 | world.entity_named("e3").set(Position { x: 10.0, y: 20.0 }); 44 | 45 | // Run the system 46 | s.run(); 47 | 48 | // Output: 49 | // e1: { 11, 22 } 50 | // e2: { 13, 24 } 51 | } 52 | 53 | #[cfg(feature = "flecs_nightly_tests")] 54 | #[test] 55 | fn test() { 56 | let output_capture = OutputCapture::capture().unwrap(); 57 | main(); 58 | output_capture.test("system_basics".to_string()); 59 | } 60 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/systems/system_custom_phases.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | // This application demonstrates how to use custom phases for systems. The 5 | // default pipeline will automatically run systems for custom phases as long as 6 | // they have the flecs::Phase tag. 7 | 8 | // Dummy system 9 | fn sys(mut it: TableIter) { 10 | while it.next() { 11 | println!("system {}", it.system().name()); 12 | } 13 | } 14 | 15 | fn main() { 16 | let world = World::new(); 17 | 18 | // Create two custom phases that branch off of EcsOnUpdate. Note that the 19 | // phases have the Phase tag, which is necessary for the builtin pipeline 20 | // to discover which systems it should run. 21 | let physics = world 22 | .entity() 23 | .add(id::()) 24 | .depends_on(id::()); 25 | 26 | let collisions = world 27 | .entity() 28 | .add(id::()) 29 | .depends_on(physics); 30 | 31 | // Create 3 dummy systems. 32 | world 33 | .system_named::<()>("CollisionSystem") 34 | .kind(collisions) 35 | .run(sys); 36 | 37 | world 38 | .system_named::<()>("PhysicsSystem") 39 | .kind(physics) 40 | .run(sys); 41 | 42 | world 43 | .system_named::<()>("GameSystem") 44 | .kind(id::()) 45 | .run(sys); 46 | 47 | // Run pipeline 48 | world.progress(); 49 | 50 | // Output: 51 | // system GameSystem 52 | // system PhysicsSystem 53 | // system CollisionSystem 54 | } 55 | 56 | #[cfg(feature = "flecs_nightly_tests")] 57 | #[test] 58 | fn test() { 59 | let output_capture = OutputCapture::capture().unwrap(); 60 | main(); 61 | output_capture.test("system_custom_phases".to_string()); 62 | } 63 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/systems/system_custom_phases_no_builtin.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | // This application demonstrates how to use custom phases for systems. The 5 | // default pipeline will automatically run systems for custom phases as long as 6 | // they have the flecs::Phase tag. 7 | 8 | // Dummy system 9 | fn sys(mut it: TableIter) { 10 | while it.next() { 11 | println!("system {}", it.system().name()); 12 | } 13 | } 14 | 15 | fn main() { 16 | let world = World::new(); 17 | 18 | // Create three custom phases. Note that the phases have the Phase tag, 19 | // which is necessary for the builtin pipeline to discover which systems it 20 | // should run. 21 | 22 | let update = world.entity().add(id::()); 23 | 24 | let physics = world 25 | .entity() 26 | .add(id::()) 27 | .depends_on(update); 28 | 29 | let collisions = world 30 | .entity() 31 | .add(id::()) 32 | .depends_on(physics); 33 | 34 | // Create 3 dummy systems. 35 | world 36 | .system_named::<()>("CollisionSystem") 37 | .kind(collisions) 38 | .run(sys); 39 | 40 | world 41 | .system_named::<()>("PhysicsSystem") 42 | .kind(physics) 43 | .run(sys); 44 | 45 | world.system_named::<()>("GameSystem").kind(update).run(sys); 46 | 47 | // Run pipeline 48 | world.progress(); 49 | 50 | // Output: 51 | // system GameSystem 52 | // system PhysicsSystem 53 | // system CollisionSystem 54 | } 55 | 56 | #[cfg(feature = "flecs_nightly_tests")] 57 | #[test] 58 | fn test() { 59 | let output_capture = OutputCapture::capture().unwrap(); 60 | main(); 61 | output_capture.test("system_custom_phases_no_builtin".to_string()); 62 | } 63 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/systems/system_custom_pipeline.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | // Custom pipelines make it possible for applications to override which systems 5 | // are ran by a pipeline and how they are ordered. Pipelines are queries under 6 | // the hood, and custom pipelines override the query used for system matching. 7 | 8 | // If you only want to use custom phases in addition or in place of the builtin 9 | // phases see the custom_phases and custom_phases_no_builtin examples, as this 10 | // does not require using a custom pipeline. 11 | 12 | #[derive(Debug, Component, Default)] 13 | struct Physics; 14 | 15 | fn main() { 16 | let world = World::new(); 17 | 18 | // Create a pipeline that matches systems with Physics. Note that this 19 | // pipeline does not require the use of phases (see custom_phases) or of the 20 | // DependsOn relationship. 21 | let pipeline = world 22 | .pipeline() 23 | .with(flecs::system::System::ID) 24 | .with(id::<&Physics>()) 25 | .build(); 26 | 27 | // Configure the world to use the custom pipeline 28 | world.set_pipeline(pipeline.entity()); 29 | 30 | // Create system with Physics tag 31 | world.system::<()>().kind(id::()).run(|mut it| { 32 | while it.next() { 33 | println!("System with Physics ran!"); 34 | } 35 | }); 36 | 37 | // Create system without Physics tag 38 | world.system::<()>().run(|mut it| { 39 | while it.next() { 40 | println!("System without Physics ran!"); 41 | } 42 | }); 43 | 44 | // Runs the pipeline & system 45 | world.progress(); 46 | 47 | // Output: 48 | // System with Physics ran! 49 | } 50 | 51 | #[cfg(feature = "flecs_nightly_tests")] 52 | #[test] 53 | fn test() { 54 | let output_capture = OutputCapture::capture().unwrap(); 55 | main(); 56 | output_capture.test("system_custom_pipeline".to_string()); 57 | } 58 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/systems/system_custom_runner.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | pub struct Position { 7 | pub x: f32, 8 | pub y: f32, 9 | } 10 | 11 | #[derive(Debug, Component)] 12 | pub struct Velocity { 13 | pub x: f32, 14 | pub y: f32, 15 | } 16 | 17 | // Systems can be created with a custom run function that takes control over the 18 | // entire iteration. By a system is invoked once per matched table, 19 | // which means the function can be called multiple times per frame. In some 20 | // cases that's inconvenient, like when a system has things it needs to do only 21 | // once per frame. For these use cases, the run callback can be used which is 22 | // called once per frame per system. 23 | 24 | fn main() { 25 | let world = World::new(); 26 | 27 | let system = world 28 | .system::<(&mut Position, &Velocity)>() 29 | // Forward each result from the run callback to the each callback. 30 | .run_each_entity( 31 | |mut iter| { 32 | println!("Move begin"); 33 | 34 | while iter.next() { 35 | iter.each(); 36 | } 37 | 38 | println!("Move end"); 39 | }, 40 | |e, (pos, vel)| { 41 | pos.x += vel.x; 42 | pos.y += vel.y; 43 | println!("{}: {{ {}, {} }}", e.name(), pos.x, pos.y); 44 | }, 45 | ); 46 | 47 | // Create a few test entities for a Position, Velocity query 48 | world 49 | .entity_named("e1") 50 | .set(Position { x: 10.0, y: 20.0 }) 51 | .set(Velocity { x: 1.0, y: 2.0 }); 52 | 53 | world 54 | .entity_named("e2") 55 | .set(Position { x: 10.0, y: 20.0 }) 56 | .set(Velocity { x: 3.0, y: 4.0 }); 57 | 58 | // This entity will not match as it does not have Position, Velocity 59 | world.entity_named("e3").set(Position { x: 10.0, y: 20.0 }); 60 | 61 | // Run the system 62 | system.run(); 63 | 64 | // Output: 65 | // Move begin 66 | // e1: {11, 22} 67 | // e2: {13, 24} 68 | // Move end 69 | } 70 | 71 | #[cfg(feature = "flecs_nightly_tests")] 72 | #[test] 73 | fn test() { 74 | let output_capture = OutputCapture::capture().unwrap(); 75 | main(); 76 | output_capture.test("system_custom_runner".to_string()); 77 | } 78 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/systems/system_delta_time.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | fn main() { 6 | let world = World::new(); 7 | 8 | // Create system that prints delta_time. This system doesn't query for any 9 | // components which means it won't match any entities, but will still be ran 10 | // once for each call to ecs_progress. 11 | world.system::<()>().run(|mut it| { 12 | while it.next() { 13 | println!("delta_time: {}", it.delta_time()); 14 | } 15 | }); 16 | 17 | // Call progress with 0.0f for the delta_time parameter. This will cause 18 | // ecs_progress to measure the time passed since the last frame. The 19 | // delta_time of the first frame is a best guess (16ms). 20 | world.progress(); 21 | 22 | // The following calls should print a delta_time of approximately 100ms 23 | 24 | let os_sleep = unsafe { flecs_ecs_sys::ecs_os_api.sleep_ }.unwrap(); 25 | 26 | unsafe { os_sleep(0, 100 * 1000 * 1000) }; 27 | world.progress(); 28 | 29 | unsafe { os_sleep(0, 100 * 1000 * 1000) }; 30 | 31 | world.progress(); 32 | 33 | // Output: 34 | // delta_time: 0.016666668 35 | // delta_time: 0.10155179 36 | // delta_time: 0.10091246 37 | } 38 | 39 | #[cfg(feature = "flecs_nightly_tests")] 40 | #[test] 41 | fn test() { 42 | let output_capture = OutputCapture::capture().unwrap(); 43 | main(); 44 | assert!(output_capture.output().lock().unwrap().len() > 0); 45 | } 46 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/systems/system_pipeline.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | #[derive(Debug, Component)] 6 | pub struct Position { 7 | pub x: f32, 8 | pub y: f32, 9 | } 10 | 11 | #[derive(Debug, Component)] 12 | pub struct Velocity { 13 | pub x: f32, 14 | pub y: f32, 15 | } 16 | 17 | fn main() { 18 | let world = World::new(); 19 | 20 | // Create a system for moving an entity 21 | world 22 | .system::<(&mut Position, &Velocity)>() 23 | .kind(id::()) 24 | .each(|(p, v)| { 25 | p.x += v.x; 26 | p.y += v.y; 27 | }); 28 | 29 | // Create a system for printing the entity position 30 | world 31 | .system::<&Position>() 32 | .kind(id::()) 33 | .each_entity(|e, p| { 34 | println!("{}: {{ {}, {} }}", e.name(), p.x, p.y); 35 | }); 36 | 37 | // Create a few test entities for a Position, Velocity query 38 | world 39 | .entity_named("e1") 40 | .set(Position { x: 10.0, y: 20.0 }) 41 | .set(Velocity { x: 1.0, y: 2.0 }); 42 | 43 | world 44 | .entity_named("e2") 45 | .set(Position { x: 10.0, y: 20.0 }) 46 | .set(Velocity { x: 3.0, y: 4.0 }); 47 | 48 | // Run the default pipeline. This will run all systems ordered by their 49 | // phase. Systems within the same phase are ran in declaration order. This 50 | // function is usually called in a loop. 51 | world.progress(); 52 | 53 | // Output: 54 | // e1: { 11, 22 } 55 | // e2: { 13, 24 } 56 | } 57 | 58 | #[cfg(feature = "flecs_nightly_tests")] 59 | #[test] 60 | fn test() { 61 | let output_capture = OutputCapture::capture().unwrap(); 62 | main(); 63 | output_capture.test("system_pipeline".to_string()); 64 | } 65 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/systems/system_startup_system.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | // Startup systems are systems registered with the EcsOnStart phase, and are 5 | // only ran during the first frame. Just like with regular phases, custom phases 6 | // can depend on the EcsOnStart phase (see custom_phases example). Phases that 7 | // depend on EcsOnStart are also only ran during the first frame. 8 | // 9 | // Other than that, startup systems behave just like regular systems (they can 10 | // match components, can introduce merge points), with as only exception that 11 | // they are guaranteed to always run on the main thread. 12 | 13 | fn main() { 14 | let world = World::new(); 15 | 16 | // Startup system 17 | world 18 | .system_named::<()>("Startup") 19 | .kind(id::()) 20 | .run(|mut it| { 21 | while it.next() { 22 | println!("{}", it.system().name()); 23 | } 24 | }); 25 | 26 | // Regular system 27 | world.system_named::<()>("Update").run(|mut it| { 28 | while it.next() { 29 | println!("{}", it.system().name()); 30 | } 31 | }); 32 | 33 | // First frame. This runs both the Startup and Update systems 34 | world.progress(); 35 | 36 | // Second frame. This runs only the Update system 37 | world.progress(); 38 | 39 | // Output: 40 | // Startup 41 | // Update 42 | // Update 43 | } 44 | 45 | #[cfg(feature = "flecs_nightly_tests")] 46 | #[test] 47 | fn test() { 48 | let output_capture = OutputCapture::capture().unwrap(); 49 | main(); 50 | output_capture.test("system_startup_system".to_string()); 51 | } 52 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/systems/system_target_fps.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | 5 | fn main() { 6 | let world = World::new(); 7 | 8 | // Create system that prints delta_time. This system doesn't query for any 9 | // components which means it won't match any entities, but will still be ran 10 | // once for each call to ecs_progress. 11 | world.system::<()>().run(|mut it| { 12 | while it.next() { 13 | println!("Delta time: {}", it.delta_time()); 14 | } 15 | }); 16 | 17 | // Set target FPS to 1 frame per second 18 | world.set_target_fps(1.0); 19 | 20 | // Run 3 frames 21 | for _ in 0..3 { 22 | // To make sure the frame doesn't run faster than the specified target 23 | // FPS ecs_progress will insert a sleep if the measured delta_time is 24 | // smaller than 1 / target_fps. 25 | // 26 | // By default ecs_progress uses the sleep function provided by the OS 27 | // which is not always very accurate. If more accuracy is required the 28 | // sleep function of the OS API can be overridden with a custom one. 29 | // 30 | // If a value other than 0 is provided to the delta_time argument of 31 | // ecs_progress, this value will be used to calculate the length of 32 | // the sleep to insert. 33 | world.progress(); 34 | } 35 | 36 | // Output: 37 | // Delta time: 1 38 | // Delta time: 1.0182016 39 | // Delta time: 1.0170991 40 | } 41 | 42 | #[cfg(feature = "flecs_nightly_tests")] 43 | #[test] 44 | fn test() { 45 | let output_capture = OutputCapture::capture().unwrap(); 46 | main(); 47 | assert!(output_capture.output().lock().unwrap().len() > 0); 48 | } 49 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/systems/system_time_interval.rs: -------------------------------------------------------------------------------- 1 | use crate::z_ignore_test_common::*; 2 | 3 | use flecs_ecs::prelude::*; 4 | // This example shows how to run a system at a specified time interval. 5 | 6 | #[derive(Component)] 7 | struct Timeout { 8 | pub value: f32, 9 | } 10 | 11 | fn tick(mut it: TableIter) { 12 | while it.next() { 13 | println!("{}", it.system().name()); 14 | } 15 | } 16 | 17 | fn main() { 18 | let world = World::new(); 19 | 20 | world.set(Timeout { value: 3.5 }); 21 | 22 | world 23 | .system::<&mut Timeout>() 24 | .each_iter(|it, _index, timeout| { 25 | timeout.value -= it.delta_time(); 26 | }); 27 | 28 | world.system_named::<()>("Tick").set_interval(1.0).run(tick); 29 | 30 | world 31 | .system_named::<()>("FastTick") 32 | .set_interval(0.5) 33 | .run(tick); 34 | 35 | // Run the main loop at 60 FPS 36 | world.set_target_fps(60.0); 37 | 38 | while world.progress() { 39 | if world.get::<&Timeout>(|timeout| timeout.value <= 0.0) { 40 | println!("Timed out!"); 41 | break; 42 | } 43 | } 44 | 45 | // Output: 46 | // FastTick 47 | // Tick 48 | // FastTick 49 | // FastTick 50 | // Tick 51 | // FastTick 52 | // FastTick 53 | // Tick 54 | // FastTick 55 | // FastTick 56 | // Timed out! 57 | } 58 | 59 | #[cfg(feature = "flecs_nightly_tests")] 60 | #[test] 61 | fn test() { 62 | let output_capture = OutputCapture::capture().unwrap(); 63 | main(); 64 | assert!(output_capture.output_string().contains("Timed out!")); 65 | } 66 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_main_test.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(feature = "flecs_nightly_tests", feature(internal_output_capture))] 2 | #![allow(dead_code)] 3 | #![allow(clippy::print_stderr, clippy::print_stdout)] 4 | #![allow(unused_imports)] 5 | #![allow(unused_variables)] 6 | #![allow(unused)] 7 | #![allow(unexpected_cfgs)] 8 | 9 | // to initialize the OS api for flecs before tests run. 10 | #[cfg(test)] 11 | #[ctor::ctor] 12 | fn init() { 13 | unsafe { 14 | flecs_ecs::sys::ecs_os_init(); 15 | } 16 | } 17 | 18 | pub mod z_ignore_test_common; 19 | 20 | mod entities; 21 | mod game_mechanics; 22 | mod hello_world; 23 | mod observers; 24 | mod prefabs; 25 | mod queries; 26 | mod reflection; 27 | mod relationships; 28 | mod systems; 29 | 30 | fn main() {} 31 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@entity_basics.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Bob's position: Position { x: 10.0, y: 20.0 }\n[examples.entities.entity_basics.Position, examples.entities.entity_basics.Walking, (Identifier,Name)]\nAlice has Position { x: 10.0, y: 20.0 }\nBob has Position { x: 20.0, y: 30.0 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@entity_hierarchy.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Is the Moon a child of the Earth? true / true\n\n::Sun [examples.entities.entity_hierarchy.Position, (Identifier,Name)]\nPosition { x: 1.0, y: 1.0 }\n::Sun::Mercury [examples.entities.entity_hierarchy.Position, examples.entities.entity_hierarchy.Planet, (Identifier,Name), (ChildOf,Sun)]\nPosition { x: 2.0, y: 2.0 }\n::Sun::Venus [examples.entities.entity_hierarchy.Position, examples.entities.entity_hierarchy.Planet, (Identifier,Name), (ChildOf,Sun)]\nPosition { x: 3.0, y: 3.0 }\n::Sun::Earth [examples.entities.entity_hierarchy.Position, examples.entities.entity_hierarchy.Planet, (Identifier,Name), (ChildOf,Sun)]\nPosition { x: 4.0, y: 4.0 }\n::Sun::Earth::Moon [examples.entities.entity_hierarchy.Position, examples.entities.entity_hierarchy.Moon, (Identifier,Name), (ChildOf,Sun.Earth)]\nPosition { x: 4.1, y: 4.1 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@entity_hooks.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "added Position to \"Bob\"\nset Position { x: 10.0, y: 20.0 } for \"Bob\"\nremoved Position { x: 10.0, y: 20.0 } from \"Bob\"\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@entity_iterate_components.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Bob's components:\n[examples.entities.entity_iterate_components.Position, examples.entities.entity_iterate_components.Velocity, examples.entities.entity_iterate_components.Human, (Identifier,Name), (examples.entities.entity_iterate_components.Eats,examples.entities.entity_iterate_components.Apples)]\n\n0: examples.entities.entity_iterate_components.Position\n1: examples.entities.entity_iterate_components.Velocity\n2: examples.entities.entity_iterate_components.Human\n3: (Identifier,Name)\n4: (examples.entities.entity_iterate_components.Eats,examples.entities.entity_iterate_components.Apples)\n\n0: entity: Position\n1: entity: Velocity\n2: entity: Human\n3: rel: Identifier, target: Name\n4: rel: Eats, target: Apples\n\nPosition's components:\n[Component, (Identifier,Name), (Identifier,Symbol), (ChildOf,examples.entities.entity_iterate_components)]\n\n0: Component\n1: (Identifier,Name)\n2: (Identifier,Symbol)\n3: (ChildOf,examples.entities.entity_iterate_components)\n\n0: entity: Component\n1: rel: Identifier, target: Name\n2: rel: Identifier, target: Symbol\n3: rel: ChildOf, target: entity_iterate_components\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@entity_prefab.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Instance type: [examples.entities.entity_prefab.Position, (Identifier,Name), (IsA,MammothFreighter)]\nImpulseSpeed: 50\nEntity my_mammoth_freighter: Position { x: 50.0, y: 0.0 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@hello world.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Bob's got [examples.hello_world.Position, examples.hello_world.Velocity, (Identifier,Name), (examples.hello_world.Eats,examples.hello_world.Apples)]\nBob's position: Position { x: 2.0, y: 4.0 }\nBob's try_get position: Position { x: 2.0, y: 4.0 }\nBob has a position component, so the try_get callback ran.\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@observer_basics.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | " - OnAdd: examples.observers.observer_basics.Position: e1\n - OnSet: examples.observers.observer_basics.Position: e1: with Position { x: 10.0, y: 20.0 }\n - OnRemove: examples.observers.observer_basics.Position: e1: with Position { x: 10.0, y: 20.0 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@observer_custom_event.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | " - MyEvent: examples.observers.observer_custom_event.Position: e1\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@observer_entity_event.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "widget: Entity name: MyWidget -- [ID] -- archetype: (Identifier,Name)\nclicked on \"MyWidget\"\nclicked!\nwidget resized to { 100, 200 }!\nMyWidget resized to { 100, 200 }!\nClose request with reason: User\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@observer_monitor.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | " - Enter: examples.observers.observer_monitor.Velocity: e\n - Leave: examples.observers.observer_monitor.Position: e\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@observer_propagate.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | " - OnSet: examples.observers.observer_propagate.Position: e: self: { 10, 20 }, parent: { 1, 2 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@observer_two_components.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | " - OnSet: examples.observers.observer_two_components.Velocity: e: p: { 10, 20 }, v: { 1, 2 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@observer_yield_existing.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | " - OnSet: examples.observers.observer_yield_existing.Position: e1: { 10, 20 }\n - OnSet: examples.observers.observer_yield_existing.Position: e2: { 20, 30 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@prefab_basics.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Defence { value: 50.0 }\nafter set: Defence { value: 100.0 }\n::my_spaceship: defence: 100\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@prefab_hierarchy.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "instance engine: \"::my_spaceship::Engine\"\ninstance cockpit: \"::my_spaceship::Cockpit\"\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@prefab_nested.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "examples.prefabs.prefab_nested.TirePressure, (Identifier,Name), (ChildOf,my_car), (IsA,Wheel)\npressure: 32\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@prefab_override.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "examples.prefabs.prefab_override.Damage, (Identifier,Name), (IsA,SpaceShip)\nexamples.prefabs.prefab_override.Attack, examples.prefabs.prefab_override.Damage, (Identifier,Name), (IsA,SpaceShip)\nattack: 75\ndefence: 100\ndamage: 50\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@prefab_slots.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "instance engine: ::my_spaceship::Engine\ninstance cockpit: ::my_spaceship::Cockpit\ninstance seat: ::my_spaceship::Cockpit::PilotSeat\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@prefab_typed.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "instance base: ::my_railgun::Base\ninstance head: ::my_railgun::Head\ninstance beam: ::my_railgun::Beam\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@prefab_variant.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "my_freighter:\n - position: 10, 20\n - impulse speed: 50\n - defense: 100\n - capacity: 500\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_basics.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "e1: [Position { x: 11.0, y: 22.0 }]\ne2: [Position { x: 13.0, y: 24.0 }]\n[Position { x: 12.0, y: 24.0 }]\n[Position { x: 16.0, y: 28.0 }]\n[Position { x: 13.0, y: 26.0 }]\n[Position { x: 19.0, y: 32.0 }]\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_chaining_queries.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Creature [ID] at location 0,0 is enchanted with mystical energy, ability power: 0 \nCreature [ID] at location 2,2 is enchanted with mystical energy, ability power: 3 \nCreature [ID] at location 4,4 is enchanted with mystical energy, ability power: 6 \nCreature [ID] at location 6,6 is enchanted with mystical energy, ability power: 9 \nCreature [ID] at location 8,8 is enchanted with mystical energy, ability power: 12 \n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_change_tracking_1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "non-skip archetype: examples.queries.query_change_tracking_1.Position, examples.queries.query_change_tracking_1.WorldPosition, (Identifier,Name)\nnon-skip archetype: examples.queries.query_change_tracking_1.Position, examples.queries.query_change_tracking_1.WorldPosition, (Identifier,Name), (ChildOf,parent)\nnon-skip archetype: examples.queries.query_change_tracking_1.Position, examples.queries.query_change_tracking_1.WorldPosition, examples.queries.query_change_tracking_1.DummyTag, (Identifier,Name)\nskip archetype: examples.queries.query_change_tracking_1.Position, examples.queries.query_change_tracking_1.WorldPosition, (Identifier,Name)\nnon-skip archetype: examples.queries.query_change_tracking_1.Position, examples.queries.query_change_tracking_1.WorldPosition, (Identifier,Name), (ChildOf,parent)\nskip archetype: examples.queries.query_change_tracking_1.Position, examples.queries.query_change_tracking_1.WorldPosition, examples.queries.query_change_tracking_1.DummyTag, (Identifier,Name)\n\nparent: WorldPosition { x: 100.0, y: 200.0 }\nchild: WorldPosition { x: 210.0, y: 410.0 }\nindependent: WorldPosition { x: 50.0, y: 30.0 }\nskip archetype: examples.queries.query_change_tracking_1.Position, examples.queries.query_change_tracking_1.WorldPosition, (Identifier,Name)\nskip archetype: examples.queries.query_change_tracking_1.Position, examples.queries.query_change_tracking_1.WorldPosition, (Identifier,Name), (ChildOf,parent)\nnon-skip archetype: examples.queries.query_change_tracking_1.Position, examples.queries.query_change_tracking_1.WorldPosition, examples.queries.query_change_tracking_1.DummyTag, (Identifier,Name)\n\nparent: WorldPosition { x: 100.0, y: 200.0 }\nchild: WorldPosition { x: 210.0, y: 410.0 }\nindependent: WorldPosition { x: 60.0, y: 40.0 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_change_tracking_2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "\nquery_read.is_changed(): true\n\niiter.is_changed() for table [examples.queries.query_change_tracking_2.Position, (Identifier,Name), (IsA,prefab_dirty_false)]: true\niiter.is_changed() for table [examples.queries.query_change_tracking_2.Position, (Identifier,Name), (IsA,prefab_dirty_true)]: true\n\nquery_read.is_changed(): false\n\niterate table [examples.queries.query_change_tracking_2.Position, (Identifier,Name), (IsA,prefab_dirty_false)]\niter.skip() for table [examples.queries.query_change_tracking_2.Position, (Identifier,Name), (IsA,prefab_dirty_false)]\niterate table [examples.queries.query_change_tracking_2.Position, (Identifier,Name), (IsA,prefab_dirty_true)]\n\nquery_read.is_changed(): true\n\niter.is_changed() for table [examples.queries.query_change_tracking_2.Position, (Identifier,Name), (IsA,prefab_dirty_false)]: false\niter.is_changed() for table [examples.queries.query_change_tracking_2.Position, (Identifier,Name), (IsA,prefab_dirty_true)]: true\n\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_component_inheritance.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Unit wizard_1 found\nUnit wizard_2 found\nUnit marksman_1 found\nUnit marksman_2 found\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_cyclic_variables.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Alice likes Bob\nJohn likes Jane\nJane likes John\nBob likes Alice\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_facts.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Are Bob and Alice friends? Yes\nAre Bob and John friends? No\nAre Jane and John friends? Yes\nAre John and Jane friends? Yes\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_find_entity.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Entity found: \"::e2\"\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_group_by.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "\nGroup: \"::examples::queries::query_group_by::First\" - Table: [Some(examples.queries.query_group_by.Position, (examples.queries.query_group_by.Group,examples.queries.query_group_by.First))]\n [Position { x: 3.0, y: 3.0 }]\n\nGroup: \"::examples::queries::query_group_by::First\" - Table: [Some(examples.queries.query_group_by.Position, examples.queries.query_group_by.Tag, (examples.queries.query_group_by.Group,examples.queries.query_group_by.First))]\n [Position { x: 6.0, y: 6.0 }]\n\nGroup: \"::examples::queries::query_group_by::Second\" - Table: [Some(examples.queries.query_group_by.Position, (examples.queries.query_group_by.Group,examples.queries.query_group_by.Second))]\n [Position { x: 2.0, y: 2.0 }]\n\nGroup: \"::examples::queries::query_group_by::Second\" - Table: [Some(examples.queries.query_group_by.Position, examples.queries.query_group_by.Tag, (examples.queries.query_group_by.Group,examples.queries.query_group_by.Second))]\n [Position { x: 5.0, y: 5.0 }]\n\nGroup: \"::examples::queries::query_group_by::Third\" - Table: [Some(examples.queries.query_group_by.Position, (examples.queries.query_group_by.Group,examples.queries.query_group_by.Third))]\n [Position { x: 1.0, y: 1.0 }]\n\nGroup: \"::examples::queries::query_group_by::Third\" - Table: [Some(examples.queries.query_group_by.Position, examples.queries.query_group_by.Tag, (examples.queries.query_group_by.Group,examples.queries.query_group_by.Third))]\n [Position { x: 4.0, y: 4.0 }]\n\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_group_by_callbacks.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "\nGroup created: \"Third\"\n\nGroup created: \"Second\"\n\nGroup created: \"First\"\n\nGroup: \"::examples::queries::query_group_by_callbacks::First\" - Table: [Some(examples.queries.query_group_by_callbacks.Position, (examples.queries.query_group_by_callbacks.Group,examples.queries.query_group_by_callbacks.First))] - Counter: 3\n [Position { x: 3.0, y: 3.0 }]\n\nGroup: \"::examples::queries::query_group_by_callbacks::First\" - Table: [Some(examples.queries.query_group_by_callbacks.Position, examples.queries.query_group_by_callbacks.Tag, (examples.queries.query_group_by_callbacks.Group,examples.queries.query_group_by_callbacks.First))] - Counter: 3\n [Position { x: 6.0, y: 6.0 }]\n\nGroup: \"::examples::queries::query_group_by_callbacks::Second\" - Table: [Some(examples.queries.query_group_by_callbacks.Position, (examples.queries.query_group_by_callbacks.Group,examples.queries.query_group_by_callbacks.Second))] - Counter: 2\n [Position { x: 2.0, y: 2.0 }]\n\nGroup: \"::examples::queries::query_group_by_callbacks::Second\" - Table: [Some(examples.queries.query_group_by_callbacks.Position, examples.queries.query_group_by_callbacks.Tag, (examples.queries.query_group_by_callbacks.Group,examples.queries.query_group_by_callbacks.Second))] - Counter: 2\n [Position { x: 5.0, y: 5.0 }]\n\nGroup: \"::examples::queries::query_group_by_callbacks::Third\" - Table: [Some(examples.queries.query_group_by_callbacks.Position, (examples.queries.query_group_by_callbacks.Group,examples.queries.query_group_by_callbacks.Third))] - Counter: 1\n [Position { x: 1.0, y: 1.0 }]\n\nGroup: \"::examples::queries::query_group_by_callbacks::Third\" - Table: [Some(examples.queries.query_group_by_callbacks.Position, examples.queries.query_group_by_callbacks.Tag, (examples.queries.query_group_by_callbacks.Group,examples.queries.query_group_by_callbacks.Third))] - Counter: 1\n [Position { x: 4.0, y: 4.0 }]\n\ngroup deleted: redacted\ngroup deleted: redacted\ngroup deleted: redacted\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_group_by_custom.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "\nGroup: \"::examples::queries::query_group_by_custom::First\" - Table: [Some(examples.queries.query_group_by_custom.Position, (examples.queries.query_group_by_custom.Group,examples.queries.query_group_by_custom.First))]\n [Position { x: 3.0, y: 3.0 }]\n\nGroup: \"::examples::queries::query_group_by_custom::First\" - Table: [Some(examples.queries.query_group_by_custom.Position, examples.queries.query_group_by_custom.Tag, (examples.queries.query_group_by_custom.Group,examples.queries.query_group_by_custom.First))]\n [Position { x: 6.0, y: 6.0 }]\n\nGroup: \"::examples::queries::query_group_by_custom::Second\" - Table: [Some(examples.queries.query_group_by_custom.Position, (examples.queries.query_group_by_custom.Group,examples.queries.query_group_by_custom.Second))]\n [Position { x: 2.0, y: 2.0 }]\n\nGroup: \"::examples::queries::query_group_by_custom::Second\" - Table: [Some(examples.queries.query_group_by_custom.Position, examples.queries.query_group_by_custom.Tag, (examples.queries.query_group_by_custom.Group,examples.queries.query_group_by_custom.Second))]\n [Position { x: 5.0, y: 5.0 }]\n\nGroup: \"::examples::queries::query_group_by_custom::Third\" - Table: [Some(examples.queries.query_group_by_custom.Position, (examples.queries.query_group_by_custom.Group,examples.queries.query_group_by_custom.Third))]\n [Position { x: 1.0, y: 1.0 }]\n\nGroup: \"::examples::queries::query_group_by_custom::Third\" - Table: [Some(examples.queries.query_group_by_custom.Position, examples.queries.query_group_by_custom.Tag, (examples.queries.query_group_by_custom.Group,examples.queries.query_group_by_custom.Third))]\n [Position { x: 4.0, y: 4.0 }]\n\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_group_iter.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "All tables\ngroup: \"::examples::queries::query_group_iter::Cell_0_0\" - Table [examples.queries.query_group_iter.Merchant, examples.queries.query_group_iter.Npc, (examples.queries.query_group_iter.WorldCell,examples.queries.query_group_iter.Cell_0_0)]\ngroup: \"::examples::queries::query_group_iter::Cell_0_1\" - Table [examples.queries.query_group_iter.Npc, examples.queries.query_group_iter.Beggar, (examples.queries.query_group_iter.WorldCell,examples.queries.query_group_iter.Cell_0_1)]\ngroup: \"::examples::queries::query_group_iter::Cell_0_1\" - Table [examples.queries.query_group_iter.Npc, examples.queries.query_group_iter.Soldier, (examples.queries.query_group_iter.WorldCell,examples.queries.query_group_iter.Cell_0_1)]\ngroup: \"::examples::queries::query_group_iter::Cell_1_0\" - Table [examples.queries.query_group_iter.Npc, examples.queries.query_group_iter.Mage, (examples.queries.query_group_iter.WorldCell,examples.queries.query_group_iter.Cell_1_0)]\ngroup: \"::examples::queries::query_group_iter::Cell_1_0\" - Table [examples.queries.query_group_iter.Npc, examples.queries.query_group_iter.Beggar, (examples.queries.query_group_iter.WorldCell,examples.queries.query_group_iter.Cell_1_0)]\ngroup: \"::examples::queries::query_group_iter::Cell_1_1\" - Table [examples.queries.query_group_iter.Npc, examples.queries.query_group_iter.Soldier, (examples.queries.query_group_iter.WorldCell,examples.queries.query_group_iter.Cell_1_1)]\n\nTables for cell 1_0:\ngroup: \"::examples::queries::query_group_iter::Cell_1_0\" - Table [examples.queries.query_group_iter.Npc, examples.queries.query_group_iter.Mage, (examples.queries.query_group_iter.WorldCell,examples.queries.query_group_iter.Cell_1_0)]\ngroup: \"::examples::queries::query_group_iter::Cell_1_0\" - Table [examples.queries.query_group_iter.Npc, examples.queries.query_group_iter.Beggar, (examples.queries.query_group_iter.WorldCell,examples.queries.query_group_iter.Cell_1_0)]\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_hierarchy.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Entity Sun is at (1, 1)\nEntity Mercury is at (2, 2)\nEntity Venus is at (3, 3)\nEntity Earth is at (4, 4)\nEntity Moon is at (4.1, 4.1)\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_pass_query_to_system.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Position { x: 1, y: 2 }, Velocity { x: 590, y: 20 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_run_iter.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "\nTable: Some(examples.queries.query_run.Position, examples.queries.query_run.Velocity, (Identifier,Name))\n - number of entities: 2\n\n - term 0 : \n - component: examples.queries.query_run.Position\n - type size: 8\n - term 1 : \n - component: examples.queries.query_run.Velocity\n - type size: 8\n\n - entity e1: has Position { x: 11.0, y: 22.0 }\n - entity e2: has Position { x: 13.0, y: 24.0 }\n\n\nTable: Some(examples.queries.query_run.Position, examples.queries.query_run.Velocity, examples.queries.query_run.Mass, (Identifier,Name))\n - number of entities: 1\n\n - term 0 : \n - component: examples.queries.query_run.Position\n - type size: 8\n - term 1 : \n - component: examples.queries.query_run.Velocity\n - type size: 8\n\n - entity e3: has Position { x: 14.0, y: 25.0 }\n\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_setting_variables.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Unit [ID] of class examples.queries.query_setting_variables.Wizard in platoon [ID] for player MyPlayer\nUnit [ID] of class examples.queries.query_setting_variables.Wizard in platoon [ID] for player MyPlayer\nUnit [ID] of class examples.queries.query_setting_variables.Wizard in platoon [ID] for player MyPlayer\nUnit [ID] of class examples.queries.query_setting_variables.Marksman in platoon [ID] for player MyPlayer\nUnit [ID] of class examples.queries.query_setting_variables.Marksman in platoon [ID] for player MyPlayer\nUnit [ID] of class examples.queries.query_setting_variables.Marksman in platoon [ID] for player MyPlayer\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_singleton.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Entity ::e1 has Velocity { x: 0.0, y: 9.81 }\nEntity ::e2 has Velocity { x: 0.0, y: 10.81 }\nEntity ::e3 has Velocity { x: 0.0, y: 11.81 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_sorting.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "\n--- First iteration ---\nPosition { x: 1.0, y: 0.0 }\nPosition { x: 2.0, y: 0.0 }\nPosition { x: 4.0, y: 0.0 }\nPosition { x: 5.0, y: 0.0 }\nPosition { x: 6.0, y: 0.0 }\n\n--- Second iteration ---\nPosition { x: 2.0, y: 0.0 }\nPosition { x: 4.0, y: 0.0 }\nPosition { x: 5.0, y: 0.0 }\nPosition { x: 6.0, y: 0.0 }\nPosition { x: 7.0, y: 0.0 }\n\n--- System iteration ---\nPosition { x: 2.0, y: 0.0 }\nPosition { x: 3.0, y: 0.0 }\nPosition { x: 4.0, y: 0.0 }\nPosition { x: 5.0, y: 0.0 }\nPosition { x: 6.0, y: 0.0 }\nPosition { x: 7.0, y: 0.0 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_transitive_queries.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Bob lives in UnitedStates\nAlice lives in UnitedStates\nJob lives in Netherlands\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_variables.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Bob eats Apples\nAlice eats Apples\nAlice eats Salad\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_wildcard.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Alice eats 4 Apples\nBob eats 10 Apples\nBob eats 5 Pears\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_with.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Entity e1: Position { x: 10.0, y: 20.0 }\nEntity e2: Position { x: 10.0, y: 20.0 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_without.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Entity e1: Position { x: 10.0, y: 20.0 }\nEntity e2: Position { x: 10.0, y: 20.0 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@query_world_query.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Entity e1: Position { x: 11.0, y: 22.0 }\nEntity e2: Position { x: 13.0, y: 24.0 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_basics.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Position: {x: 2, y: 4}\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_basics_json.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Position: {\"x\":2, \"y\":4}\nEntity: {\"name\":\"#[ID] \", \"components\":{\"examples.reflection.reflection_basics_json.Position\":{\"x\":2, \"y\":4}}}\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_basics_simple_enum.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "TypeWithEnum: {color: Green}\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_bitmask.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "{toppings: lettuce|bacon}\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_deserialize.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "{x: 10, y: 20}\n{x: 20, y: 10}\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_nested_set_member.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "{start: {x: 10, y: 20}, stop: {x: 30, y: 40}}\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_nested_struct.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "{start: {x: 10, y: 20}, stop: {x: 30, y: 40}}\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_query_to_custom_json.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "{\"results\":[{\"name\":\"a\", \"fields\":{\"values\":[{\"x\":10, \"y\":20}, {\"x\":1, \"y\":2}]}}, {\"name\":\"b\", \"fields\":{\"values\":[{\"x\":20, \"y\":30}, {\"x\":2, \"y\":3}]}}, {\"name\":\"c\", \"fields\":{\"values\":[{\"x\":30, \"y\":40}, {\"x\":3, \"y\":4}]}}, {\"name\":\"d\", \"fields\":{\"values\":[{\"x\":30, \"y\":40}, {\"x\":4, \"y\":5}]}}]}\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_query_to_json.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "{\"results\":[{\"name\":\"a\", \"fields\":{\"values\":[{\"x\":10, \"y\":20}, {\"x\":1, \"y\":2}]}}, {\"name\":\"b\", \"fields\":{\"values\":[{\"x\":20, \"y\":30}, {\"x\":2, \"y\":3}]}}, {\"name\":\"c\", \"fields\":{\"values\":[{\"x\":30, \"y\":40}, {\"x\":3, \"y\":4}]}}, {\"name\":\"d\", \"fields\":{\"values\":[{\"x\":30, \"y\":40}, {\"x\":4, \"y\":5}]}}]}\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_runtime_component.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "\"{x: 10, y: 20}\"\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_runtime_nested_component.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "\"{start: {x: 10, y: 20}, stop: {x: 30, y: 40}}\"\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_ser_opaque_type.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "\"{\\\"a\\\":10, \\\"b\\\":20, \\\"result\\\":30}\"\n\"{\\\"a\\\":22, \\\"b\\\":20, \\\"result\\\":42}\"\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_ser_std_string.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "\"{\\\"a\\\":\\\"foo\\\", \\\"b\\\":\\\"bar\\\"}\"\nStringComponent { a: \"hello\", b: \"world\" }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_ser_std_vector_builtin_types.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "\"{\\\"ints\\\":[1, 2, 3], \\\"strings\\\":[\\\"foo\\\", \\\"bar\\\"]}\"\n\"{\\\"ints\\\":[4, 5, 3], \\\"strings\\\":[\\\"hello\\\", \\\"flecs\\\", \\\"reflection\\\", \\\"\\\"]}\"\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_ser_std_vector_custom_types.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "\"{\\\"points\\\":[{\\\"x\\\":1, \\\"y\\\":2}, {\\\"x\\\":3, \\\"y\\\":4}], \\\"strings\\\":[\\\"foo\\\", \\\"bar\\\"]}\"\n\"{\\\"points\\\":[{\\\"x\\\":4, \\\"y\\\":5}, {\\\"x\\\":6, \\\"y\\\":7}, {\\\"x\\\":0, \\\"y\\\":0}], \\\"strings\\\":[\\\"hello\\\", \\\"flecs\\\", \\\"reflection\\\", \\\"\\\"]}\"\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@reflection_world_ser_deser.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "{\"results\":[{\"name\":\"ent_1\", \"id\":566, \"components\":{\"examples.reflection.reflection_world_ser_deser.Move.examples.reflection.reflection_world_ser_deser.Position\":{\"x\":10, \"y\":20}, \"examples.reflection.reflection_world_ser_deser.Move.examples.reflection.reflection_world_ser_deser.Velocity\":{\"x\":1, \"y\":-1}}}, {\"name\":\"ent_2\", \"id\":567, \"components\":{\"examples.reflection.reflection_world_ser_deser.Move.examples.reflection.reflection_world_ser_deser.Position\":{\"x\":30, \"y\":40}, \"examples.reflection.reflection_world_ser_deser.Move.examples.reflection.reflection_world_ser_deser.Velocity\":{\"x\":-1, \"y\":1}}}]}\n::ent_1 moved to {x: 11, y: 19}\n::ent_2 moved to {x: 29, y: 41}\n\n::ent_1 moved to {x: 11, y: 19}\n::ent_2 moved to {x: 29, y: 41}\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@relationships_basics.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Bob eats apples? true\nBob grows food? true, true\n\nBob's type: [(Identifier,Name), (examples.relationships.relationships_basics.Eats,Apples), (examples.relationships.relationships_basics.Eats,Pears), (Grows,Pears)]\n\nBob eats Apples\nBob eats Pears\n\nBob Eats pears\nBob Grows pears\n\nBob eats Apples\nBob also eats Pears\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@relationships_exclusive.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Unit in platoon 1: true\nUnit in platoon 2: false\n\nUnit in platoon 1: false\nUnit in platoon 2: true\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@relationships_symmetric.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Player 1 trades with Player 2: true\nPlayer 2 trades with Player 1: true\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@relationships_union.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "e3: Movement: \"Walking\", Direction: \"Back\"\ne1: Movement: \"Walking\", Direction: \"Front\"\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@system_basics.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "e1: { 11, 22 }\ne2: { 13, 24 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@system_custom_phases.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "system GameSystem\nsystem PhysicsSystem\nsystem CollisionSystem\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@system_custom_phases_no_builtin.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "system GameSystem\nsystem PhysicsSystem\nsystem CollisionSystem\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@system_custom_pipeline.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "System with Physics ran!\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@system_custom_runner.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Move begin\ne1: { 11, 22 }\ne2: { 13, 24 }\nMove end\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@system_pipeline.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "e1: { 11, 22 }\ne2: { 13, 24 }\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/examples/flecs/z_ignore_test_snapshots/test@system_startup_system.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: flecs_ecs/examples/flecs/z_ignore_test_common.rs 3 | expression: str_output 4 | --- 5 | "Startup\nUpdate\nUpdate\n" 6 | -------------------------------------------------------------------------------- /flecs_ecs/src/addons/alerts/module.rs: -------------------------------------------------------------------------------- 1 | use crate::{addons::metrics::MetricsModule, core::World, prelude::Module}; 2 | use flecs_ecs_derive::Component; 3 | 4 | #[derive(Clone, Copy, Component, Default)] 5 | pub struct AlertsModule; 6 | 7 | impl Module for AlertsModule { 8 | fn module(world: &World) { 9 | world.import::(); 10 | 11 | world.module::("::flecs::alerts"); 12 | 13 | // Import C module 14 | unsafe { flecs_ecs_sys::FlecsAlertsImport(world.ptr_mut()) }; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /flecs_ecs/src/addons/alerts/types.rs: -------------------------------------------------------------------------------- 1 | use core::ops::Deref; 2 | use core::ptr::addr_of; 3 | 4 | use crate::addons::create_pre_registered_extern_component; 5 | use crate::core::*; 6 | use crate::sys; 7 | use flecs_ecs_sys::*; //for all the alerts 8 | 9 | pub trait SeverityAlert {} 10 | 11 | create_pre_registered_extern_component!( 12 | Alert, 13 | FLECS_IDEcsAlertID_, 14 | "Component added to alert, and used as first element of alert severity pair." 15 | ); 16 | 17 | create_pre_registered_extern_component!(Info, EcsAlertInfo, "Info alert severity."); 18 | create_pre_registered_extern_component!(Warning, EcsAlertWarning, "Warning alert severity."); 19 | create_pre_registered_extern_component!(Error, EcsAlertError, "Error alert severity."); 20 | create_pre_registered_extern_component!(Critical, EcsAlertCritical, "Critical alert severity."); 21 | 22 | impl SeverityAlert for Info {} 23 | impl SeverityAlert for Warning {} 24 | impl SeverityAlert for Error {} 25 | impl SeverityAlert for Critical {} 26 | 27 | create_pre_registered_extern_component!( 28 | AlertsActive, 29 | FLECS_IDEcsAlertsActiveID_, 30 | "Component added to alert source which tracks how many active alerts there are." 31 | ); 32 | create_pre_registered_extern_component!( 33 | AlertInstance, 34 | FLECS_IDEcsAlertInstanceID_, 35 | "Component added to alert instance." 36 | ); 37 | create_pre_registered_extern_component!( 38 | AlertTimeout, 39 | FLECS_IDEcsAlertTimeoutID_, 40 | "Component added to alert which tracks how long an alert has been inactive." 41 | ); 42 | -------------------------------------------------------------------------------- /flecs_ecs/src/addons/meta/impl_bindings.rs: -------------------------------------------------------------------------------- 1 | use flecs_ecs::prelude::*; 2 | use flecs_ecs::sys; 3 | 4 | use super::Opaque; 5 | 6 | unsafe impl Send for Opaque<'static, T> {} 7 | 8 | unsafe impl Sync for Opaque<'static, T> {} 9 | 10 | impl FlecsConstantId for Opaque<'static, T> { 11 | const ID: u64 = ECS_OPAQUE; 12 | } 13 | 14 | impl TagComponent for Opaque<'static, T> {} 15 | 16 | impl ComponentType for Opaque<'static, T> {} 17 | 18 | impl ComponentInfo for Opaque<'static, T> { 19 | const IS_ENUM: bool = false; 20 | const IS_TAG: bool = false; 21 | type TagType = FlecsFirstIsNotATag; 22 | const IMPLS_CLONE: bool = true; 23 | const IMPLS_DEFAULT: bool = true; 24 | const IS_REF: bool = false; 25 | const IS_MUT: bool = false; 26 | const IS_GENERIC: bool = true; 27 | } 28 | 29 | impl ComponentId for Opaque<'static, T> { 30 | type UnderlyingType = Opaque<'static, T>; 31 | type UnderlyingEnumType = NoneEnum; 32 | 33 | fn __register_lifecycle_hooks(_type_hooks: &mut sys::ecs_type_hooks_t) {} 34 | fn __register_default_hooks(_type_hooks: &mut sys::ecs_type_hooks_t) {} 35 | fn __register_clone_hooks(_type_hooks: &mut sys::ecs_type_hooks_t) {} 36 | 37 | #[inline(always)] 38 | fn index() -> u32 { 39 | static INDEX: core::sync::atomic::AtomicU32 = core::sync::atomic::AtomicU32::new(u32::MAX); 40 | Self::get_or_init_index(&INDEX) 41 | } 42 | 43 | fn __register_or_get_id<'a, const MANUAL_REGISTRATION_CHECK: bool>( 44 | _world: impl WorldProvider<'a>, 45 | ) -> sys::ecs_entity_t { 46 | ECS_OPAQUE 47 | } 48 | 49 | fn __register_or_get_id_named<'a, const MANUAL_REGISTRATION_CHECK: bool>( 50 | _world: impl WorldProvider<'a>, 51 | _name: &str, 52 | ) -> sys::ecs_entity_t { 53 | ECS_OPAQUE 54 | } 55 | 56 | fn is_registered_with_world<'a>(_: impl WorldProvider<'a>) -> bool { 57 | true 58 | } 59 | 60 | fn id<'a>(_world: impl WorldProvider<'a>) -> sys::ecs_id_t { 61 | ECS_OPAQUE 62 | } 63 | } 64 | 65 | impl OnComponentRegistration for Opaque<'static, T> { 66 | fn on_component_registration(_world: WorldRef, _component_id: Entity) {} 67 | } 68 | -------------------------------------------------------------------------------- /flecs_ecs/src/addons/meta/macros/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod macro_component; 2 | pub mod macro_meta_register_vector; 3 | 4 | pub use macro_component::*; 5 | pub use macro_meta_register_vector::*; 6 | -------------------------------------------------------------------------------- /flecs_ecs/src/addons/meta/meta_traits.rs: -------------------------------------------------------------------------------- 1 | use super::Count; 2 | 3 | /// Meant to be used with `.member` method of (untyped) components. 4 | /// This is to allow an unified function API to allow arbitrary number of arguments. 5 | /// valid options are (name : &'static str,), (name: &'static str, count: i32), (name: &'static str, count: i32, offset: i32) 6 | pub trait MetaMember: 'static { 7 | /// Whether to use explicit offset or not 8 | /// when false, flecs calculates the offset for us, this is useful for simple structs. 9 | /// but might fail for more complex structs. 10 | const USE_OFFSET: bool; 11 | 12 | fn name(&self) -> &str; 13 | fn count(&self) -> i32; 14 | fn offset(&self) -> i32; 15 | } 16 | 17 | impl MetaMember for &'static str { 18 | const USE_OFFSET: bool = false; 19 | 20 | #[inline(always)] 21 | fn name(&self) -> &str { 22 | self 23 | } 24 | 25 | #[inline(always)] 26 | fn count(&self) -> i32 { 27 | 0 28 | } 29 | 30 | #[inline(always)] 31 | fn offset(&self) -> i32 { 32 | 0 33 | } 34 | } 35 | 36 | impl MetaMember for (&'static str,) { 37 | const USE_OFFSET: bool = false; 38 | 39 | #[inline(always)] 40 | fn name(&self) -> &str { 41 | self.0 42 | } 43 | 44 | #[inline(always)] 45 | fn count(&self) -> i32 { 46 | 0 47 | } 48 | 49 | #[inline(always)] 50 | fn offset(&self) -> i32 { 51 | 0 52 | } 53 | } 54 | 55 | impl MetaMember for (&'static str, Count) { 56 | const USE_OFFSET: bool = false; 57 | 58 | #[inline(always)] 59 | fn name(&self) -> &str { 60 | self.0 61 | } 62 | 63 | #[inline(always)] 64 | fn count(&self) -> i32 { 65 | self.1.0 66 | } 67 | 68 | #[inline(always)] 69 | fn offset(&self) -> i32 { 70 | 0 71 | } 72 | } 73 | 74 | impl MetaMember for (&'static str, Count, usize) { 75 | const USE_OFFSET: bool = true; 76 | 77 | #[inline(always)] 78 | fn name(&self) -> &str { 79 | self.0 80 | } 81 | 82 | #[inline(always)] 83 | fn count(&self) -> i32 { 84 | self.1.0 85 | } 86 | 87 | #[inline(always)] 88 | fn offset(&self) -> i32 { 89 | self.2 as i32 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /flecs_ecs/src/addons/metrics/module.rs: -------------------------------------------------------------------------------- 1 | use flecs_ecs_derive::Component; 2 | 3 | use crate::{core::World, prelude::Module}; 4 | 5 | #[derive(Clone, Copy, Component, Default)] 6 | pub struct MetricsModule; 7 | 8 | impl Module for MetricsModule { 9 | fn module(world: &World) { 10 | world.module::("::flecs::metrics"); 11 | unsafe { flecs_ecs_sys::FlecsMetricsImport(world.ptr_mut()) }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /flecs_ecs/src/addons/metrics/types.rs: -------------------------------------------------------------------------------- 1 | use core::ops::Deref; 2 | use core::ptr::addr_of; 3 | 4 | use crate::addons::create_pre_registered_extern_component; 5 | use crate::core::*; 6 | use crate::sys; 7 | use flecs_ecs_sys::*; //for all the metrics 8 | 9 | pub trait MetricKind {} 10 | 11 | create_pre_registered_extern_component!( 12 | Value, 13 | FLECS_IDEcsMetricValueID_, 14 | "Component with metric instance value." 15 | ); 16 | 17 | create_pre_registered_extern_component!( 18 | MetricInstance, 19 | EcsMetricInstance, 20 | "Tag added to metric instances." 21 | ); 22 | create_pre_registered_extern_component!( 23 | Metric, 24 | EcsMetric, 25 | "Tag added to metrics, and used as first element of metric kind pair." 26 | ); 27 | create_pre_registered_extern_component!( 28 | Counter, 29 | EcsCounter, 30 | "Metric that has monotonically increasing value." 31 | ); 32 | create_pre_registered_extern_component!( 33 | CounterIncrement, 34 | EcsCounterIncrement, 35 | "Counter metric that is auto-incremented by source value." 36 | ); 37 | create_pre_registered_extern_component!( 38 | CounterId, 39 | EcsCounterId, 40 | "Counter metric that counts the number of entities with an id." 41 | ); 42 | create_pre_registered_extern_component!(Gauge, EcsGauge, "Metric that represents current value."); 43 | 44 | impl MetricKind for Value {} 45 | impl MetricKind for MetricInstance {} 46 | impl MetricKind for Metric {} 47 | impl MetricKind for Counter {} 48 | impl MetricKind for CounterIncrement {} 49 | impl MetricKind for CounterId {} 50 | impl MetricKind for Gauge {} 51 | -------------------------------------------------------------------------------- /flecs_ecs/src/addons/pipeline/mod.rs: -------------------------------------------------------------------------------- 1 | //! Pipelines order and schedule systems for execution. 2 | 3 | mod pipeline_builder; 4 | pub use pipeline_builder::*; 5 | 6 | use core::ops::{Deref, DerefMut}; 7 | 8 | use crate::core::*; 9 | use crate::sys; 10 | 11 | /// Pipelines order and schedule systems for execution. 12 | /// 13 | /// These are typically constructed via [`World::pipeline()`]. 14 | pub struct Pipeline<'a, T> 15 | where 16 | T: QueryTuple, 17 | { 18 | entity: EntityView<'a>, 19 | phantom: core::marker::PhantomData, 20 | } 21 | 22 | impl<'a, T> Deref for Pipeline<'a, T> 23 | where 24 | T: QueryTuple, 25 | { 26 | type Target = EntityView<'a>; 27 | 28 | #[inline] 29 | fn deref(&self) -> &Self::Target { 30 | &self.entity 31 | } 32 | } 33 | 34 | impl DerefMut for Pipeline<'_, T> 35 | where 36 | T: QueryTuple, 37 | { 38 | #[inline] 39 | fn deref_mut(&mut self) -> &mut Self::Target { 40 | &mut self.entity 41 | } 42 | } 43 | 44 | impl<'a, T> From> for EntityView<'a> 45 | where 46 | T: QueryTuple, 47 | { 48 | fn from(pipeline: Pipeline<'a, T>) -> Self { 49 | pipeline.entity 50 | } 51 | } 52 | 53 | impl<'a, T> From> for Entity 54 | where 55 | T: QueryTuple, 56 | { 57 | fn from(pipeline: Pipeline<'a, T>) -> Self { 58 | pipeline.id 59 | } 60 | } 61 | 62 | impl<'a, T> Pipeline<'a, T> 63 | where 64 | T: QueryTuple, 65 | { 66 | /// Create a new pipeline. 67 | /// 68 | /// # Arguments 69 | /// 70 | /// * `world` - The world to create the pipeline in. 71 | /// * `desc` - The pipeline description. 72 | pub(crate) fn new(world: impl WorldProvider<'a>, desc: sys::ecs_pipeline_desc_t) -> Self { 73 | let entity = EntityView::new(world.world()); 74 | let mut pipeline = Self { 75 | entity, 76 | phantom: Default::default(), 77 | }; 78 | pipeline.id = Entity(unsafe { sys::ecs_pipeline_init(world.world_ptr_mut(), &desc) }); 79 | 80 | if pipeline.id == 0 { 81 | ecs_abort!(FlecsErrorCode::InvalidParameter); 82 | } 83 | 84 | pipeline 85 | } 86 | 87 | pub fn entity(&self) -> EntityView<'a> { 88 | self.entity 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /flecs_ecs/src/addons/system/system_runner_fluent.rs: -------------------------------------------------------------------------------- 1 | //! System module implementation 2 | use core::ffi::c_void; 3 | 4 | use crate::core::*; 5 | use crate::sys; 6 | 7 | pub struct SystemRunnerFluent<'a> { 8 | stage: WorldRef<'a>, 9 | id: sys::ecs_entity_t, 10 | stage_current: i32, 11 | stage_count: i32, 12 | offset: i32, 13 | limit: i32, 14 | delta_time: FTime, 15 | param: *mut c_void, 16 | } 17 | 18 | impl<'a> SystemRunnerFluent<'a> { 19 | /// Create a new system runner fluent interface 20 | pub fn new( 21 | world: impl WorldProvider<'a>, 22 | id: impl Into, 23 | stage_current: i32, 24 | stage_count: i32, 25 | delta_time: FTime, 26 | param: *mut c_void, 27 | ) -> Self { 28 | Self { 29 | stage: world.world(), 30 | id: *id.into(), 31 | stage_current, 32 | stage_count, 33 | offset: 0, 34 | limit: 0, 35 | delta_time, 36 | param, 37 | } 38 | } 39 | 40 | /// Set the offset 41 | pub fn set_offset(&mut self, offset: i32) -> &mut Self { 42 | self.offset = offset; 43 | self 44 | } 45 | 46 | /// Set the limit 47 | pub fn set_limit(&mut self, limit: i32) -> &mut Self { 48 | self.limit = limit; 49 | self 50 | } 51 | 52 | /// Set the stage 53 | pub fn set_stage(&mut self, stage: impl WorldProvider<'a>) -> &mut Self { 54 | self.stage = stage.world(); 55 | self 56 | } 57 | } 58 | 59 | impl Drop for SystemRunnerFluent<'_> { 60 | fn drop(&mut self) { 61 | if self.stage_count != 0 { 62 | unsafe { 63 | sys::ecs_run_worker( 64 | self.stage.world_ptr_mut(), 65 | self.id, 66 | self.stage_current, 67 | self.stage_count, 68 | self.delta_time, 69 | self.param, 70 | ); 71 | } 72 | } else { 73 | unsafe { 74 | sys::ecs_run( 75 | self.stage.world_ptr_mut(), 76 | self.id, 77 | self.delta_time, 78 | self.param, 79 | ); 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /flecs_ecs/src/addons/units/mod.rs: -------------------------------------------------------------------------------- 1 | mod types; 2 | pub use types::*; 3 | 4 | use super::module::Module; 5 | use crate::core::World; 6 | use flecs_ecs_derive::Component; 7 | 8 | #[derive(Clone, Copy, Component, Default)] 9 | pub struct UnitsModule; 10 | 11 | impl Module for UnitsModule { 12 | fn module(world: &World) { 13 | world.module::("::flecs::units"); 14 | unsafe { flecs_ecs_sys::FlecsUnitsImport(world.ptr_mut()) }; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /flecs_ecs/src/core/builder.rs: -------------------------------------------------------------------------------- 1 | #![doc(hidden)] 2 | 3 | pub trait Builder<'a> { 4 | type BuiltType; 5 | 6 | fn build(&mut self) -> Self::BuiltType; 7 | } 8 | -------------------------------------------------------------------------------- /flecs_ecs/src/core/component_registration/mod.rs: -------------------------------------------------------------------------------- 1 | //! Contains types and traits that define what a component is and how it is registered. 2 | 3 | mod helpers; 4 | mod registration; 5 | pub mod registration_traits; 6 | pub mod registration_types; 7 | 8 | pub(crate) use helpers::*; 9 | #[doc(hidden)] 10 | pub use registration::*; 11 | #[doc(hidden)] 12 | pub use registration_traits::*; 13 | #[doc(hidden)] 14 | pub use registration_types::*; 15 | -------------------------------------------------------------------------------- /flecs_ecs/src/core/components/component_binding.rs: -------------------------------------------------------------------------------- 1 | #![doc(hidden)] 2 | use core::ffi::c_void; 3 | 4 | type EcsCtxFreeT = unsafe extern "C" fn(*mut c_void); 5 | 6 | pub(crate) struct ComponentBindingCtx { 7 | pub(crate) on_add: Option<*mut c_void>, 8 | pub(crate) on_remove: Option<*mut c_void>, 9 | pub(crate) on_set: Option<*mut c_void>, 10 | pub(crate) free_on_add: Option, 11 | pub(crate) free_on_remove: Option, 12 | pub(crate) free_on_set: Option, 13 | } 14 | 15 | impl Drop for ComponentBindingCtx { 16 | fn drop(&mut self) { 17 | if std::thread::panicking() { 18 | return; 19 | } 20 | 21 | if let Some(on_add) = self.on_add { 22 | if let Some(free_on_add) = self.free_on_add { 23 | unsafe { free_on_add(on_add) }; 24 | } 25 | } 26 | if let Some(on_remove) = self.on_remove { 27 | if let Some(free_on_remove) = self.free_on_remove { 28 | unsafe { free_on_remove(on_remove) }; 29 | } 30 | } 31 | if let Some(on_set) = self.on_set { 32 | if let Some(free_on_set) = self.free_on_set { 33 | unsafe { free_on_set(on_set) }; 34 | } 35 | } 36 | } 37 | } 38 | 39 | #[allow(clippy::derivable_impls)] 40 | impl Default for ComponentBindingCtx { 41 | fn default() -> Self { 42 | Self { 43 | on_add: None, 44 | on_remove: None, 45 | on_set: None, 46 | free_on_add: None, 47 | free_on_remove: None, 48 | free_on_set: None, 49 | } 50 | } 51 | } 52 | impl ComponentBindingCtx { 53 | pub(crate) fn new( 54 | on_add: Option<*mut c_void>, 55 | on_remove: Option<*mut c_void>, 56 | on_set: Option<*mut c_void>, 57 | free_on_add: Option, 58 | free_on_remove: Option, 59 | free_on_set: Option, 60 | ) -> Self { 61 | Self { 62 | on_add, 63 | on_remove, 64 | on_set, 65 | free_on_add, 66 | free_on_remove, 67 | free_on_set, 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /flecs_ecs/src/core/components/mod.rs: -------------------------------------------------------------------------------- 1 | //! Contains types that represents components and a fast mechanism for caching access to them from an entity. 2 | 3 | mod cached_ref; 4 | mod component; 5 | mod component_binding; 6 | mod component_untyped; 7 | #[doc(hidden)] 8 | pub mod lifecycle_traits; 9 | 10 | pub use cached_ref::*; 11 | pub use component::*; 12 | pub(crate) use component_binding::*; 13 | pub use component_untyped::*; 14 | #[doc(hidden)] 15 | pub use lifecycle_traits::*; 16 | -------------------------------------------------------------------------------- /flecs_ecs/src/core/entity_view/mod.rs: -------------------------------------------------------------------------------- 1 | //! `EntityViews` are wrappers around an [`Entity`][super::Entity] id with the world. It provides methods to build and interact with entities. 2 | 3 | mod bulk_entity_builder; 4 | mod entity_view_const; 5 | mod entity_view_impl; 6 | mod entity_view_mut; 7 | mod macros; 8 | 9 | pub use entity_view_const::EntityView; 10 | pub use entity_view_const::EntityViewGet; 11 | -------------------------------------------------------------------------------- /flecs_ecs/src/core/mod.rs: -------------------------------------------------------------------------------- 1 | mod archetype; 2 | pub mod builder; 3 | pub mod c_types; 4 | pub(crate) mod cloned_tuple; 5 | pub mod component_registration; 6 | mod components; 7 | pub mod ecs_os_api; 8 | mod entity; 9 | mod entity_view; 10 | mod event; 11 | pub mod flecs; 12 | pub(crate) mod get_tuple; 13 | pub mod id; 14 | mod id_view; 15 | mod observer; 16 | mod observer_builder; 17 | mod query; 18 | pub mod query_builder; 19 | mod query_iter; 20 | pub(crate) mod query_tuple; 21 | pub mod table; 22 | pub mod term; 23 | pub mod utility; 24 | mod world; 25 | pub(crate) mod world_ctx; 26 | 27 | pub use archetype::Archetype; 28 | #[doc(hidden)] 29 | pub use builder::*; 30 | #[doc(hidden)] 31 | pub use c_types::*; 32 | pub(crate) use cloned_tuple::*; 33 | #[doc(hidden)] 34 | pub use component_registration::*; 35 | #[doc(inline)] 36 | pub use components::*; 37 | pub use entity::Entity; 38 | pub use entity_view::EntityView; 39 | pub use entity_view::EntityViewGet; 40 | pub use event::EventBuilder; 41 | pub(crate) use get_tuple::*; 42 | pub use id::Id; 43 | pub use id_view::IdView; 44 | pub use observer::Observer; 45 | pub use observer_builder::ObserverBuilder; 46 | pub use query::Query; 47 | #[doc(hidden)] 48 | pub use query_builder::*; 49 | pub use query_iter::QueryIter; 50 | #[doc(hidden)] 51 | pub use query_tuple::*; 52 | #[doc(hidden)] 53 | pub use table::*; 54 | #[doc(hidden)] 55 | pub use term::*; 56 | #[doc(hidden)] 57 | pub use utility::*; 58 | pub(crate) use world::FlecsArray; 59 | pub use world::World; 60 | pub use world::WorldGet; 61 | pub(crate) use world_ctx::*; 62 | -------------------------------------------------------------------------------- /flecs_ecs/src/core/utility/id.rs: -------------------------------------------------------------------------------- 1 | use crate::core::ComponentId; 2 | 3 | impl Clone for Id { 4 | fn clone(&self) -> Self { 5 | *self 6 | } 7 | } 8 | 9 | impl Copy for Id {} 10 | 11 | #[derive(Debug)] 12 | pub struct Id { 13 | _marker: core::marker::PhantomData, 14 | } 15 | 16 | #[inline(always)] 17 | pub const fn id() -> Id { 18 | Id::new() 19 | } 20 | 21 | impl Id { 22 | #[inline(always)] 23 | pub(crate) const fn new() -> Self { 24 | Id { 25 | _marker: core::marker::PhantomData, 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /flecs_ecs/src/core/utility/id_map.rs: -------------------------------------------------------------------------------- 1 | use core::any::TypeId; 2 | use core::hash::BuildHasher; 3 | use core::hash::Hasher; 4 | 5 | pub(crate) type FlecsIdMap = hashbrown::HashMap; 6 | 7 | // A hasher for `TypeId`s that takes advantage of its known characteristics. 8 | // TypeIds are already a hash, so we can just use that. 9 | #[derive(Debug, Default)] 10 | #[doc(hidden)] 11 | pub struct NoOpHasher(u64); 12 | 13 | impl Hasher for NoOpHasher { 14 | fn write(&mut self, _: &[u8]) { 15 | unimplemented!("This NoOpHasher can only handle u64s") 16 | } 17 | 18 | fn write_u64(&mut self, i: u64) { 19 | self.0 = i; 20 | } 21 | 22 | fn finish(&self) -> u64 { 23 | self.0 24 | } 25 | } 26 | 27 | // A hasher builder that always returns the same hasher meant for `TypeId`s. 28 | #[derive(Clone, Default)] 29 | pub struct NoOpHash; 30 | 31 | impl BuildHasher for NoOpHash { 32 | type Hasher = NoOpHasher; 33 | 34 | fn build_hasher(&self) -> Self::Hasher { 35 | NoOpHasher(0) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /flecs_ecs/src/core/utility/log.rs: -------------------------------------------------------------------------------- 1 | //! sets various internal logging options 2 | use crate::sys; 3 | 4 | /// Sets the logging level to the specified value. 5 | /// 6 | /// # Arguments 7 | /// 8 | /// * `level` - An integer representing the logging level. 9 | pub fn set_log_level(level: i32) { 10 | unsafe { 11 | sys::ecs_log_set_level(level); 12 | } 13 | } 14 | 15 | /// Returns the current logging level. 16 | /// 17 | /// # Returns 18 | /// 19 | /// An integer representing the current logging level. 20 | pub fn get_log_level() -> i32 { 21 | unsafe { sys::ecs_log_get_level() } 22 | } 23 | 24 | /// Enables or disables colors in logging. 25 | /// 26 | /// # Arguments 27 | /// 28 | /// * `enabled` - A boolean value indicating whether to enable or disable colors. 29 | pub fn enable_color_logging(enabled: bool) { 30 | unsafe { 31 | sys::ecs_log_enable_colors(enabled); 32 | } 33 | } 34 | 35 | /// Enables or disables timestamps in logging. 36 | /// 37 | /// # Arguments 38 | /// 39 | /// * `enabled` - A boolean value indicating whether to enable or disable timestamps. 40 | pub fn enable_timestamp_logging(enabled: bool) { 41 | unsafe { 42 | sys::ecs_log_enable_timestamp(enabled); 43 | } 44 | } 45 | 46 | /// Enables or disables time delta in logging. 47 | /// 48 | /// # Arguments 49 | /// 50 | /// * `enabled` - A boolean value indicating whether to enable or disable time delta. 51 | pub fn enable_timedelta_logging(enabled: bool) { 52 | unsafe { 53 | sys::ecs_log_enable_timedelta(enabled); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /flecs_ecs/src/core/utility/mod.rs: -------------------------------------------------------------------------------- 1 | //! contains traits that define what a component is and also the API's for [`Query`][super::Query], [`Observer`][super::Observer] and [`System`][crate::addons::system::System]. 2 | //! Also contains lower level utility functions on ECS IDs. This is mostly used internally by the library. 3 | 4 | mod errors; 5 | mod functions; 6 | pub mod id; 7 | pub(crate) mod id_map; 8 | mod log; 9 | pub mod traits; 10 | pub mod types; 11 | 12 | pub use errors::*; 13 | pub use functions::*; 14 | pub use id::id; 15 | pub(crate) use id_map::*; 16 | pub use log::*; 17 | 18 | #[doc(hidden)] 19 | pub use traits::*; 20 | #[doc(hidden)] 21 | pub use types::*; 22 | -------------------------------------------------------------------------------- /flecs_ecs/src/core/utility/traits/inout_oper.rs: -------------------------------------------------------------------------------- 1 | #![doc(hidden)] 2 | use crate::core::*; 3 | 4 | /// Represents the operation type of a system in an ECS framework. 5 | /// 6 | /// This trait is used to specify the kind of operation a system performs on a component, 7 | /// such as adding, removing, or setting a component. Implementing this trait allows the ECS 8 | /// framework to understand and optimize the execution of systems based on their operational 9 | /// characteristics. 10 | /// 11 | /// # Associated Constants 12 | /// 13 | /// * `OPER`: The kind of operation (`OperKind`) the system performs. 14 | /// 15 | /// # Associated Types 16 | /// 17 | /// * `Type`: The type of the component data. Must implement `ComponentId`. 18 | pub trait OperType { 19 | const OPER: OperKind; 20 | type Type: ComponentId; 21 | } 22 | 23 | impl OperType for &mut T 24 | where 25 | T: ComponentId, 26 | { 27 | type Type = T; 28 | const OPER: OperKind = OperKind::And; 29 | } 30 | 31 | impl OperType for &T 32 | where 33 | T: ComponentId, 34 | { 35 | type Type = T; 36 | const OPER: OperKind = OperKind::And; 37 | } 38 | 39 | impl OperType for Option<&T> 40 | where 41 | T: ComponentId, 42 | { 43 | type Type = T; 44 | const OPER: OperKind = OperKind::Optional; 45 | } 46 | 47 | impl OperType for Option<&mut T> 48 | where 49 | T: ComponentId, 50 | { 51 | type Type = T; 52 | const OPER: OperKind = OperKind::Optional; 53 | } 54 | -------------------------------------------------------------------------------- /flecs_ecs/src/core/utility/traits/into_table.rs: -------------------------------------------------------------------------------- 1 | use crate::core::*; 2 | use crate::sys; 3 | 4 | pub trait IntoTable { 5 | fn table_ptr_mut(&self) -> *mut sys::ecs_table_t; 6 | } 7 | 8 | impl IntoTable for *mut sys::ecs_table_t { 9 | #[inline] 10 | fn table_ptr_mut(&self) -> *mut sys::ecs_table_t { 11 | *self 12 | } 13 | } 14 | 15 | impl IntoTable for *const sys::ecs_table_t { 16 | #[inline] 17 | fn table_ptr_mut(&self) -> *mut sys::ecs_table_t { 18 | *self as *mut sys::ecs_table_t 19 | } 20 | } 21 | 22 | impl IntoTable for Table<'_> { 23 | #[inline] 24 | fn table_ptr_mut(&self) -> *mut sys::ecs_table_t { 25 | self.table.as_ptr() 26 | } 27 | } 28 | 29 | impl IntoTable for TableRange<'_> { 30 | #[inline] 31 | fn table_ptr_mut(&self) -> *mut sys::ecs_table_t { 32 | self.table.table.as_ptr() 33 | } 34 | } 35 | 36 | pub trait IntoTableRange { 37 | fn range(&self) -> TableRange; 38 | fn range_raw(&self) -> sys::ecs_table_range_t; 39 | } 40 | 41 | impl IntoTableRange for TableRange<'_> { 42 | #[inline] 43 | fn range(&self) -> TableRange { 44 | *self 45 | } 46 | 47 | #[inline] 48 | fn range_raw(&self) -> sys::ecs_table_range_t { 49 | sys::ecs_table_range_t { 50 | table: self.table.table.as_ptr(), 51 | offset: self.offset(), 52 | count: self.count(), 53 | } 54 | } 55 | } 56 | 57 | impl IntoTableRange for Table<'_> { 58 | #[inline] 59 | fn range(&self) -> TableRange { 60 | TableRange::new(*self, 0, self.count()) 61 | } 62 | 63 | #[inline] 64 | fn range_raw(&self) -> sys::ecs_table_range_t { 65 | sys::ecs_table_range_t { 66 | table: self.table.as_ptr(), 67 | offset: 0, 68 | count: self.count(), 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /flecs_ecs/src/decision_reasoning.txt: -------------------------------------------------------------------------------- 1 | 2 | /* Removal of `ScopedWorld`: */ 3 | // `ScopedWorld` was removed because it did not effectively isolate the original world or prevent 4 | // multiple scopes from being created on the same world. Although it implemented `Drop` to end scoping, 5 | // this did not occur until the end of the scope, making it easy to reach unintended states. 6 | // Using a closure instead clearly delineates the start and end of the scope and eliminates the need 7 | // for an extra type, thereby simplifying the code and reducing potential errors. 8 | 9 | /* removing of Term struct & diverging from the CPP implementation */ 10 | // reasoning being that in the cpp implementation, it uses pointers to reference to its own fields, 11 | // which is a painpoint in rust due to invalidation (and rightfully so), hence I saw the need to 12 | // find a better solution, which is an indexed based approach on query (& alike) from the desc itself. 13 | 14 | /* Why Entity and EntityView were merged in the Rust API compared to the C++ API */ 15 | // The merge of Entity and EntityView into `EntityView` was motivated by the lack of any real distinction 16 | // between the two in Rust, meaning most Rust developers wouldn't see a difference. 17 | // In Rust, the term `View` is not familiar as it doesn't align with typical Rust semantics. 18 | // Now, `Entity` is essentially a strongly typed u64 identifier, while `EntityView` acts as a wrapper 19 | // around this identifier, providing added functionality and managing lifetimes. 20 | // The term `EntityView` also indicates that it is not merely an "entity" but rather a reference to the world, wrapped with an ID. 21 | // In Rust, placing an `EntityView` within a struct feels intuitively incorrect because views are 22 | // considered transient and not meant for persistent borrowing; thus, lifetime errors are expected and make sense. 23 | // Developers might naturally lean towards using `Entity` when they want a more permanent reference, 24 | // unaware that `EntityView` can convert into `Entity` via `Into`. 25 | // This restructuring was primarily driven by considerations for improving user experience (UX). 26 | -------------------------------------------------------------------------------- /flecs_ecs/src/prelude.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "flecs_module")] 2 | pub use crate::addons::module::Module; 3 | pub use crate::addons::*; 4 | pub use crate::core::*; 5 | pub use crate::macros::*; 6 | pub use flecs_ecs_sys::EcsComponent; 7 | 8 | #[cfg(feature = "flecs_meta")] 9 | pub use crate::addons::meta::*; 10 | #[cfg(feature = "flecs_meta")] 11 | pub use crate::{component, component_ext, member, member_ext}; 12 | -------------------------------------------------------------------------------- /flecs_ecs/tests/ecs_os_api/main.rs: -------------------------------------------------------------------------------- 1 | //! This test needs to be a separate process, since the OS API is process-global. 2 | 3 | use ecs_os_api::try_add_init_hook; 4 | use flecs_ecs::prelude::*; 5 | 6 | #[test] 7 | fn hooks() { 8 | use core::sync::atomic::{AtomicU32, Ordering}; 9 | use flecs_ecs::prelude::*; 10 | 11 | let n = Box::leak(Box::new(AtomicU32::new(0))); 12 | 13 | try_add_init_hook(Box::new(|_| { 14 | n.fetch_add(1, Ordering::SeqCst); 15 | })) 16 | .unwrap(); 17 | 18 | // Hooks do not run until the first World is created 19 | assert_eq!(n.load(Ordering::SeqCst), 0); 20 | 21 | let _w = World::new(); 22 | 23 | // Hooks should have run now 24 | assert_eq!(n.load(Ordering::SeqCst), 1); 25 | 26 | let _w2 = World::new(); 27 | 28 | // Hooks should only run once 29 | assert_eq!(n.load(Ordering::SeqCst), 1); 30 | 31 | // Late hooks should fail 32 | try_add_init_hook(Box::new(|_| { 33 | n.fetch_add(2, Ordering::SeqCst); 34 | })) 35 | .unwrap_err(); 36 | 37 | // Late hooks should have no effect 38 | assert_eq!(n.load(Ordering::SeqCst), 1); 39 | } 40 | -------------------------------------------------------------------------------- /flecs_ecs/tests/flecs/clone_default_impl_test.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | use flecs_ecs::core::{ComponentInfo, EntityViewGet, World}; 3 | use flecs_ecs_derive::Component; 4 | 5 | // normal structs 6 | #[derive(Component)] 7 | struct NoneCloneDefault; 8 | 9 | #[derive(Default, Clone, Component)] 10 | struct CloneDefault; 11 | 12 | #[derive(Clone, Component)] 13 | struct CloneNoDefault; 14 | 15 | #[derive(Default, Component)] 16 | struct DefaultNoClone; 17 | 18 | // drop structs 19 | #[derive(Component, Default)] 20 | struct DefaultNoCloneDrop { 21 | _data: String, 22 | } 23 | 24 | #[derive(Default, Clone, Component)] 25 | struct CloneDefaultDrop { 26 | data: String, 27 | } 28 | 29 | #[test] 30 | fn compile_time_check_impls_clone_default() { 31 | // we do it this way to avoid the warning of constant bools getting optimized away from clippy in test cases. 32 | let none_clone_default = !NoneCloneDefault::IMPLS_CLONE && !NoneCloneDefault::IMPLS_DEFAULT; 33 | let clone_default = CloneDefault::IMPLS_CLONE && CloneDefault::IMPLS_DEFAULT; 34 | let clone_no_default = CloneNoDefault::IMPLS_CLONE && !CloneNoDefault::IMPLS_DEFAULT; 35 | let default_no_clone = !DefaultNoClone::IMPLS_CLONE && DefaultNoClone::IMPLS_DEFAULT; 36 | 37 | assert!(none_clone_default); 38 | assert!(clone_default); 39 | assert!(clone_no_default); 40 | assert!(default_no_clone); 41 | } 42 | 43 | #[test] 44 | fn copy_hook_implemented_for_drop_types() { 45 | let world = World::new(); 46 | let e_orig = world.entity().set(CloneDefaultDrop { 47 | data: "data".to_string(), 48 | }); 49 | 50 | let entity_cloned = e_orig.duplicate(true); 51 | 52 | e_orig.get::<&CloneDefaultDrop>(|cd| { 53 | entity_cloned.get::<&CloneDefaultDrop>(|cd_cloned| { 54 | assert!(cd.data == cd_cloned.data); 55 | }); 56 | }); 57 | } 58 | 59 | #[test] 60 | #[should_panic( 61 | expected = "DefaultNoClone does not implement Clone and with a duplicate operation it will panic" 62 | )] 63 | #[ignore = "C asserts that world didn't properly end deferring and aborts 64 | the test & thus the test not registering the panic and does not get marked as passed"] 65 | fn copy_hook_not_implemented_for_drop_types() { 66 | let world = World::new(); 67 | let e_orig = world.entity().set(DefaultNoCloneDrop { 68 | _data: "data".to_string(), 69 | }); 70 | 71 | let _entity_cloned = e_orig.duplicate(true); // PANICS 72 | } 73 | -------------------------------------------------------------------------------- /flecs_ecs/tests/flecs/component_lifecycle_test.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | use crate::common_test::*; 3 | 4 | #[test] 5 | fn component_lifecycle_count_in_add_hook() { 6 | let world = World::new(); 7 | 8 | world.set(Count(0)); 9 | 10 | world.component::().on_add(|e, _| { 11 | e.world().get::<&mut Count>(|count| { 12 | count.0 += 1; 13 | }); 14 | }); 15 | 16 | world.entity().set(Position { x: 1, y: 2 }); 17 | 18 | assert_eq!(world.cloned::<&Count>().0, 1); 19 | 20 | world.new_query::<&Position>().each_entity(|e, _| { 21 | e.world().get::<&mut Count>(|count| { 22 | count.0 += 1; 23 | }); 24 | }); 25 | 26 | assert_eq!(world.cloned::<&Count>().0, 2); 27 | } 28 | 29 | #[test] 30 | fn component_lifecycle_count_in_remove_hook() { 31 | let world = World::new(); 32 | 33 | world.set(Count(0)); 34 | 35 | world.component::().on_remove(|e, _| { 36 | e.world().set(Count(e.world().count(id::()))); 37 | }); 38 | 39 | let entity = world.entity().set(Position { x: 1, y: 2 }); 40 | assert_eq!(world.cloned::<&Count>().0, 0); 41 | 42 | entity.destruct(); 43 | assert_eq!(world.cloned::<&Count>().0, 1); 44 | 45 | world.set(Count(0)); 46 | 47 | world.new_query::<&Position>().each_entity(|e, _| { 48 | e.world().get::<&mut Count>(|count| { 49 | count.0 += 1; 50 | }); 51 | }); 52 | 53 | assert_eq!(world.cloned::<&Count>().0, 0); 54 | } 55 | -------------------------------------------------------------------------------- /flecs_ecs/tests/flecs/entity_rust_test.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | 3 | use crate::common_test::*; 4 | 5 | #[test] 6 | fn count_target_ids() { 7 | let world = World::new(); 8 | 9 | let e = world.entity(); 10 | let r = world.entity(); 11 | let o = world.entity(); 12 | 13 | e.add((r, o)); 14 | e.add((r, o)); 15 | 16 | assert_eq!(e.target_id_count(r).unwrap(), 1); 17 | 18 | let e2 = world.entity(); 19 | e2.add((r, o)); 20 | 21 | assert_eq!(e.target_id_count(r).unwrap(), 1); 22 | assert_eq!(e2.target_id_count(r).unwrap(), 1); 23 | 24 | let o2 = world.entity(); 25 | 26 | e.add((r, o2)); 27 | 28 | assert_eq!(e.target_id_count(r).unwrap(), 2); 29 | assert_eq!(e2.target_id_count(r).unwrap(), 1); 30 | } 31 | 32 | #[test] 33 | fn entity_id_reuse() { 34 | let world = World::new(); 35 | 36 | let a = world.entity_named("a"); 37 | let b = world.entity().child_of(a); 38 | let first_archetype = b.archetype().to_string(); 39 | a.destruct(); 40 | 41 | let a = world.entity_named("a"); 42 | let b = world.entity().child_of(a); 43 | assert!( 44 | b.id() > u32::MAX as u64, 45 | "this test is not valid if the id was not reused" 46 | ); 47 | assert_eq!(b.archetype().to_string(), first_archetype); 48 | } 49 | -------------------------------------------------------------------------------- /flecs_ecs/tests/flecs/is_ref_test.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | use flecs_ecs::core::ComponentId; 3 | use flecs_ecs_derive::Component; 4 | 5 | #[derive(Debug, Component)] 6 | pub struct Position { 7 | pub x: i32, 8 | pub y: i32, 9 | } 10 | 11 | fn is_ref(is_ref: bool) { 12 | assert_eq!(is_ref, T::IS_REF); 13 | } 14 | 15 | fn is_mut(is_mut: bool) { 16 | assert_eq!(is_mut, T::IS_MUT); 17 | } 18 | 19 | #[test] 20 | fn test_ref_mut_ref() { 21 | is_ref::(false); 22 | is_mut::(false); 23 | 24 | is_ref::<&Position>(true); 25 | is_mut::<&Position>(false); 26 | 27 | is_ref::<&mut Position>(false); 28 | is_mut::<&mut Position>(true); 29 | } 30 | -------------------------------------------------------------------------------- /flecs_ecs/tests/flecs/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | //! integration tests for the public API of the `flecs_ecs` crate 3 | //! split into a single module due to the benefits it provides. 4 | //! see <`https://matklad.github.io/2021/02/27/delete-cargo-integration-tests.html/`> for more information. 5 | 6 | pub mod common_test; 7 | 8 | mod clone_default_impl_test; 9 | mod component_lifecycle_test; 10 | mod component_test; 11 | mod entity_bulk_rust_test; 12 | mod entity_rust_test; 13 | mod entity_test; 14 | mod enum_test; 15 | mod eq_test; 16 | mod flecs_docs_test; 17 | mod is_ref_test; 18 | mod meta_macro_test; 19 | mod meta_test; 20 | mod meta_test_rust; 21 | mod meta_trait_test; 22 | mod observer_rust_test; 23 | mod observer_test; 24 | mod query_builder_test; 25 | mod query_rust_test; 26 | mod query_test; 27 | mod system_test; 28 | mod world_test; 29 | -------------------------------------------------------------------------------- /flecs_ecs/tests/flecs/observer_rust_test.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | 3 | use flecs_ecs::core::*; 4 | 5 | use crate::common_test::*; 6 | 7 | #[test] 8 | #[should_panic] 9 | fn observer_panic_on_add_1() { 10 | let world = World::new(); 11 | 12 | world 13 | .observer::() 14 | .with(id::<&Position>()) 15 | .each_entity(|_, _| {}); 16 | 17 | world.entity().set(Position { x: 10, y: 20 }); 18 | } 19 | 20 | #[test] 21 | #[should_panic] 22 | fn observer_panic_on_add_2() { 23 | let world = World::new(); 24 | 25 | world 26 | .observer::() 27 | .with(id::<&mut Position>()) 28 | .each_entity(|_, _| {}); 29 | 30 | world.entity().set(Position { x: 10, y: 20 }); 31 | } 32 | 33 | #[test] 34 | #[should_panic] 35 | fn observer_panic_on_add_3() { 36 | let world = World::new(); 37 | 38 | world 39 | .observer::() 40 | .each_entity(|_, _| {}); 41 | 42 | world.entity().set(Position { x: 10, y: 20 }); 43 | } 44 | 45 | #[test] 46 | #[should_panic] 47 | fn observer_panic_on_add_4() { 48 | let world = World::new(); 49 | 50 | world 51 | .observer::() 52 | .each_entity(|_, _| {}); 53 | 54 | world.entity().set(Position { x: 10, y: 20 }); 55 | } 56 | -------------------------------------------------------------------------------- /flecs_ecs/tests/flecs/world_test.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | use flecs_ecs::prelude::*; 3 | use flecs_ecs::sys; 4 | 5 | #[test] 6 | fn world_no_panic_clone_test() { 7 | let world = World::default(); 8 | let world2 = world.clone(); 9 | let _query = world.new_query::<()>(); 10 | core::mem::drop(world); 11 | let _query2 = world2.new_query::<()>(); 12 | } 13 | 14 | #[test] 15 | #[should_panic] 16 | fn world_reset_panic_lingering_world_refs() { 17 | let world = World::default(); 18 | let _world2 = world.clone(); 19 | world.reset(); 20 | } 21 | 22 | #[test] 23 | #[should_panic] 24 | fn world_panic_lingering_query_handles() { 25 | let world = World::default(); 26 | let _query = world.new_query::<()>(); 27 | core::mem::drop(world); 28 | } 29 | 30 | #[test] 31 | #[ignore = "this code is not applicable to rust as it is to cpp, since we deal with copying the world differently"] 32 | fn world_finis_reentrancy() { 33 | #[derive(Debug, Clone, Copy, Component, Default)] 34 | struct A { 35 | a: i32, 36 | } 37 | 38 | let world = World::default(); 39 | 40 | // declare on remove hook for component A: 41 | world.component::().on_remove(|e, _| { 42 | let world = e.world(); 43 | // This code runs on world destroy, since we did not remove this component manually before the world was destroyed. 44 | 45 | // before we make a copy of the world, the refcount has to be 1 since this is the special case where 46 | // we will be copying a world object precisely when the world is being destroyed. 47 | // see world::~world() code and notes. 48 | let hdr = world.ptr_mut() as *mut sys::ecs_header_t; 49 | unsafe { 50 | assert_eq!((*hdr).refcount, 1); 51 | }; 52 | 53 | // obtain the entity's world. This increments the world's hdr refcount 54 | let hdr = e.world().ptr_mut() as *mut sys::ecs_header_t; 55 | 56 | unsafe { 57 | assert_eq!((*hdr).refcount, 2); 58 | } 59 | 60 | // here world_copy object wrapping c world is destroyed 61 | // therefore, world destroy will be called again wreaking havoc. 62 | }); 63 | 64 | world.entity().add(id::()); 65 | 66 | // world will be destroyed here, and hook above will be called. 67 | } 68 | -------------------------------------------------------------------------------- /flecs_ecs_derive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "flecs_ecs_derive" 3 | version = "0.1.0" 4 | edition.workspace = true 5 | license = "MIT" 6 | repository.workspace = true 7 | description = "A procedural macro crate for the Flecs ECS library." 8 | rust-version.workspace = true 9 | 10 | [lib] 11 | proc-macro = true 12 | name = "flecs_ecs_derive" 13 | 14 | [lints] 15 | workspace = true 16 | 17 | [dependencies] 18 | syn = "2.0.101" 19 | quote = "1.0.40" 20 | proc-macro2 = "1.0.95" 21 | 22 | [dev-dependencies] 23 | flecs_ecs = { version = "*", path = "../flecs_ecs" } 24 | 25 | [package.metadata.docs.rs] 26 | rustdoc-args = [ "-Zunstable-options", "--generate-link-to-definition"] 27 | cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"] 28 | 29 | [features] 30 | 31 | flecs_meta = [] 32 | flecs_query_rust_traits = [] 33 | std = [] 34 | default = [] 35 | -------------------------------------------------------------------------------- /flecs_ecs_derive/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Indra de Backere 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 | -------------------------------------------------------------------------------- /flecs_ecs_sys/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Indra de Backere 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 | -------------------------------------------------------------------------------- /flecs_ecs_sys/src/flecs_rust.h: -------------------------------------------------------------------------------- 1 | #include "flecs.h" 2 | 3 | FLECS_API 4 | void* ecs_rust_mut_get_id( 5 | const ecs_world_t *world, 6 | ecs_entity_t entity, 7 | const ecs_record_t* record, 8 | ecs_table_t* table, 9 | ecs_id_t id); 10 | 11 | FLECS_API 12 | void* ecs_rust_get_id( 13 | const ecs_world_t *world, 14 | ecs_entity_t entity, 15 | const ecs_record_t* record, 16 | ecs_table_t* table, 17 | ecs_id_t id); 18 | 19 | FLECS_API 20 | int32_t ecs_rust_rel_count( 21 | const ecs_world_t *world, 22 | ecs_id_t id, 23 | ecs_table_t* table); 24 | 25 | -------------------------------------------------------------------------------- /flecs_ecs_sys/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Raw FFI bindings to the [`flecs`] library. 2 | //! 3 | //! These are only intended for use by the higher level bindings that build atop these. 4 | //! 5 | //! [`flecs`]: https://www.flecs.dev/ 6 | 7 | #[cfg(all(feature = "force_build_release", feature = "force_build_debug"))] 8 | compile_error!( 9 | "Features 'force_build_release' and 'force_build_debug' cannot be enabled at the same time." 10 | ); 11 | 12 | mod bindings; 13 | mod extensions; 14 | mod mbindings; 15 | 16 | pub use bindings::*; 17 | pub use mbindings::*; 18 | -------------------------------------------------------------------------------- /flecs_ecs_sys/tests/check_for_changes.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn query_flags() { 3 | assert_eq!(flecs_ecs_sys::EcsQueryMatchPrefab, 2); 4 | assert_eq!(flecs_ecs_sys::EcsQueryMatchDisabled, 4); 5 | assert_eq!(flecs_ecs_sys::EcsQueryMatchEmptyTables, 8); 6 | assert_eq!(flecs_ecs_sys::EcsQueryAllowUnresolvedByName, 64); 7 | assert_eq!(flecs_ecs_sys::EcsQueryTableOnly, 128); 8 | } 9 | -------------------------------------------------------------------------------- /scripts/fbench_log.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cargo criterion --plotting-backend disabled 2>&1 | tee ${CARGO_MAKE_WORKING_DIRECTORY}/flecs_ecs/benches/fbench_log/bench.log 4 | ./filter_bench_log.sh -------------------------------------------------------------------------------- /scripts/filter_bench_log.sh: -------------------------------------------------------------------------------- 1 | awk '{ 2 | if (/time:/) { 3 | gsub(/^[ \t]+|[ \t]+$/, "", prev); 4 | gsub(/[ \t]+/, " ", $0); 5 | split($0, a, " "); 6 | if (a[1] != "time:") { 7 | title = a[1]; 8 | unit = a[4]; 9 | timing = a[5]; 10 | } else { 11 | title = prev; 12 | unit = a[3]; 13 | timing = a[4]; 14 | } 15 | title_width = 50; 16 | padding = title_width - length(title); 17 | printf "%-*s %s %s\n", title_width, title, timing, unit; 18 | } 19 | prev=$0 20 | }' ${CARGO_MAKE_WORKING_DIRECTORY}/flecs_ecs/benches/fbench_log/bench.log > ${CARGO_MAKE_WORKING_DIRECTORY}/flecs_ecs/benches/fbench_log/bench_filtered.log 21 | -------------------------------------------------------------------------------- /test_crash_handler/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "test_crash_handler" 3 | version = "0.1.0" 4 | edition.workspace = true 5 | license.workspace = true 6 | repository.workspace = true 7 | rust-version.workspace = true 8 | publish = false 9 | 10 | [dependencies] 11 | crash-handler = { version = "0.6.2", features = ["debug-print"], optional = true } 12 | 13 | [lints] 14 | workspace = true 15 | 16 | [features] 17 | # feature-gated again to protect against workspace builds on unsupported platforms 18 | crash-handler = ["dep:crash-handler"] --------------------------------------------------------------------------------