Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #![allow(unused)]
- use std::cell::RefCell;
- use std::collections::HashMap;
- use std::rc::Rc;
- use std::thread::{self, sleep};
- struct Core {
- m: HashMap<u8, Rc<RefCell<State>>>,
- tx_msg: std::sync::mpsc::Sender<Msg>,
- }
- trait State {
- fn terminate(&mut self, &mut Core);
- }
- struct QueuedReq<T, F>(Option<F>, std::marker::PhantomData<T>);
- struct Inner<T, F>(u8, Option<F>, Option<T>);
- impl<T: 'static, F: FnOnce(T) + 'static> QueuedReq<T, F> {
- fn new(co: &mut Core, f: F) -> Self {
- QueuedReq(Some(f), std::marker::PhantomData)
- }
- fn fire(&mut self, co: &mut Core, t: T) {
- let f = self.0.take().unwrap();
- let qr = Inner(99, Some(f), Some(t));
- let qr = Rc::new(RefCell::new(qr));
- co.m.insert(99, qr);
- co.tx_msg.send(Msg::new(move |co| {
- let qr = co.m.get(&99).unwrap().clone();
- qr.borrow_mut().terminate(co);
- }));
- }
- }
- impl<T: 'static, F: FnOnce(T) + 'static> State for Inner<T, F> {
- fn terminate(&mut self, co: &mut Core) {
- co.m.remove(&self.0).unwrap();
- let t = self.2.take().unwrap();
- self.1.take().unwrap()(t);
- }
- }
- fn foo(co: &mut Core) {
- let mut c = "C".to_string();
- let h = move |(a, b)| {
- let c = std::mem::replace(&mut c, Default::default());
- handle(a, b, c);
- };
- let qr = QueuedReq::new(co, h);
- bar(co, qr);
- }
- fn handle(a: String, b: Vec<u8>, c: String) {
- println!("{},\t{:?},\t{}", a, b, c);
- }
- type Finish<F> = QueuedReq<(String, Vec<u8>), F>;
- fn bar<F: FnMut((String, Vec<u8>)) + 'static>(co: &mut Core, mut f: Finish<F>) {
- let a = "hello".to_string();
- let b = vec![2, 3, 4];
- f.fire(co, (a, b));
- }
- fn main() {
- let (tx_done, rx_done) = std::sync::mpsc::channel::<()>();
- thread::spawn(move || run(tx_done));
- rx_done.recv().unwrap();
- }
- struct Msg(Box<FnMut(&mut Core) + 'static + Send>);
- impl Msg {
- fn new<F: FnOnce(&mut Core) + Send + 'static>(f: F) -> Self {
- let mut f = Some(f);
- Msg(Box::new(move |co: &mut Core| {
- let f = f.take().unwrap();
- f(co)
- }))
- }
- fn invoke(&mut self, co: &mut Core) {
- (self.0)(co)
- }
- }
- fn run(tx_done: std::sync::mpsc::Sender<()>) {
- let (tx_msg, rx_msg) = std::sync::mpsc::channel::<Msg>();
- let mut co = Core {
- m: Default::default(),
- tx_msg,
- };
- foo(&mut co);
- rx_msg.recv().unwrap().invoke(&mut co);
- }
Add Comment
Please, Sign In to add comment