#ecs #component #bindings #entity #native

flecs

Flecs 实体组件系统(ECS)的 Rust 绑定

6 个版本

0.1.5 2023年10月16日
0.1.4 2023年6月21日
0.1.3 2023年4月17日
0.1.1 2022年8月4日

#73 in 游戏开发

每月下载量 24

MIT 许可证

2.5MB
62K SLoC

C 53K SLoC // 0.1% comments Rust 10K SLoC // 0.0% comments C++ 5 SLoC

flecs-rs: Flecs 的 Rust 绑定

Crates.io license Discord Chat

Flecs ECS 库的 Rust 绑定: https://github.com/SanderMertens/flecs

包装了原生 Flecs v3.2.8

简单示例

use flecs::*;

#[derive(Default, Debug, PartialEq)]
struct Position {
    x: f32,
    y: f32,
}

#[derive(Default, Debug, PartialEq)]
struct Walking { }

fn main() {
    let mut world = World::new();

    // We have to manually register all components
    world.component::<Position>();
    world.component::<Walking>();

    // Create an entity with name Bob
    let bob = world.entity().named("Bob")
        .set(Position { x: 10.0, y: 20.0 }) 
        .add::<Walking>();

    // Get the value for the Position component
    let pos = bob.get::<Position>();
    println!("Bob position: {}, {}", pos.x, pos.y);

    // Overwrite the value of the Position component
    bob.set(Position { x: 20.0, y: 30.0 });
    println!("Bob position: {}, {}", pos.x, pos.y);

    // Create another named entity
    let alice = world.entity().named("Alice")
        .set(Position { x: 10.0, y: 20.0 });

    // Add a tag after entity is created
    alice.add::<Walking>();

    // Print all of the components the entity has. This will output:
    //    Position, Walking, (Identifier,Name)
    println!("Alice type = [ {} ]", alice.type_info().to_str());

    // Remove tag
    alice.remove::<Walking>();

    // Iterate all entities with Position
    world.each1(|e: flecs::Entity, p: &Position| {
        println!("{}: {}, {}", e.name(), p.x, p.y);
    });
}

编译和运行示例

git clone https://github.com/jazzay/flecs-rs
cd flecs-rs
cargo build --release

主要示例位于 examples 目录中。可以像这样运行它们

cargo test

cargo run --example hello_world
cargo run --example prefabs

使用 WebAssembly 编译

使用 WebAssembly 编译需要使用 wasm32-unknown-emscripten 目标。

这是因为没有针对 wasm32-unknown-unknown 的官方工具链,这意味着 C/C++ 绑定不适用于此目标,并且会导致符号未解析。

Emscripten 目标不如 wasm32-unknown-unknown 受支持,这意味着 wasm-bindgen 和一些其他针对 WebAssembly 的流行 Rust 库将无法正常工作。所以请务必记住这一点。

创建一个要静态提供的目录

mkdir static

static/ 下创建一个名为 index.html 的文件

<html>
  <body>
    <script type="module">
      import init from './systems.js'
      await init()
    </script>
  </body>
</html>

Emscripten 设置:需要一个特定版本的 Emscripten SDK。较新版本通常会导致构建或运行时错误。

在 Mac 上,您可能需要确保您的 Python3 SSL 证书已设置:https://bugs.python.org/issue43404

make setup_emsdk EMSDK=/your/install/directory

如果需要,您可以覆盖标准库路径

export STDLIB=/usr/include

默认情况下,它使用 Emsdk 的 sysroot 用于包含。

在某些平台上,您可能会遇到链接器错误

https://stackoverflow.com/questions/67474533/error-in-compiling-rust-into-webassembly-using-emscripten-on-windows

为了避免这种情况,请在构建之前运行此命令:(TODO 使其自动运行)

emcc -c gxx_personality_v0_stub.cpp

构建 WASM 二进制文件

cargo build --example systems --target wasm32-unknown-emscripten
cp ./target/wasm32-unknown-emscripten/debug/examples/systems.js ./static/
cp ./target/wasm32-unknown-emscripten/debug/examples/systems.wasm ./static/

使用任何 HTTP 服务器工具在本地提供静态文件,例如 basic-http-server

cargo install basic-http-server
basic-http-server ./static/

依赖项

~0–2MB
~40K SLoC