This commit is contained in:
Conrad Irwin
2023-10-26 18:19:57 +02:00
parent 452006560e
commit adc426b668
15 changed files with 4231 additions and 4182 deletions
+1 -1
View File
@@ -362,7 +362,7 @@ impl AppContext {
self.observers.remove(&entity_id);
self.event_listeners.remove(&entity_id);
for mut release_callback in self.release_listeners.remove(&entity_id) {
release_callback(&mut entity, self);
release_callback(entity.as_mut(), self);
}
}
}
+1 -1
View File
@@ -211,7 +211,7 @@ impl Drop for AnyHandle {
let count = entity_map
.counts
.get(self.entity_id)
.expect("Detected over-release of a handle.");
.expect("detected over-release of a handle.");
let prev_count = count.fetch_sub(1, SeqCst);
assert_ne!(prev_count, 0, "Detected over-release of a handle.");
if prev_count == 1 {
+38 -2
View File
@@ -1,7 +1,8 @@
use crate::{
AnyWindowHandle, AppContext, AsyncAppContext, Context, Executor, Handle, MainThread,
ModelContext, Result, Task, TestDispatcher, TestPlatform, WindowContext,
AnyWindowHandle, AppContext, AsyncAppContext, Context, EventEmitter, Executor, Handle,
MainThread, ModelContext, Result, Task, TestDispatcher, TestPlatform, WindowContext,
};
use futures::SinkExt;
use parking_lot::Mutex;
use std::{any::Any, future::Future, sync::Arc};
@@ -149,4 +150,39 @@ impl TestAppContext {
executor: self.executor.clone(),
}
}
pub fn subscribe<T: 'static + EventEmitter + Send + Sync>(
&mut self,
entity: &Handle<T>,
) -> futures::channel::mpsc::UnboundedReceiver<T::Event>
where
T::Event: 'static + Send + Clone,
{
let (mut tx, rx) = futures::channel::mpsc::unbounded();
entity
.update(self, |_, cx: &mut ModelContext<T>| {
cx.subscribe(&entity, move |_, _, event, _| {
let _ = tx.send(event.clone());
})
})
.detach();
rx
}
}
// pub fn subscribe<T: Entity>(
// entity: &impl Handle<T>,
// cx: &mut TestAppContext,
// ) -> Observation<T::Event>
// where
// T::Event: Clone,
// {
// let (tx, rx) = smol::channel::unbounded();
// let _subscription = cx.update(|cx| {
// cx.subscribe(entity, move |_, event, _| {
// let _ = smol::block_on(tx.send(event.clone()));
// })
// });
// Observation { rx, _subscription }
// }
+10 -3
View File
@@ -147,8 +147,10 @@ impl Executor {
Poll::Pending => {
if !self.dispatcher.poll() {
#[cfg(any(test, feature = "test-support"))]
if let Some(_) = self.dispatcher.as_test() {
panic!("blocked with nothing left to run")
if let Some(test) = self.dispatcher.as_test() {
if !test.parking_allowed() {
panic!("blocked with nothing left to run")
}
}
parker.park();
}
@@ -216,7 +218,7 @@ impl Executor {
#[cfg(any(test, feature = "test-support"))]
pub fn simulate_random_delay(&self) -> impl Future<Output = ()> {
self.dispatcher.as_test().unwrap().simulate_random_delay()
self.spawn(self.dispatcher.as_test().unwrap().simulate_random_delay())
}
#[cfg(any(test, feature = "test-support"))]
@@ -229,6 +231,11 @@ impl Executor {
self.dispatcher.as_test().unwrap().run_until_parked()
}
#[cfg(any(test, feature = "test-support"))]
pub fn allow_parking(&self) {
self.dispatcher.as_test().unwrap().allow_parking();
}
pub fn num_cpus(&self) -> usize {
num_cpus::get()
}
+12 -1
View File
@@ -28,6 +28,7 @@ struct TestDispatcherState {
time: Duration,
is_main_thread: bool,
next_id: TestDispatcherId,
allow_parking: bool,
}
impl TestDispatcher {
@@ -40,6 +41,7 @@ impl TestDispatcher {
time: Duration::ZERO,
is_main_thread: true,
next_id: TestDispatcherId(1),
allow_parking: false,
};
TestDispatcher {
@@ -66,7 +68,7 @@ impl TestDispatcher {
self.state.lock().time = new_now;
}
pub fn simulate_random_delay(&self) -> impl Future<Output = ()> {
pub fn simulate_random_delay(&self) -> impl 'static + Send + Future<Output = ()> {
pub struct YieldNow {
count: usize,
}
@@ -75,6 +77,7 @@ impl TestDispatcher {
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
eprintln!("self.count: {}", self.count);
if self.count > 0 {
self.count -= 1;
cx.waker().wake_by_ref();
@@ -93,6 +96,14 @@ impl TestDispatcher {
pub fn run_until_parked(&self) {
while self.poll() {}
}
pub fn parking_allowed(&self) -> bool {
self.state.lock().allow_parking
}
pub fn allow_parking(&self) {
self.state.lock().allow_parking = true
}
}
impl Clone for TestDispatcher {