#binding #events #reactive #parametric #data-structures

flo_binding

Rust 声明式绑定库

9 个版本 (稳定)

2.2.0 2022年6月9日
2.0.1 2021年11月20日
2.0.0 2021年2月8日
1.1.0 2019年12月23日
0.1.0 2018年3月17日

#374算法

Download history 31/week @ 2024-03-11 29/week @ 2024-03-18 14/week @ 2024-03-25 54/week @ 2024-04-01 18/week @ 2024-04-08 25/week @ 2024-04-15 38/week @ 2024-04-22 23/week @ 2024-04-29 25/week @ 2024-05-06 20/week @ 2024-05-13 28/week @ 2024-05-20 22/week @ 2024-05-27 24/week @ 2024-06-03 23/week @ 2024-06-10 24/week @ 2024-06-17 23/week @ 2024-06-24

每月97次下载
用于 5 个crate

Apache-2.0

145KB
2.5K SLoC

flo_binding,一个数据驱动绑定库

flo_binding 提供创建 '数据绑定' 的方式,这是在应用程序的不同部分之间存储和共享状态的一种方式。围绕这些数据结构设计的应用程序有时被称为 '响应式' 应用程序。

可以使用 bind() 函数创建基本绑定

    let binding = bind(1);

可以通过调用 set() 来更新,并使用 get() 来检索

    let value = binding.get(); // == 1
    binding.set(2);
    let value = binding.get(); // == 2

克隆绑定将共享状态

    let another_binding = binding.clone();
    another_binding.set(3);
    let value = another_binding.get();  // == 3
    let value = binding.get();          // Also == 3

有两种主要方式可以在绑定更改时收到通知。当绑定自上次读取以来已更改时,when_changed() 函数提供调用函数的方式,而 follow() 函数将返回绑定最近附加的值的 Stream。流式方法是最灵活的。

    let binding             = bind(1);
    let mut event_lifetime  = binding.when_changed(notify(|| { println!("Binding changed"); }));
    let mut binding_stream  = follow(binding.clone());

    let value = binding_stream.next().await;        // == 1
    binding.set(2);                                 // Prints 'Binding changed'
    binding.set(3);                                 // Changed flag is set, so prints nothing
    let value = binding.get();                      // == 3

    binding.set(4);                                 // Prints 'Binding changed' again
    let value = binding_stream.next().await;        // == 4 (stream does not return intermediate values)
    let value = binding_stream.next().await;        // Blocks until something elsewhere updates the binding

    event_lifetime.done();
    binding.set(5);                                 // Prints nothing as the 'when_changed' event has been deregistered

follow() 的逆操作是 bind_stream(),它创建一个与从流接收到的最后一个值保持更新的绑定

    let binding             = bind(1);
    let binding_from_stream = bind_stream(follow(binding.clone()), 1, |_old_value, new_value| new_value);

    let value = binding.get();                  // == 1
    let value = binding_from_stream.get();      // == 1

    binding.set(2);
    let value = binding_from_stream.get();      // == 2

这样的流绑定是只读的,但将任何状态值流转换为表示静态状态的值的好方法。它实现了所有其他绑定操作。

另一种重要的绑定类型是 computed() 绑定,它可以使创建一个从其他绑定中派生值的绑定成为可能。计算绑定会自动监视任何被捕获的绑定以检测变化,因此它们可以像任何其他绑定一样被 followwhen_change

    let binding             = bind(1);
    let binding_copy        = binding.clone();
    let one_more            = computed(move || binding_copy.get() + 1);

    let mut event_lifetime  = one_more.when_changed(notify(|| println!("Computed binding changed")));

    let value = one_more.get();     // == 2 (1 + 1)
    binding.set(2);                 // Prints 'Computed binding changed'
    binding.set(3);                 // Computed binding has not been read since the last notification so prints nothing
    let value = one_more.get();     // == 4 (3 + 1)

对于数据集合,flo_binding 使用了“绳绑定”的概念。绳数据类型由 flo_rope crate 提供。这些绑定在流式传输时发送差异而不是它们的完整状态,并在内部通过一种可以高效执行删除和插入操作的数据结构表示。与传统的绳概念不同,它们不仅限于编辑字符串,还可以使用属性注释其内容,这使得它们适合表示任何类型的序列,或带有样式信息的富文本序列。

    let mutable_rope        = RopeBindingMut::<usize, ()>::new();
    let rope_copy           = RopeBinding::from_stream(mutable_rope.follow_changes());
    let mut rope_stream     = rope_copy.follow_changes();

    mutable_rope.replace(0..0, vec![1, 2, 3, 4]);

    let next            = rope_stream.next().await;                         // == RopeAction::Replace(0..0, vec![1,2,3,4]))

    let rope_len        = rope_copy.len();                                  // == 4
    let rope_content    = rope_copy.read_cells(0..4).collect::<Vec<_>>();   // == vec![1, 2, 3, 4]

flo_rope 库提供了一些额外功能——例如,通过在变化的序列上使用差异算法而不是仅仅报告到达的变化,来创建绳的 RopeAction

配套库

除了 flo_rope 之外,desync crate 提供了一种新颖的异步代码方法,包括与 follow() 函数的流式更新协同工作的管道操作。

flo_stream 提供了一个 pubsub 系统,它提供了通过流分发状态的更灵活的方法。

flo_scene 是一个运行时,用于构建由相互交换消息的实体组成的复杂系统。它使用 flo_binding 作为交换状态信息的便捷方式。

FlowBetween 是一个矢量和平面动画编辑器,它使用 flo_binding 来表示其用户界面。

依赖项

~0–255KB