@@ -6,11 +6,11 @@ use crate::events::EventsRegistry;
6use crate::node::{Node, NodeKey};
6use crate::node::{Node, NodeKey};
7use crate::RenderContext;
7use crate::RenderContext;
8use bumpalo::Bump;
8use bumpalo::Bump;
9−use futures::future::Future;
10use fxhash::FxHashMap;
9use fxhash::FxHashMap;
11use std::cell::Cell;
10use std::cell::Cell;
12use std::cell::RefCell;
11use std::cell::RefCell;
13use std::fmt;
12use std::fmt;
13+use std::future::Future;
14use std::mem;
14use std::mem;
15use std::mem::ManuallyDrop;
15use std::mem::ManuallyDrop;
16use std::rc::{Rc, Weak};
16use std::rc::{Rc, Weak};
@@ -371,25 +371,20 @@ impl VdomWeak {
371 /// Replace the root rendering component with the new `root`.
371 /// Replace the root rendering component with the new `root`.
373 /// Returns a future that resolves to the *old* root component.
373 /// Returns a future that resolves to the *old* root component.
374− pub fn set_component(
374+ pub async fn set_component(
376 root: Box<dyn RootRender>,
376 root: Box<dyn RootRender>,
377− ) -> impl Future<Item = Box<dyn RootRender + 'static>, Error = VdomDroppedError> {
377+ ) -> Result<Box<dyn RootRender + 'static>, VdomDroppedError> {
378− futures::future::ok(self.inner.upgrade())
379− .and_then(|inner| inner.ok_or(()))
380− .map_err(|_| VdomDroppedError {})
378+ let inner = self.inner.upgrade().ok_or(VdomDroppedError {})?;
381− .and_then(|inner| {
379+
382− let promise = js_sys::Promise::resolve(&JsValue::null());
383− JsFuture::from(promise)
384− .map_err(|_| VdomDroppedError {})
385− .and_then(move |_| {
386− let old = {
380+ let old = {
387− let mut exclusive = inner.exclusive.borrow_mut();
381+ let mut exclusive = inner.exclusive.borrow_mut();
388− mem::replace(&mut *exclusive.component.as_mut().unwrap_throw(), root)
382+ mem::replace(&mut *exclusive.component.as_mut().unwrap_throw(), root)
390− VdomWeak::new(&inner).render().map(|_| old)
385+ VdomWeak::new(&inner).render().await?;
395 /// Execute `f` with a reference to this virtual DOM's root rendering
390 /// Execute `f` with a reference to this virtual DOM's root rendering
@@ -397,24 +392,15 @@ impl VdomWeak {
398 /// To ensure exclusive access to the root rendering component, the
393 /// To ensure exclusive access to the root rendering component, the
399 /// invocation takes place on a new tick of the micro-task queue.
394 /// invocation takes place on a new tick of the micro-task queue.
400− pub fn with_component<F, T>(&self, f: F) -> impl Future<Item = T, Error = VdomDroppedError>
395+ pub async fn with_component<F, T>(&self, f: F) -> Result<T, VdomDroppedError>
402 F: 'static + FnOnce(&mut dyn RootRender) -> T,
397 F: 'static + FnOnce(&mut dyn RootRender) -> T,
404− futures::future::ok(self.inner.upgrade())
405− .and_then(|inner| inner.ok_or(()))
406− .map_err(|_| VdomDroppedError {})
399+ let inner = self.inner.upgrade().ok_or(VdomDroppedError {})?;
407− .and_then(|inner| {
400+
408− let mut f = Some(f);
409− let promise = js_sys::Promise::resolve(&JsValue::null());
410− JsFuture::from(promise)
411− .map_err(|_| VdomDroppedError {})
413− let f = f.take().unwrap_throw();
414− let mut exclusive = inner.exclusive.borrow_mut();
401+ let mut exclusive = inner.exclusive.borrow_mut();
415− f(exclusive.component_raw_mut())
403+ Ok(f(exclusive.component_raw_mut()))
420 /// Schedule a render to occur during the next animation frame.
406 /// Schedule a render to occur during the next animation frame.
@@ -423,7 +409,12 @@ impl VdomWeak {
423 /// `render` instead.
409 /// `render` instead.
424 pub fn schedule_render(&self) {
410 pub fn schedule_render(&self) {
425 debug!("VdomWeak::schedule_render");
411 debug!("VdomWeak::schedule_render");
413+ let future = self.render();
426− wasm_bindgen_futures::spawn_local(self.render().map_err(|_| ()));
415+ wasm_bindgen_futures::spawn_local(async move {
416+ let _ = future.await;
429 /// Schedule a render to occur during the next animation frame and return a
420 /// Schedule a render to occur during the next animation frame and return a
@@ -431,41 +422,46 @@ impl VdomWeak {
432 /// If you don't want to do more things after the render completes, then use
423 /// If you don't want to do more things after the render completes, then use
433 /// `schedule_render` instead of `render`.
424 /// `schedule_render` instead of `render`.
434− pub fn render(&self) -> impl Future<Item = (), Error = VdomDroppedError> {
425+ pub fn render(&self) -> impl Future<Output = Result<(), VdomDroppedError>> {
435− futures::future::ok(self.inner.upgrade())
426+ let inner = self.inner.upgrade();
436− .and_then(|inner| inner.ok_or(()))
427+
437− .map_err(|_| VdomDroppedError {})
429+ let inner = inner.ok_or(VdomDroppedError {})?;
438− .and_then(|inner| {
430+
439− let promise = inner.shared.render_scheduled.take().unwrap_or_else(|| {
431+ let promise = inner.shared.render_scheduled.take().unwrap_or_else(|| {
440− js_sys::Promise::new(&mut |resolve, reject| {
432+ js_sys::Promise::new(&mut |resolve, reject| {
441− let vdom = VdomWeak {
433+ let vdom = VdomWeak {
442− inner: Rc::downgrade(&inner),
434+ inner: Rc::downgrade(&inner),
444− with_animation_frame(move || match vdom.inner.upgrade() {
437+ with_animation_frame(move || match vdom.inner.upgrade() {
445− None => {
438+ None => {
446− warn!("VdomWeak::render: vdom unmounted before we could render");
439+ warn!("VdomWeak::render: vdom unmounted before we could render");
447− let r = reject.call0(&JsValue::null());
440+ let r = reject.call0(&JsValue::null());
448− debug_assert!(r.is_ok());
441+ debug_assert!(r.is_ok());
450− Some(inner) => {
443+ Some(inner) => {
451− let mut exclusive = inner.exclusive.borrow_mut();
444+ let mut exclusive = inner.exclusive.borrow_mut();
452− exclusive.render();
445+ exclusive.render();
454− // We did the render, so take the promise away
447+ // We did the render, so take the promise away
455− // and let future `render` calls request new
448+ // and let future `render` calls request new
456− // animation frames.
449+ // animation frames.
457− let _ = inner.shared.render_scheduled.take();
450+ let _ = inner.shared.render_scheduled.take();
459− let r = resolve.call0(&JsValue::null());
452+ let r = resolve.call0(&JsValue::null());
460− debug_assert!(r.is_ok());
453+ debug_assert!(r.is_ok());
465− inner.shared.render_scheduled.set(Some(promise.clone()));
459+ inner.shared.render_scheduled.set(Some(promise.clone()));
466− JsFuture::from(promise)
461+ JsFuture::from(promise)
467− .map(|_| ())
463+ .map(drop)
468− .map_err(|_| VdomDroppedError {})
464+ .map_err(|_| VdomDroppedError {})