Rust学习 实现一个单线程事件驱动模型

实现一个单线程事件驱动模型

需求描述

实现一个主事件循环,不停往主事件循环中塞入事件,事件可以描述他的名称、事件类型(不等待,等待,终止)、携带的数据、指定的事件处理。

代码实现

main.rs

mod event;
mod handler;

use event::{EventType, Event};
use handler::Handler;

use std::thread;
use std::time::Duration;


fn main() {
    let mut event_loop: Vec<Event<i64, i64>> = Vec::new();
    let mut event1 = Event::<i64, i64>::new("PlusOne", EventType::NoWait, 1);
    let plus_one = Handler::<i64, i64>::new(|x: i64| x + 1);
    event1.set_handler(&plus_one);

    let mut event2 = Event::<i64, i64>::new("MinusOne", EventType::Wait(5), 0);
    let minus_one = Handler::<i64, i64>::new(|x: i64| x - 1);
    event2.set_handler(&minus_one);

    event_loop.push(event1);
    event_loop.push(event2);

    loop {
        if let Some(event) = event_loop.pop() {
            match event.get_type() {
                EventType::NoWait => {
                    println!("{:?}", event.name);
                    let result = event.handle();
                    println!("{:?}", result);
                }
                EventType::Wait(duration) => {
                    thread::sleep(Duration::from_secs(duration));
                    println!("{:?}", event.name);
                    let result = event.handle();
                    println!("{:?}", result);
                }
                EventType::Stop => {
                    break;
                }
            }
        }
    }
}

Event.rs

use crate::handler::EventHandler;

#[derive(Debug, Copy, Clone)]
#[allow(dead_code)]
pub enum EventType {
    NoWait,
    Wait(u64),
    Stop,
}

pub struct Event<'a, T, R> {
    pub name: &'static str,
    r#type: EventType,
    data: T,
    handler: Option<&'a (dyn EventHandler<T, Output=R>)>,
}

#[allow(dead_code)]
impl<'a, T: Clone, R> Event<'a, T, R> {
    pub fn new(name: &'static str, r#type: EventType, data: T) -> Self {
        Self {
            name,
            r#type,
            data,
            handler: None,
        }
    }

    pub fn set_handler(&mut self, handler: &'a (dyn EventHandler<T, Output=R>)) {
        self.handler = Option::from(handler);
    }

    pub fn handle(&self) -> Option<R> {
        if let Some(handler) = self.handler {
            Option::from(handler.handle(self.data.clone()))
        } else {
            None
        }
    }

    pub fn get_type(&self) -> EventType {
        self.r#type
    }
}

Handler.rs

pub trait EventHandler<T> {
    type Output;
    fn get_func(&self) -> fn(T) -> Self::Output;
    fn handle(&self, data: T) -> Self::Output {
        self.get_func()(data)
    }
}

#[derive(Debug)]
pub struct Handler<T, Output> {
    func: fn(data: T) -> Output,
}

impl<T, Output> EventHandler<T> for Handler<T, Output> {
    type Output = Output;
    fn get_func(&self) -> fn(T) -> Self::Output { self.func }
}

impl<T, Output> Handler<T, Output> {
    pub fn new(func: fn(T) -> Output) -> Self {
        Self {
            func
        }
    }
}

运行结果

/usr/bin/cargo run --color=always
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/event-driven`
"MinusOne"
Some(-1)
"PlusOne"
Some(2)

总结

  1. 通过范型可以将代码的冗余再降低一些。
  2. 使用多线程描述这个模式更加符号。
  3. trait的使用还不熟练,有点大材小用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值