1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use crate::base::{on_idle, RuntimeLoop, RuntimeWaker};
use std::{
    future::Future,
    ops::ControlFlow,
    sync::{Arc, Condvar, Mutex},
};

/// Executes the specified future and blocks until it completes.
pub fn run<F: Future>(future: F) -> F::Output {
    crate::base::run(&NoFrameworkRuntimeLoop::new(), future)
}

struct NoFrameworkRuntimeLoop(Arc<Waker>);

struct Waker {
    is_wake: Mutex<bool>,
    cv: Condvar,
}

impl NoFrameworkRuntimeLoop {
    pub fn new() -> Self {
        Self(Arc::new(Waker {
            is_wake: Mutex::new(true),
            cv: Condvar::new(),
        }))
    }
}

impl Default for NoFrameworkRuntimeLoop {
    fn default() -> Self {
        Self::new()
    }
}

impl RuntimeLoop for NoFrameworkRuntimeLoop {
    fn waker(&self) -> Arc<dyn RuntimeWaker> {
        self.0.clone()
    }
    fn run<T>(&self, mut on_step: impl FnMut() -> ControlFlow<T>) -> T {
        let mut is_wake = self.0.is_wake.lock().unwrap();
        loop {
            if *is_wake {
                *is_wake = false;
                drop(is_wake);
                loop {
                    if let ControlFlow::Break(value) = on_step() {
                        return value;
                    }
                    if !on_idle() {
                        break;
                    }
                }
                is_wake = self.0.is_wake.lock().unwrap()
            } else {
                is_wake = self.0.cv.wait(is_wake).unwrap();
            }
        }
    }
}

impl RuntimeWaker for Waker {
    fn wake(&self) {
        let mut is_wake = self.is_wake.lock().unwrap();
        if !*is_wake {
            *is_wake = true;
            self.cv.notify_all();
        }
    }
}