diff options
Diffstat (limited to 'bindings/rs-timeout/README.zh_cn.md')
| -rw-r--r-- | bindings/rs-timeout/README.zh_cn.md | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/bindings/rs-timeout/README.zh_cn.md b/bindings/rs-timeout/README.zh_cn.md new file mode 100644 index 0000000..2c15249 --- /dev/null +++ b/bindings/rs-timeout/README.zh_cn.md @@ -0,0 +1,163 @@ +# bind-rs-timeout + +[timeout](https://github.com/wahern/timeout) 的 Rust binding. + +主要包括 `Timeout` 和 `TimeoutManager` 两个模块. 分别是 timeout 实例和 timeout 管理. +- `Timeout` 是 timeout 实例,用于设置超时时间,可以绑定回调函数(支持闭包). +- `TimeoutManager` 用于管理 timeout 实例, 更新时间, 触发超时等. + +使用方法 +- 首先需要创建一个 `Timeout` 实例,并设置超时回调函数.将其添加到 `TimeoutManager` 中(所有权转移到 C 端的`TimeoutManager`),不断更新 `TimeoutManager` 时间,调用 `TimeoutManager::expired_timeouts` 方法返回已过期的 `Timeout`, 执行对应超时回调函数. + +```rust +let to = Timeout::new(ToType::Default).unwrap(); // onetime type, relative timeout +let to2 = Timeout::new(ToType::INT).unwrap(); // periodic type +let mut tos = TimeoutManager::new(TIMEOUT_mHZ).unwrap(); + +tos.update_time_rel(0); // relative time, tos.now = 0 +tos.add(to, 50); // onetime, expired time = tos.now + 50 +tos.add(to2, 100); // periodic, starting from tos.now, expiring every 100. + +tos.update_time_abs(150); // absolute time, tos.now = 150 + +for to in tos.expired_timeouts() { + match to { + ToR::OneTime(temp) => { + // onetime type, Timeout, do something + // all flag has cleared assert!(to.is_expired()); will error + temp.run_cb(); + } + ToR::Periodic(temp) => { + //periodic type, &Timeout, do something + // assert!(temp.is_periodic()); will work + } + }; +} +``` + +## Timeout + +`Timeout` 是 timeout 实例的结构体,用于设置超时时间.该结构体包含了多个方法, 用于设置超时回调函数(支持闭包(FnMut 类型))、检查超时状态、删除超时操作等. + +`Timeout` 有 3 种类型 +- `ToType::INT`: 周期性的定时器, 间隔固定时间重复触发, 每次触发之间独立, 错过某次触发不影响下次触发时间. +- `ToType::ABS`: 一次性定时器, 在指定绝对时间触发一次. +- `ToType::Default`: 一次性定时器, 添加定时器时间点后,经过指定相对时间后触发一次. + +### 方法列表 + +以下是 `Timeout` 结构体的方法列表: + +- `new(flags: ToType) -> Result<Timeout, &'static str>`: 创建一个新的 `Timeout` 实例,并设置超时标志. +- `is_pending(&self) -> bool`: 检查超时是否已经注册并在计时轮上 +- `is_expired(&self) -> bool`: 检查超时是否已经注册并在过期队列上 +- `is_periodic(&self) -> bool`: 检查超时是否是周期性的 +- `delete(&mut self)`: 从计时轮或过期队列中删除超时 +- `set_cb<T>(&mut self, cb: TimeoutCallBack<T>)`: 设置超时回调函数 +- `set_cb_closure<F>(&mut self, closure: &mut F) where F: FnMut()`: 传入闭包,设置超时回调. +- `run_cb(&self) -> bool`: 运行超时回调函数,并返回是否已经执行成功. + + +### 添加回调 + +`Timeout` 支持添加回调,在过期后自行调用 `run_cb` 执行回调. + +`Timeout` 的回调函数支持传入 C 兼容的函数,也支持传入 `FnMut()` 类型的闭包. +- 传入函数限定,函数参数为 `&mut T` 类型,返回值为 `()`. +- 传入闭包限定,入参为 `()`,返回值为 `()`. + +```rust +pub struct Session { pub session_id: String,} +let mut timeout = Timeout::new(ToType::Default).unwrap(); + +extern "C" fn rust_callback(arg: &mut i32) { + println!("Callback executed with arg: {}", arg); +} + +let mut binding = 11; +let cb = TimeoutCallBack::new(rust_callback, &mut binding); + +timeout.set_cb(cb); +timeout.run_cb(); + +let mut session = Session { session_id: "123".to_string(),}; + +timeout.set_cb_closure(&mut || { + println!("Callback executed with session_id: {}", session.session_id); + session.session_id = "456".to_string(); + println!("Callback executed with session_id: {}", session.session_id); +}); + +timeout.run_cb(); +``` + +请注意回调的生命周期. +- 传入函数时,需要保证 函数及其参数 的生命周期长于 `Timeout` 的生命周期,否则调用时会返回 false 表示调用失败. +- 传入闭包时,需要保证 闭包及其调用变量 的生命周期长于 `Timeout` 的生命周期,否则调用时会返回 false 表示调用失败. + +## TimeoutManager + +`TimeoutManager` 提供了一个 `TimeoutManager` 结构体,用于管理超时操作.该结构体包含了多个方法,用于创建、添加、删除、更新超时操作等. + +### 方法列表 + +以下是 `TimeoutManager` 结构体的方法列表: + +- `new(hz_set: timeout_t) -> Result<TimeoutManager, &'static str>`: 创建一个新的 `TimeoutManager` 实例 +- `close(&mut self)`: 关闭 `TimeoutManager` 实例. +- `update_time_rel(&mut self, time: timeout_t)`: 更新时间,now = now + 相对时间, +- `update_time_abs(&mut self, current_time: timeout_t)`: 更新时间,now = 绝对时间. +- `get_hz(&self) -> timeout_t`: 获取 `TimeoutManager` 的频率. +- `get_next_wait_time(&self) -> timeout_t`: 获取下一个超时过期前的等待时间(一定小于实际的等待时间).没有等待时返回 `u64::MAX`. +- `any_pending(&self) -> bool`: 检查是否有 Timeout 正在等待. +- `any_expired(&self) -> bool`: 检查是否有 Timeout 已经过期. +- `check(&self) -> bool`: 检查 `TimeoutManager` 是否有效. + +与 `Timeout` 相关的方法: + +- `add(&mut self, to: Timeout, timeout: timeout_t)`: 添加 Timeout,所有权转移到 C 端的 `TimeoutManager`, 依照参数 to 的类型,参数 timeout 会有不同的效果. + - `ToType::INT` 类型,参数 timeout 为周期性的间隔时间.开始时间为 `TimeoutManager` 的当前时间. + - `ToType::ABS` 类型,在参数 timeout 指定的绝对时间触发一次. + - `ToType::Default` 类型,在参数 timeout + TimeoutManger.now 的时间触发一次. +- `delete(&mut self, to: &mut Timeout)`: 删除 Timeout. +- `expired_timeouts(&mut self) -> ExpireIter`: 获取已过期的 Timeout, 返回迭代器. + - 对应 `Timeout`, 返回的包括两种类型: `ToR::OneTime` 和 `ToR::Periodic`. + - 非周期的 `Timeout` 对应 `ToR::OneTime`,返回 `Timeout` 类型,所有权转移到 Rust 中. + - 周期的 `Timeout` 对应 `ToR::Periodic`,其所有权还在 C 端,因此返回 `&Timeout` 类型. +- `next_timeouts_pending(&mut self) -> NextIter`: 获取等待的 &Timeout,返回迭代器. +- `next_timeouts_expired(&mut self) -> NextIter`: 获取过期的 &Timeout,返回迭代器. +- `next_timeouts_all(&mut self) -> NextIter`: 获取全部的 &Timeout,返回迭代器. + +备注: `next_timeouts_xxx` 仅为查询方法,并不会对等待或过期队列进行任何操作. + +简单示例 + +```rust +xxx +let mut tos = TimeoutManager::new(TIMEOUT_mHZ).unwrap(); +xxx + +for to in tos.expired_timeouts() { + match to { + ToR::OneTime(temp) => { + // onetime type, Timeout, do something + temp.run_cb(); + } + ToR::Periodic(temp) => { + //periodic type, &Timeout, do something + // temp.run_cb(); + } + }; +} + +for to_ptr in tos.next_timeouts_expired() { + // do something + to_ptr.run_cb(); +} +``` + +## 其他 + +对于周期性 `Timeout` 其所有权自添加到 `TimeoutManager` 开始,直到 `TimeoutManager` 关闭,都在 C 端.因此,在 Rust 端无法获取周期性 `Timeout` 的所有权,只能获取其引用. + +单独提供了 `delete_to_periodic(to: &Timeout)` 用于从 `TimeoutManager` 中删除周期性 `Timeout`.
\ No newline at end of file |
