reactive_signals/runtimes/
test_client.rs1use std::cell::RefCell;
2
3use super::{Runtime, RuntimeInner, Scope};
4
5thread_local! {
6 pub static RUNTIME_POOL: TestClientRuntimePool = Default::default();
7}
8
9#[derive(Default, Clone, Copy)]
33pub struct TestClientRuntime(u32);
34
35impl TestClientRuntime {
36 pub(crate) fn from(idx: usize) -> Self {
37 if idx >= u32::MAX as usize {
38 panic!("Too many runtimes. Check your code for leaks. A runtime needs to be discarded");
39 }
40 Self(idx as u32)
41 }
42}
43
44impl Runtime for TestClientRuntime {
45 const IS_SERVER: bool = false;
46
47 fn with_mut<F, T>(&self, f: F) -> T
48 where
49 F: FnOnce(&mut RuntimeInner<TestClientRuntime>) -> T,
50 {
51 RUNTIME_POOL.with(|pool| {
52 let mut pool = pool.0.borrow_mut();
53 let rt = &mut pool[self.0 as usize];
54 f(rt)
55 })
56 }
57
58 fn with_ref<F, T>(&self, f: F) -> T
59 where
60 F: FnOnce(&RuntimeInner<TestClientRuntime>) -> T,
61 {
62 RUNTIME_POOL.with(|pool| {
63 let pool = pool.0.borrow();
64 let rt = &pool[self.0 as usize];
65 f(rt)
66 })
67 }
68}
69
70#[derive(Default)]
71pub struct TestClientRuntimePool(RefCell<Vec<RuntimeInner<TestClientRuntime>>>);
72
73impl TestClientRuntime {
74 pub fn new_root_scope() -> Scope<TestClientRuntime> {
75 RUNTIME_POOL.with(|rt| {
76 let mut vec = rt.0.borrow_mut();
77
78 for (i, rt) in &mut vec.iter_mut().enumerate() {
79 if !rt.in_use() {
80 let id = rt.scope_tree.init(Default::default());
81 return Scope {
82 rt: TestClientRuntime(i as u32),
83 sx: id,
84 };
85 }
86 }
87
88 let id = TestClientRuntime::from(vec.len());
89 let mut rti = RuntimeInner::new();
90 rti.scope_tree.init(Default::default());
91 let sx = rti.scope_tree.root();
92 vec.push(rti);
93 Scope { rt: id, sx }
94 })
95 }
96
97 #[cfg(any(test, feature = "profile"))]
98 pub fn bench_root_scope() -> Scope<TestClientRuntime> {
99 RUNTIME_POOL.with(|rt| {
100 drop(rt.0.borrow_mut().clear());
101 Self::new_root_scope()
102 })
103 }
104}