3 个不稳定版本

0.2.1 2023年1月8日
0.2.0 2023年1月8日
0.1.0 2022年9月11日

#951Rust 模式

MIT/Apache

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

应用程序状态已按照 t0t1t2t3 的顺序更改。现在,当前状态是 t3

让我们考虑将当前状态 t3 撤销到其上一个状态 t2。首先,系统从历史中的任何一点恢复其快照中的旧状态。在这种情况下,我们必须从 s0 恢复状态 t0,因为只有一个快照 s0。然后系统按顺序重新运行命令(c1c2)。最后,将获得目标状态 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`。因此,变量可以像智能指针一样使用。

无运行时依赖