3 个不稳定版本
0.2.1 | 2023年1月8日 |
---|---|
0.2.0 | 2023年1月8日 |
0.1.0 | 2022年9月11日 |
#951 在 Rust 模式
93KB
2K SLoC
gur
一个撤销-重做框架。
生成式方法
本节介绍了该包的基本概念。该概念是“撤销是重新生成(重新计算)旧状态”。
为了解释,以下是一个示例更改历史:
t: state
c: command
s: snapshot
old <----------------------> new
c1 c2 c3
t0 -----> t1 -----> t2 -----> t3
| +--------------> |
| | |
s0 +--------------------------+
undo t3 -> t2
其中 tx
是时间点 x
的应用程序状态,cx
是更改状态的命令,将 tx-1
变为下一个 tx
,而 sx
是状态的快照 tx
。
应用程序状态已按照 t0
、t1
、t2
和 t3
的顺序更改。现在,当前状态是 t3
。
让我们考虑将当前状态 t3
撤销到其上一个状态 t2
。首先,系统从历史中的任何一点恢复其快照中的旧状态。在这种情况下,我们必须从 s0
恢复状态 t0
,因为只有一个快照 s0
。然后系统按顺序重新运行命令(c1
和 c2
)。最后,将获得目标状态 t2
。
示例代码
use gur::prelude::*;
use gur::cur::{Cur, CurBuilder};
// Appication state
#[derive(Clone)]
struct MyState {
data: String
}
fn main() {
// Initialize
let mut state: Cur<MyState> = CurBuilder::new().build(MyState{ data: "My".to_string() });
assert_eq!("My", state.data);
// Change state
state.edit(|mut state: MyState| { state.data += "State"; state });
assert_eq!("MyState", state.data);
// Undo
state.undo();
assert_eq!("My", state.data);
// Redo
state.redo();
assert_eq!("MyState", state.data);
}
其中 Cur<T>
是提供撤销-重做功能的一种类型。`MyState
` 是用户应用程序状态的一种类型。`MyState
` 实现了 `Clone
` trait,这是 `Cur<T>
` 所需要的。然后创建了一个类型为 `Cur<MyState>
` 的变量 `state` 来获得撤销-重做的能力。
`edit
` 接收一个闭包来更改变量。闭包是一个函数,它消耗当前状态作为内部类型 `MyState
` 并返回一个新状态。`undo
` 可以恢复上一个状态。`redo
` 是 `undo
` 的逆操作。
`Cur<T>
` 实现 `Deref
`。因此,变量可以像智能指针一样使用。