rust实现向handler post函数,在handler的独立线程中按照顺序执行函数对象

use std::sync::{Arc, Mutex};
use std::{thread, time::Duration};
use std::collections::HashMap;

type Callback = Box<dyn FnOnce() + Send + 'static>;

enum MessageType {
    CallbackFunction,
    LiteMessage,
    Terminate,
}

#[derive(Clone, Debug, PartialEq)]
pub enum Object {
    Bool(bool),
    Char(char),
    I8(i8),
    U8(u8),
    I16(i16),
    U16(u16),
    I32(i32),
    U32(u32),
    I64(i64),
    U64(u64),
    F32(f32),
    F64(f64),
    String(String),
    BoolArray(Vec<bool>),
    CharArray(Vec<char>),
    I8Array(Vec<i8>),
    U8Array(Vec<u8>),
    I16Array(Vec<i16>),
    U16Array(Vec<u16>),
    I32Array(Vec<i32>),
    U32Array(Vec<u32>),
    I64Array(Vec<i64>),
    U64Array(Vec<u64>),
    F32Array(Vec<f32>),
    F64Array(Vec<f64>),
    StringArray(Vec<String>),
}

#[derive(Clone, Debug, PartialEq)]
struct Bundle {
    data: HashMap<String, Object>,
}

impl Bundle {
    pub fn new() -> Bundle {
        let data = HashMap::<String, Object>::new();
        Bundle {
            data,
        }
    }

    pub fn set_bool(&mut self, k: String, v: bool) {
        let o = Object::Bool(v);
        self.data.insert(k, o);
    }
    pub fn get_bool(&self, k: String, default_v: bool) -> bool {
        let val = self.data.get(&k);
        match val {
            Some(v) => {
                match v {
                    Object::Bool(v) => {
                        *v
                    }
                    _ => {
                        default_v
                    }
                }
            },
            None => {
                default_v
            }
        }
    }

    pub fn set_i32(&mut self, k: String, v: i32) {
        self.data.insert(k, Object::I32(v));
    }
    pub fn get_i32(&self, k: String, default_v: i32) -> i32 {
        let val = self.data.get(&k);
        match val {
            Some(v) => {
                match v {
                    Object::I32(v) => {
                        *v
                    }
                    _ => {
                        default_v
                    }
                }
            },
            None => {
                default_v
            }
        }
    }

    pub fn set_string(&mut self, k: String, v: String) {
        self.data.insert(k, Object::String(v));
    }
    pub fn get_string(&self, k: String, default_v: String) -> String {
        let val = self.data.get(&k);
        match val {
            Some(v) => {
                match v {
                    Object::String(v) => {
                        v.clone()
                    }
                    _ => {
                        default_v
                    }
                }
            },
            None => {
                default_v
            }
        }
    }
}

#[derive(Clone, Debug, PartialEq)]
struct LiteMessage {
    what: i32,
    arg1: i32,
    arg2: i32,
    data: Bundle,
}

impl LiteMessage {
    pub fn new() -> LiteMessage {
        LiteMessage {
            what: -1,
            arg1: -1,
            arg2: -1,
            data: Bundle::new(),
        }
    }

    pub fn set_what(&mut self, w: i32) {
        self.what = w;
    }
    pub fn get_what(&self) -> i32 {
        self.what
    }

    pub fn set_arg1(&mut self, a: i32) {
        self.arg1 = a;
    }
    pub fn get_arg1(&self) -> i32 {
        self.arg1
    }

    pub fn set_arg2(&mut self, a: i32) {
        self.arg2 = a;
    }
    pub fn get_arg2(&self) -> i32 {
        self.arg2
    }

    pub fn put_bool(&mut self, k: String, v: bool) {
        self.data.set_bool(k, v);
    }
    pub fn get_bool(&self, k: String, default_v: bool) -> bool {
        self.data.get_bool(k, default_v)
    }

    pub fn put_i32(&mut self, k: String, v: i32) {
        self.data.set_i32(k, v);
    }
    pub fn get_i32(&self, k: String, default_v: i32) -> i32 {
        self.data.get_i32(k, default_v)
    }

    pub fn put_string(&mut self, k: String, v: String) {
        self.data.set_string(k, v);
    }
    pub fn get_string(&self, k: String, default_v: String) -> String {
        self.data.get_string(k, default_v)
    }
}

struct Message {
    msg_type: MessageType,
    cb: Option<Callback>,
    lite_msg: Option<LiteMessage>,
}

impl Message {
    pub fn new_with_cb(cb: Callback) -> Message {
        Message {
            msg_type: MessageType::CallbackFunction,
            cb: Some(cb),
            lite_msg: None,
        }
    }

    pub fn new_with_lite(lite_msg: LiteMessage) -> Message {
        Message {
            msg_type: MessageType::LiteMessage,
            cb: None,
            lite_msg: Some(lite_msg),
        }
    }
}

struct MessageQueue {
    messages: std::collections::VecDeque<Message>,
}

impl MessageQueue {
    pub fn new() -> MessageQueue {
        MessageQueue {
            messages: std::collections::VecDeque::new(),
        }
    }

    pub fn pop_message(&mut self) -> Option<Message> {
        let msg = self.messages.pop_front();
        msg
    }

    pub fn push_message(&mut self, msg: Message) {
        self.messages.push_back(msg);
    }
}

struct MessageHandler {
    message_queue: Arc<Mutex<MessageQueue>>,
    message_handler_thread: thread::JoinHandle<()>,
}

impl MessageHandler {
    pub fn new() -> MessageHandler {
        let message_queue = Arc::new(Mutex::new(MessageQueue::new()));
        let message_queue_clone = Arc::clone(&message_queue);
        let handler_thread = thread::Builder::new().name("MessageHandler".to_string()).spawn(move || {
            loop {
                let message = message_queue_clone.lock().unwrap().pop_message();
                match message {
                    Some(msg) => {
                        println!("please handle new message");
                        let msg_type = msg.msg_type;
                        match msg_type {
                            MessageType::CallbackFunction => {
                                println!("do callback function");
                                match msg.cb {
                                    Some(func) => {
                                        func();
                                    },
                                    None => {
                                        println!("invalid callback function");
                                    }
                                }
                            },
                            MessageType::LiteMessage => {
                                println!("handle lite message");
                                match msg.lite_msg {
                                    Some(lite_msg) => {
                                        println!("received lite message: {:?}", lite_msg);
                                        let v_bool = lite_msg.get_bool("key_bool_1".to_string(), false);
                                        let v_i32 = lite_msg.get_i32("key_i32_1".to_string(), -1);
                                        let v_string = lite_msg.get_string("key_string_1".to_string(), "default_string".to_string());
                                        println!("v_bool: {}, v_i32: {}, v_string: {}", v_bool, v_i32, v_string);
                                    },
                                    None => {
                                        println!("invalied lite message");
                                    }
                                }
                            },
                            MessageType::Terminate => {
                                println!("received Terminate message, exit!");
                                break;
                            }
                        }
                    },
                    None => {
                        continue;
                    }
                }
            }
        });
        MessageHandler {
            message_handler_thread: handler_thread.unwrap(),
            message_queue,
        }
    }

    pub fn send_lite_message(&mut self, msg: LiteMessage) {
        println!("send lite message");
        let msg = Message::new_with_lite(msg);
        self.message_queue.lock().unwrap().push_message(msg);
    }

    pub fn send_cb_message(&mut self, cb: Callback) {
        println!("send callback message");
        let msg = Message::new_with_cb(cb);
        self.message_queue.lock().unwrap().push_message(msg);
    }

    pub fn send_pure_cb_message<T>(&mut self, cb: T)
        where
            T: FnOnce() + Send + 'static, {
            let cb = Box::new(cb);
            self.send_cb_message(cb);
    }

    pub fn send_terminate_message(&mut self) {
        println!("send terminate message");
        let msg = Message {
            msg_type: MessageType::Terminate,
            cb: None,
            lite_msg: None,
        };
        self.message_queue.lock().unwrap().push_message(msg);
    }
}

fn handle_message(val: Arc<Mutex<i32>>) {
    println!("handle message now, thread name = {:?}, val = {}", thread::current().name().unwrap(), val.lock().unwrap());
}

fn main() {
    // let mut bundle = Bundle::new();
    // bundle.set_bool("key_bool_1".to_string(), true);
    // bundle.set_bool("key_bool_2".to_string(), false);
    // let val_bool_1 = bundle.get_bool("key_bool_1".to_string(), false);
    // let val_bool_2 = bundle.get_bool("key_bool_2".to_string(), true);
    // println!("val_bool_1 = {}, val_bool_2 = {}", val_bool_1, val_bool_2);

    // bundle.set_i32("key_i32_1".to_string(), 8);
    // bundle.set_i32("key_i32_2".to_string(), 16);
    // let val_i32_1 = bundle.get_i32("key_i32_1".to_string(), -1);
    // let val_i32_2 = bundle.get_i32("key_i32_2".to_string(), -1);
    // println!("val_i32_1 = {}, val_i32_2 = {}", val_i32_1, val_i32_2);

    // bundle.set_string("key_string_1".to_string(), "test_string_1".to_string());
    // bundle.set_string("key_string_2".to_string(), "test_string_2".to_string());
    // let val_string_1 = bundle.get_string("key_string_1".to_string(), "default string".to_string());
    // let val_string_2 = bundle.get_string("key_string_2".to_string(), "default string".to_string());
    // println!("val_string_1 = {}, val_string_2 = {}", val_string_1, val_string_2);

    let msg_handler = Arc::new(Mutex::new(MessageHandler::new()));
    let msg_h_1 = Arc::clone(&msg_handler);
    let msg_h_2 = Arc::clone(&msg_handler);
    let msg_h_3 = Arc::clone(&msg_handler);
    let v: i32 = 0;
    let counter = Arc::new(Mutex::new(v));

    let counter_1 = Arc::clone(&counter);
    let counter_2 = Arc::clone(&counter);

    let t1 = thread::Builder::new().name("thread_1".to_string()).spawn(move || {
        loop {
             {
                let mut num = counter_1.lock().unwrap();
                if *num == 10 {
                    println!("thread name = {:?}, send terminate message", thread::current().name().unwrap());
                    msg_h_1.lock().unwrap().send_terminate_message();
                    break;
                }
                let counter_1 = Arc::clone(&counter_1);
                println!("thread name = {:?}, send cb message, val = {}", thread::current().name().unwrap(), num);
                msg_h_1.lock().unwrap().send_pure_cb_message(move || {
                    handle_message(counter_1);
                });
                *num += 1;
             }
            thread::sleep(Duration::from_millis(500));
        }
    });

    let t2 = thread::Builder::new().name("thread_2".to_string()).spawn(move || {
        loop {
            {
                let mut num = counter_2.lock().unwrap();
                if *num == 10 {
                    println!("thread name = {:?}, send terminate message", thread::current().name().unwrap());
                    msg_h_2.lock().unwrap().send_terminate_message();
                    break;
                }
                let counter_2 = Arc::clone(&counter_2);
                println!("thread name = {:?}, send cb message, val = {}", thread::current().name().unwrap(), num);
                msg_h_2.lock().unwrap().send_pure_cb_message(move || {
                    handle_message(counter_2);
                });
                *num += 1;
            }
            thread::sleep(Duration::from_millis(500));
        }
    });

    let t3 = thread::Builder::new().name("thread_3".to_string()).spawn(move || {
        let mut counter: i32 = 0;
        loop {
            if counter == 10 {
                println!("counter is 10, exit loop");
                // msg_h_3.lock().unwrap().send_terminate_message();
                break;
            } else {
                let mut lite_msg = LiteMessage::new();
                lite_msg.set_what(1);
                lite_msg.set_arg1(counter);
                lite_msg.set_arg2(counter);
                lite_msg.put_bool("key_bool_1".to_string(), true);
                lite_msg.put_i32("key_i32_1".to_string(), 8);
                lite_msg.put_string("key_string_1".to_string(), "test_string_1".to_string());
                msg_h_3.lock().unwrap().send_lite_message(lite_msg);
                counter += 1;
            }
        }
    });

    t1.unwrap().join();
    t2.unwrap().join();
    t3.unwrap().join();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值