Legion ECS 的多个可变查询
Multiple mutable queries with Legion ECS
我正在使用 Legion ECS 并尝试将多个可变查询和 运行 用于一些借用检查器约束。
我基本上想通过与所有其他组件进行比较来更新组件的状态。
本质上 - 如果组件与另一个组件相邻,则将它们设为蓝色。
let components = <&Component>::query()
.iter(world)
.collect();
<&Component>::query()
.iter_mut(world)
.for_each(|component| {
// for each c in components
// make component blue if c is adjacent to this component
})
上面的错误是 cannot borrow
*ecs as mutable more than once at a time
|
128 | .iter(&ecs)
| ---- immutable borrow occurs here
...
134 | .iter_mut(&mut ecs)
| ^^^^^^^^ mutable borrow occurs here
135 | .for_each(|(_, fov)| {
136 | let fovs: HashSet<Point> = components
| --- immutable borrow later captured here by closure
还有其他方法可以做到以上几点吗?
我认为克隆初始集合会使我与 World/ecs 脱钩。但即使使用克隆,遍历组件集合也是不可变的借用。
问题是你的 components
向量是一个包含 references 到 Component
的向量,它借鉴了 world
,这意味着你可以稍后编辑组件时可变地借用它。
您可以通过几种方式解决此问题:
- 在创建
compontents
向量时克隆组件。简单,但需要更多分配。
- 首先不可变地迭代组件并保留更改缓冲区,然后应用这些更改。
CommandBuffer
可以提供帮助 - 您甚至可以将其添加到系统中,legion 将负责创建和刷新。
- 遍历
Entities
,可能使用组件过滤器(IDK,如果它锁定其过滤的存储),并使用 world.entry[_mut]
一次访问一个组件。不需要分配,但性能可能较差。
我正在使用 Legion ECS 并尝试将多个可变查询和 运行 用于一些借用检查器约束。
我基本上想通过与所有其他组件进行比较来更新组件的状态。
本质上 - 如果组件与另一个组件相邻,则将它们设为蓝色。
let components = <&Component>::query()
.iter(world)
.collect();
<&Component>::query()
.iter_mut(world)
.for_each(|component| {
// for each c in components
// make component blue if c is adjacent to this component
})
上面的错误是 cannot borrow
*ecs as mutable more than once at a time
|
128 | .iter(&ecs)
| ---- immutable borrow occurs here
...
134 | .iter_mut(&mut ecs)
| ^^^^^^^^ mutable borrow occurs here
135 | .for_each(|(_, fov)| {
136 | let fovs: HashSet<Point> = components
| --- immutable borrow later captured here by closure
还有其他方法可以做到以上几点吗? 我认为克隆初始集合会使我与 World/ecs 脱钩。但即使使用克隆,遍历组件集合也是不可变的借用。
问题是你的 components
向量是一个包含 references 到 Component
的向量,它借鉴了 world
,这意味着你可以稍后编辑组件时可变地借用它。
您可以通过几种方式解决此问题:
- 在创建
compontents
向量时克隆组件。简单,但需要更多分配。 - 首先不可变地迭代组件并保留更改缓冲区,然后应用这些更改。
CommandBuffer
可以提供帮助 - 您甚至可以将其添加到系统中,legion 将负责创建和刷新。 - 遍历
Entities
,可能使用组件过滤器(IDK,如果它锁定其过滤的存储),并使用world.entry[_mut]
一次访问一个组件。不需要分配,但性能可能较差。