#bus #message #async #module #run-time #event-handling

nightly dabus

动态应用程序控制总线 - 一个为希望快速移动且不破坏事物的人提供的异步、基于事件的模块系统

5 个版本

0.5.1 2023年9月20日
0.5.0 2022年6月8日
0.4.3 2022年5月27日
0.4.2 2022年5月26日
0.4.1 2022年5月26日

#762 in 异步

MIT 许可证

54KB
1K SLoC

DABus

DABus 是一个多类型应用程序总线。它允许您拥有多个完全独立的“处理器”或“总线停靠站”,您可以与之交互,并且它们可以相互交互 而不需要知道彼此的存在。它维护 Rust 的所有类型安全和保证,同时能够以高度动态的方式运行,几乎像 JavaScript 中的某些内容,但没有任何缺点。

问题跟踪器

此项目的问题跟踪器位于 GitHub 镜像

关键特性

  • 类型擦除:中心的 DABus 结构不需要知道与处理器或它正在处理的事件相关的任何类型
  • 异步:所有处理器都是异步的
  • 线程安全:完全支持多线程异步执行器
  • 类型安全:处理器和事件调用都是完全静态类型的
  • 方便:API 不会强迫您通过不便的途径

限制

  • 如前所述,它是异步和线程安全的。不幸的是,没有办法绕过这一点,因为所有类型都必须是 Sync 和 Send,并且异步是执行器函数的核心要求
  • 由于内部使用了所有动态类型,这严重依赖于动态分派,因此受到其性能问题的影响(别担心,它不是
  • 对于调试,它使用 log crate 实现了日志记录,但仍然相当难以调试。希望这很快会随着回溯而改变

用法

DABus 的事件处理器是一个简单的结构方法,例如这样的

use dabus::BusInterface;

#[derive(Debug)]
struct ExampleHandler;

impl ExampleHandler {
    async fn hello_world(&mut self, arguments: (), mut _interface: BusInterface) {
        /*
        here, arguments is the args passed to the event call,
        and _interface is a struct for communicating with the bus that invoked it

        warning! do NOT use BusInterface outside of the async handler it was passed to!
        it may seem like a good way of doing things, but IT WILL NOT WORK!!!
        */
        println!("Hello, World!");
    }
}

然后定义它所伴随的事件

//            the name     args  return type
dabus::event!(HELLO_EVENT, (),   ());

要将此从常规结构转换为总线停靠站,实现 BusStop

use dabus::{BusStop, EventRegister};

impl BusStop for HelloHandler {
    // this function provides a list of the handlers that this stop provides
    fn registered_handlers(h: EventRegister<Self>) -> EventRegister<Self> {
        //        event def    event function
        h.handler(HELLO_EVENT, Self::hello_world)
    }
}

最后,要使用它

use dabus::DABus;

#[tokio::main]
async fn main() {
    let mut bus = DABus::new();
    // create a new instance of HelloHandler, and pass it to the bus for useage
    bus.register(HelloHandler);
    //      the event     arguments (type from event def)
    bus.fire(PRINT_EVENT, "Hello, World!".to_string()).await.unwrap();
    // you should now see Hello, World! on your terminal!
}

重要说明

此 crate 需要 nightly!

这就是原因

#![feature(downcast_unchecked)]
#![feature(drain_filter)]
#![allow(incomplete_features)]
#![feature(specialization)]

crate 功能

名称 描述 默认行为
backtrace_track_values 回溯将包括处理器参数和返回值的调试格式 禁用

待办事项

  • 文档
  • 测试
  • 回溯(稍后做,现在做日志记录)
  • 格式化回溯
  • 关闭回溯的方法?(性能)
  • 示例 重要
  • 适当的错误处理
  • 多处理器事件
  • 更复杂的事件匹配(允许处理器在查看参数后消费事件?)
  • 嵌套处理器调用
  • 错误转发
  • 查看Rust API 指南
  • 性能分析优化

依赖关系

~1.2–1.9MB
~38K SLoC