Panic when awaiting conditions on dropped entities
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com> Co-Authored-By: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
parent
ddd746b9f9
commit
dcc2bdfd4c
1 changed files with 68 additions and 10 deletions
|
@ -2005,7 +2005,7 @@ impl<T: Entity> ModelHandle<T> {
|
||||||
.or_insert_with(|| postage::broadcast::channel(128).0);
|
.or_insert_with(|| postage::broadcast::channel(128).0);
|
||||||
let mut rx = tx.subscribe();
|
let mut rx = tx.subscribe();
|
||||||
let ctx = ctx.weak_self.as_ref().unwrap().upgrade().unwrap();
|
let ctx = ctx.weak_self.as_ref().unwrap().upgrade().unwrap();
|
||||||
let handle = self.clone();
|
let handle = self.downgrade();
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
timeout(Duration::from_millis(200), async move {
|
timeout(Duration::from_millis(200), async move {
|
||||||
|
@ -2013,14 +2013,20 @@ impl<T: Entity> ModelHandle<T> {
|
||||||
{
|
{
|
||||||
let ctx = ctx.borrow();
|
let ctx = ctx.borrow();
|
||||||
let ctx = ctx.as_ref();
|
let ctx = ctx.as_ref();
|
||||||
if predicate(handle.read(ctx), ctx) {
|
if predicate(
|
||||||
|
handle
|
||||||
|
.upgrade(ctx)
|
||||||
|
.expect("model dropped with pending condition")
|
||||||
|
.read(ctx),
|
||||||
|
ctx,
|
||||||
|
) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if rx.recv().await.is_none() {
|
rx.recv()
|
||||||
panic!("model dropped with pending condition");
|
.await
|
||||||
}
|
.expect("model dropped with pending condition");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
|
@ -2173,7 +2179,7 @@ impl<T: View> ViewHandle<T> {
|
||||||
.or_insert_with(|| postage::broadcast::channel(128).0);
|
.or_insert_with(|| postage::broadcast::channel(128).0);
|
||||||
let mut rx = tx.subscribe();
|
let mut rx = tx.subscribe();
|
||||||
let ctx = ctx.weak_self.as_ref().unwrap().upgrade().unwrap();
|
let ctx = ctx.weak_self.as_ref().unwrap().upgrade().unwrap();
|
||||||
let handle = self.clone();
|
let handle = self.downgrade();
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
timeout(Duration::from_millis(200), async move {
|
timeout(Duration::from_millis(200), async move {
|
||||||
|
@ -2181,14 +2187,20 @@ impl<T: View> ViewHandle<T> {
|
||||||
{
|
{
|
||||||
let ctx = ctx.borrow();
|
let ctx = ctx.borrow();
|
||||||
let ctx = ctx.as_ref();
|
let ctx = ctx.as_ref();
|
||||||
if predicate(handle.read(ctx), ctx) {
|
if predicate(
|
||||||
|
handle
|
||||||
|
.upgrade(ctx)
|
||||||
|
.expect("model dropped with pending condition")
|
||||||
|
.read(ctx),
|
||||||
|
ctx,
|
||||||
|
) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if rx.recv().await.is_none() {
|
rx.recv()
|
||||||
panic!("model dropped with pending condition");
|
.await
|
||||||
}
|
.expect("model dropped with pending condition");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
|
@ -3338,6 +3350,23 @@ mod tests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "model dropped with pending condition")]
|
||||||
|
fn test_model_condition_panic_on_drop() {
|
||||||
|
struct Model;
|
||||||
|
|
||||||
|
impl super::Entity for Model {
|
||||||
|
type Event = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
App::test_async((), |mut app| async move {
|
||||||
|
let model = app.add_model(|_| Model);
|
||||||
|
let condition = model.condition(&app, |_, _| false);
|
||||||
|
app.update(|_| drop(model));
|
||||||
|
condition.await;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_view_condition() {
|
fn test_view_condition() {
|
||||||
struct Counter(usize);
|
struct Counter(usize);
|
||||||
|
@ -3408,6 +3437,35 @@ mod tests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "model dropped with pending condition")]
|
||||||
|
fn test_view_condition_panic_on_drop() {
|
||||||
|
struct View;
|
||||||
|
|
||||||
|
impl super::Entity for View {
|
||||||
|
type Event = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl super::View for View {
|
||||||
|
fn ui_name() -> &'static str {
|
||||||
|
"test view"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&self, _: &AppContext) -> ElementBox {
|
||||||
|
Empty::new().boxed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
App::test_async((), |mut app| async move {
|
||||||
|
let window_id = app.add_window(|_| View).0;
|
||||||
|
let view = app.add_view(window_id, |_| View);
|
||||||
|
|
||||||
|
let condition = view.condition(&app, |_, _| false);
|
||||||
|
app.update(|_| drop(view));
|
||||||
|
condition.await;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn test_ui_and_window_updates() {
|
// fn test_ui_and_window_updates() {
|
||||||
// struct View {
|
// struct View {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue