1个不稳定版本

0.1.0 2022年4月24日

#49#tooling

MIT/Apache

47KB
995

异步对象

本库提供用于异步环境中使用对象的引用计数包装器,并支持事件。

该库的主要目的是为我实验性的GUI库WAG提供基础,但它足够抽象,可以在任何其他地方使用。

示例

此代码为BackgroundImpl对象创建Background和WBackground包装器。内部它们只是Arc和Weak,以及用于无阻塞访问Rwlock的工具。

#[async_object_decl(pub Background, pub WBackground)]
struct BackgroundImpl {
   color: Color
}

#[async_object_impl(Background,  WBackground)]
impl BackgroundImpl {
   pub fn set_color(&mut this, color: Color) {
       this.color = color
   }
   pub fn get_color(&this) -> Color {
       this.color
   }
}

impl Background {
   pub fn new() -> Background {
       Background::create(BackgroundImpl { color: Color::White })
   }
}

Background和WBackground结构将具有以下自动生成的代理方法

impl Background {
    pub fn set_color(...);
    pub fn get_golor() -> Color;
    async pub fn async_set_color(...);
    async pub fn async_get_color(...) -> Color
}

impl WBackground {
    pub fn set_color(...) -> Option<()>;
    pub fn get_golor() -> Option<Color>;
    async pub fn async_set_color(...) -> Option<()>;
    async pub fn async_get_color(...) -> Option<Color>
}

还有事件发布/订阅支持。例如

enum ButtonEvent { Press, Release }

#[async_object_with_events_decl(pub Button, pub WButton)]
struct ButtonImpl {
}

#[async_object_impl(Button, WButton)]
impl ButtonImpl {
    async pub fn async_press(&mut self) {
        self.send_event(ButtonEvent::Press).await
    }
    pub fn press(&mut self) {
        let _ = self.send_event(ButtonEvent::Press)
    }
    pub fn events(&self) -> EventStream<ButtonEvent> {
        self.create_event_stream()
    }
}

以下代码在按钮按下时更改背景颜色

let pool = ThreadPool::builder().create().unwrap();
let button = Button::new();
let background = Background::new();

pool.spawn({
    let events = button.events();
    async move {
        // As soon as button is destroyed stream returns None
        while let Some(event) = events.next().await {
            // event has type Event<ButtonEvent>
            match *event.as_ref() {
                ButtonEvent::Pressed => background.set_color(Color::Red).await,
                ButtonEvent::Released => background.set_color(Color::White).await,
            }
        }
    }
});

依赖关系

~2.5MB
~53K SLoC