跳转到内容
查看源码

嵌入与桥接

Entelechy 可以作为独立程序运行(CLI、Player),也可以嵌入到别的程序中。所有桥接都只是公共契约的客户端:Host 的文件格式和创作协议。Rust 工作区中没有任何东西依赖它们。

libentelechy_ffi 位于 C 头文件 entelechy.h 之后:宿主从路径或自己提供的文件打开场景,在自己的输入下求值,原地读取输出(不复制),并通过 entelechy_request 发送协议行。

终端窗口
cargo build --release -p entelechy-ffi
cc bridges/c/hello.c -Icrates/interface/ffi/include -Ltarget/release -lentelechy_ffi -o /tmp/entelechy-hello
LD_LIBRARY_PATH=target/release /tmp/entelechy-hello examples/text/scene.esn jit # Linux
DYLD_LIBRARY_PATH=target/release /tmp/entelechy-hello examples/text/scene.esn jit # macOS

在撰写本文档的 Linux 机器上的真实输出:

entelechy 0.0.2-rc.3
picture 192 x 88, 4 words a pixel, schema f,f,f,f, pixels 1
pixel (12, 9) = 0.09 0.10 0.13
publish: {"id":null,"ok":{"generation":24,"id":"scene.back@1"}}
pixel (12, 9) = 0.30 0.10 0.10

hello.c 打开场景、求值、在 Host 内存中读取图片(RGBA float),通过协议发布一个新 Kernel,再读一次图片——像素变了。

主要函数:

函数 作用
entelechy_open(scene, backend, library) 打开场景;失败时返回 NULL,原因见 entelechy_open_error()
entelechy_open_files(files, scene, backend) 从宿主提供的文件集合(entelechy_files_put)打开
entelechy_open_replay(files, replay, backend) 打开一个回放
entelechy_evaluate(session, input) 在宿主的输入下求值一帧;entelechy_report 读报告
entelechy_output(session, name, field) 原地读取一个输出 Field
entelechy_node(session, node, port, field) 读取某个节点端口
entelechy_allow(session, allowance) 授予与 --allow 相同的 Host 权限
entelechy_request(session, line) 发送一行协议请求,返回答复
entelechy_play_* 作为 Player 驱动(按键、指针、手柄、帧、声音)
entelechy_close(session) 关闭

静态库 libentelechy_ffi.a 链接方式相同。任何有 C FFI 的语言(Python ctypes、C#、Zig、Godot GDExtension)都可以绑定;头文件说明了每个指针的生命周期。

发布包中:

终端窗口
wasmtime run --dir . entelechy-<version>-wasm32-wasip1.wasm replay examples/ant/tests/ant.replay --backend cpu
cd entelechy-<version>-web && node bridges/web/serve.mjs # 然后打开 http://127.0.0.1:7789/bridges/web/play.html?scene=examples/voxel/scene.esn

从源码:

终端窗口
cargo build --release -p entelechy --target wasm32-wasip1
cargo build --release -p entelechy-ffi --target wasm32-unknown-unknown
wasm-bindgen --target web --keep-lld-exports --no-typescript --out-dir target/page \
target/wasm32-unknown-unknown/release/entelechy_ffi.wasm
node bridges/web/serve.mjs # 然后打开 http://127.0.0.1:7789/bridges/web/index.html
  • 在 WASI 下,entelechy 用解释器运行场景,serve 在 stdin/stdout 上应答。
  • 在网页中,Entelechy 就是 C ABI 加上 wasm-bindgen 胶水:文档是页面交给它的文件,JIT 生成页面加载的 WebAssembly,GPU 后端运行在浏览器的 WebGPU 上(Chrome 和 Edge 137 及以后)。play.html 是网页中的 Player,接受 ?scene= 或 ?replay=。
桥接 连接方式 说明
bridges/c 进程内 C ABI 上面的 hello.c
bridges/web WebSocket(--listen) 网页客户端:连接、逐帧 evaluate + read(PPM)、按键与指针、列出并编辑 Kernel;从文件打开时需要 --allow-origin null
bridges/godot TCP socket Godot 4 项目(GDScript):EntelechyClient(open、request、close、PPM 与 Field 解码)、一个作为会话窗口的 Control、为每个图参数生成控件
bridges/blender 文件 + socket Blender 插件:把活动网格推送为场景资源(.vertices.field、.triangles.field、.albedo.png),Live 模式下 Blender 中编辑网格即刻改变窗口;处理 z-up / y-up 坐标转换;推送骨骼
终端窗口
entelechy player examples/voxel/scene.esn --serve --listen 127.0.0.1:7788 --allow-origin null # web
entelechy serve examples/fluid/scene.esn --backend jit --listen 127.0.0.1:7788 # godot
entelechy player examples/mesh/parts/model/scene.esn --serve --listen 127.0.0.1:7788 # blender

cargo test -p entelechy --test bridges 会在安装了相应工具的机器上运行这些桥接的测试。