节律源
节律源决定“何时触发节点执行”。
你可以把它理解成系统的触发器或时钟源。
Rhythm Trait(当前实现)
pub trait Rhythm {
type Yield: Send;
type Feed;
type Output;
type Error: Into<RoplatError> + Debug;
fn drive<N, F, Fut>(
&mut self, nodes: N, op_domain: F,
) -> impl Future<Output = Self::Output> + Send
where
N: Send,
F: FnMut(N, Self::Yield) -> Fut + Send,
Fut: Future<Output = (Self::Feed, N)> + Send;
}
设计要点
- 零分配:回调
F返回编译期已知的Fut类型,无Box::pin堆分配。 - Pass-by-Value:节点元组
N按值传递,回调返回(Feed, N)归还所有权。N实际是可变引用元组(几个指针),移动成本为零。 - Send 安全:
Fut: Send确保 future 可在tokio::spawn环境中使用。
注意:
drive不要求N: Sync。节点元组通过&mut引用在闭包中逐一解包,不存在并发共享,因此Send足矣。
Yield 是节律源每次触发时交给节点域的数据。
内置节律源
-
SysTimer -
固定周期触发
-
产出
EventMeta(包含timestamp、delta、jitter、sequence) -
CountRhythm -
按次数触发
-
可通过
CountHandle动态调整目标次数 -
EventRhythm<T> -
基于事件通道触发
- 由
EventTrigger<T>主动投递事件
什么时候选哪一种
- 控制回路:优先
SysTimer - 有限步测试:优先
CountRhythm - 外部事件驱动:优先
EventRhythm<T> - 物理仿真步进:优先
SimRhythm(在rsbulletcrate 中,每 tick 先调用engine.step()再 yield 给下游) - 离线数据回放 / 批处理:直接使用
Iterator适配器
实践注意
- 你的
drive循环里不要长期阻塞。 - 时间敏感场景应关注
EventMeta.jitter。 - 节律触发频率要与节点计算耗时匹配,避免持续积压。