1 个不稳定版本
0.6.2 | 2023 年 5 月 27 日 |
---|
#496 在 并发
51 每月下载量
用于 7 个 Crates (2 直接使用)
66KB
1.5K SLoC
hecs-schedule
Hecs-schedule
hecs-schedule 是一个为 hecs 提供系统抽象的并行执行框架。
子世界
SubWorld 允许将世界分割成更小的部分,这些部分只能访问子集组件。这允许
命令缓冲区
CommandBuffer 通过组件插入、移除、实体生成和销毁等方式,提供了延迟的世界修改,以及通过闭包在以后时间进行任意世界修改的能力。
命令缓冲区扩展了现有的 hecs::CommandBuffer 并提供了更多功能。
系统和调度
系统代表一个可以访问任何资源的单元工作。系统可以针对任何具有任意数量参数(好吧,由于元组大小和编译时间,有一个合理的限制)的函数和闭包进行实现。
系统可以访问子世界并安全地访问声明的组件。它还可以通过 Read 和 Write 包装器访问任何其他类型的值。
此值将从提供的 Context 中提取,该 Context 被作为可变引用提供给 Schedule::execute。这意味着系统可以访问 ECS 外部的局部变量和结构成员。如果没有提供该类型的值,系统将干净地退出并返回错误。
系统可以返回空值或空结果,这将被正确装箱并传播
调度是一系列按顺序执行的系统。
当执行调度时,将为包含的系统提供引用的元组。
使用方法
use hecs_schedule::*;
use hecs::*;
let mut world = World::default();
#[derive(Debug)]
struct App {
name: &'static str,
}
let mut app = App {
name: "hecs-schedule"
};
// Spawn some entities
let a = world.spawn(("a", 42));
world.spawn(("b", 0));
world.spawn(("c", 7));
// Create a simple system to print the entities
let print_system = | w: SubWorld<(& &'static str, &i32)> | {
w.query::<(&&'static str, &i32)>().iter().for_each(|(e, val)| {
println!("Entity {:?}: {:?}", e, val);
})
};
// Get a component from a specific entity, failing gracefully if the entity
// didn't exist or the subworld did not support the component. The result
// will propogate to the schedule execution.
let get_system = move | w: SubWorld<&i32> | -> anyhow::Result<()> {
let val = w.get::<i32>(a)?;
// Prints the answer to life, the universe, and everything.
// Welp, maybe not how to please the borrow checker, but almost
// everything.
println!("Got: {}", *val);
Ok(())
};
// Declare a system which borrows the app and prints it.
// This requires that a reference to app was provided to execute.
// Otherwise, the system fails and returns an error, which propogates to the
// schedule and stops execution.
// It is also possible to modify the app via `mut Write<App>`
let print_app = |app: Read<App>| {
println!("App: {:?}", app);
};
// Note: the `hecs_schedule::CommandBuffer` is a superset of `hecs::CommandBuffer` and is
// accesible as a shared resource from systems.
let spawn_system = |mut cmd: Write<hecs_schedule::CommandBuffer>| {
cmd.spawn(("c", 5));
};
// Construct a schedule
let mut schedule = Schedule::builder()
.add_system(spawn_system)
.add_system(print_system)
.add_system(print_app)
.add_system(get_system)
.build();
// Execute the schedule's systems and provide the world and app. This will parallelize as much
// as possible.
schedule.execute((&mut world, &mut app)).expect("Failed to execute schedule");
依赖关系
~4MB
~75K SLoC