基於rust實現的事件系統,支援同步和非同步

wdshihaoren發表於2020-12-06

簡介

事件系統是受到c#的啟發,基於事件系統可以更容易地實現程式解耦。
因此,用rust也實現了一個類似的、但更豐富的輕量級事件開發包。
crate地址:crates.io/crates/wd_event
git地址:gitee.com/yutiandou/wd-event

功能

  • 事件註冊和呼叫(廢話)
  • Context 上下文
  • delay event,delay cycle event,定時任務和迴圈任務
  • task pool 任務池
  • object pool 物件池(暫時沒用)

用法

導包
use wd_event::{EventManage,EConfig,Context,Event,EType,AsyncEvent};
建立一個事件管理器
fn main() {
    let mut es = EventManage::new(EConfig::default());
    //TODO ...
}

#[tokio::main]
async fn main() {
    let mut es = EventManage::new_async(EConfig::default()).await;
    //TODO ...
}
註冊事件

任何一個實現了Event 特性的型別的實體都可以被註冊。事件型別如下三種

  • EType::Default: 執行 Event 特性的 handle 方法.
  • EType::Mutable: 執行 Event 特性的 handle_mut 方法.
  • EType::Async: 非同步事件,新增非同步事件時自動呼叫。

sync

struct HandleOne;
impl Event for HandleOne{
    fn handle(&self,_ctx:Arc<Context>){
        println!("execute handlone handle")
    }
}

let event_one = String::from("event_one");
es.add( event_one.clone(),HandleOne{},EType::Default).unwrap();

async 注意:一個非同步事件是不能被exec_sequence函式順序執行的

struct AsyncHanle;
#[wd_event::event_trait]
impl AsyncEvent for AsyncHanle{
    async fn handle(&self,_ctx:Arc<Context>){
        tokio::time::sleep(Duration::from_secs(1)).await;
        println!("休眠一秒後執行");
    }
}

es.add_async(event_one.clone(),AsyncHanle{}).unwrap();
執行事件 ,都是非阻塞的
  • exec_sequence: 按順序執行一個事件,先註冊先執行
  • exec_pool: 將事件傳送到任務池中執行
  • exec_immediately: 立即非同步執行事件
    es.exec_sequence(&event_one,None);
    es.exec_pool(&event_one,None);
    es.exec_immediately(&event_one,None).await;;
上下文

上下文用於在對事件的多個回撥中傳遞狀態和共享訊息。

更改上下文的狀態將停止後續的函式呼叫,只有exec_sequence方法和迴圈事件才會停止。

更多方法請參考API。

//Create context and add a default message
let a:i32 = 1;
es.exec_sequence(&event_one,Some(Context::new_add_msg(a)));

//Gets the default message for the context
impl Event for HandleOne{
    fn handle(&self,ctx:Arc<Context>){
        let value = match ctx.get_msg::<i32>(){
            Some(s)=>{
                s.add(10)
            }
            None=>{0}
        };
        println!("execute handlone handle,get value {}",value);
    }
}
//
定時事件和迴圈事件
//delay event and cycle event. only the handle_mut method is called
fn handle_mut(&mut self,ctx:Arc<Context>){
    let a = match ctx.get_arc_value::<String,i32>(&self.key){
        Some(s)=>{
            s.add(1)}
        None=>{0}
    };
    println!("迴圈{}次",a);
    ctx.set_value(&self.key, a);
}
//Once a second
es.delay_exec(Cycle{key:"default".to_string()},Context::new_delay(std::time::Duration::from_secs(1),true));
任務池

任務池功能,整合到事件管理器中。使用exec_pool函式。
當然,也可以單獨使用任務池函式,詳見API。

物件池

物件池,目前只是一個簡單的實現。
值得考慮的是,rust是否真的需要物件池?

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章