// Run the application loop under the `RefreshSync` mode.
Run the application loop under the `RefreshSync` mode.
Run the application loop under the ` RefreshSync ` mode .
fn run_loop_mode_refresh_sync<M, E>(
    app: &mut App,
    mut model: M,
    loop_ctxt: &mut LoopContext<M, E>,
    mut minimum_update_interval: Duration,
    mut windows: Option<HashSet<window::Id>>,
) -> Break<M>
where
    M: 'static,
    E: LoopEvent,
{
    loop {
        // TODO: Properly consider the impact of an individual window blocking.
        for window_id in app.window_ids() {
            // Skip closed windows.
            if app.window(window_id).is_none() {
                continue;
            }
            cleanup_unused_gpu_resources_for_window(app, window_id);
            // Ensure swapchain dimensions are up to date.
            loop {
                if window_swapchain_needs_recreation(app, window_id) {
                    match recreate_window_swapchain(app, window_id) {
                        Ok(()) => break,
                        Err(vk::SwapchainCreationError::UnsupportedDimensions) => {
                            set_window_swapchain_needs_recreation(app, window_id, true);
                            continue;
                        }
                        Err(err) => panic!("{:?}", err),
                    }
                }
                break;
            }
            // Acquire the next image from the swapchain.
            let timeout = None;
            let swapchain = app.windows.borrow()[&window_id].swapchain.clone();
            let next_img = vk::swapchain::acquire_next_image(swapchain.swapchain.clone(), timeout);
            let (swapchain_image_index, swapchain_image_acquire_future) = match next_img {
                Ok(r) => r,
                Err(vk::swapchain::AcquireError::OutOfDate) => {
                    set_window_swapchain_needs_recreation(app, window_id, true);
                    continue;
                }
                Err(err) => panic!("{:?}", err),
            };
            // Process pending app events.
            let (new_model, exit, event_count) = poll_and_process_events(app, model, loop_ctxt);
            model = new_model;
            if exit {
                let reason = BreakReason::Exit;
                return Break { model, reason };
            }
            // Only emit an `update` if there was some user input or if it's been more than
            // `minimum_update_interval`.
            let now = Instant::now();
            let since_last = now.duration_since(loop_ctxt.last_update).into();
            let should_emit_update = windows
                .as_ref()
                .map(|ws| ws.contains(&window_id))
                .unwrap_or(true)
                && (event_count > 0 || since_last > minimum_update_interval);
            if should_emit_update {
                let since_start = now.duration_since(loop_ctxt.loop_start).into();
                app.duration.since_start = since_start;
                app.duration.since_prev_update = since_last;
                app.time = app.duration.since_start.secs() as _;
                // Emit an update event.
                let update = update_event(loop_ctxt.loop_start, &mut loop_ctxt.last_update);
                if let Some(event_fn) = loop_ctxt.event_fn {
                    let event = E::from(update.clone());
                    event_fn(&app, &mut model, event);
                }
                if let Some(update_fn) = loop_ctxt.update_fn {
                    update_fn(&app, &mut model, update);
                }
            }
            // If the window has been removed, continue.
            if app.window(window_id).is_none() {
                continue;
            }
            view_frame(
                app,
                &model,
                window_id,
                swapchain_image_index,
                swapchain_image_acquire_future,
                loop_ctxt.default_view.as_ref(),
            );
        }
        loop_ctxt.last_loop_end = Instant::now();
        // See if the loop mode has changed. If so, break.
        match app.loop_mode() {
            LoopMode::RefreshSync {
                minimum_update_interval: mli,
                windows: w,
            } => {
                minimum_update_interval = mli;
                windows = w;
            }
            loop_mode => {
                let reason = BreakReason::NewLoopMode(loop_mode);
                return Break { model, reason };
            }
        }
    }
}
fn run_loop_mode_refresh_sync < M , E > ( app : & mut App , mut model : M , loop_ctxt : & mut LoopContext < M , E > , mut minimum_update_interval : Duration , mut windows : Option < HashSet < window :: Id > > , ) -> Break < M > where M : ' static , E : LoopEvent , { loop { // TODO: Properly consider the impact of an individual window blocking. for window_id in app . window_ids ( ) { // Skip closed windows. if app . window ( window_id ) . is_none ( ) { continue ; } cleanup_unused_gpu_resources_for_window ( app , window_id ) ; // Ensure swapchain dimensions are up to date. loop { if window_swapchain_needs_recreation ( app , window_id ) { match recreate_window_swapchain ( app , window_id ) { Ok ( ( ) ) => break , Err ( vk :: SwapchainCreationError :: UnsupportedDimensions ) => { set_window_swapchain_needs_recreation ( app , window_id , true ) ; continue ; } Err ( err ) => panic ! ( " " err ) , } } break ; } // Acquire the next image from the swapchain. let timeout = None ; let swapchain = app . windows . borrow ( ) [ & window_id ] . swapchain . clone ( ) ; let next_img = vk :: swapchain :: acquire_next_image ( swapchain . swapchain . clone ( ) , timeout ) ; let ( swapchain_image_index , swapchain_image_acquire_future ) = match next_img { Ok ( r ) => r , Err ( vk :: swapchain :: AcquireError :: OutOfDate ) => { set_window_swapchain_needs_recreation ( app , window_id , true ) ; continue ; } Err ( err ) => panic ! ( " " err ) , } ; // Process pending app events. let ( new_model , exit , event_count ) = poll_and_process_events ( app , model , loop_ctxt ) ; model = new_model ; if exit { let reason = BreakReason :: Exit ; return Break { model , reason } ; } // Only emit an `update` if there was some user input or if it's been more than // `minimum_update_interval`. let now = Instant :: now ( ) ; let since_last = now . duration_since ( loop_ctxt . last_update ) . into ( ) ; let should_emit_update = windows . as_ref ( ) . map ( | ws | ws . contains ( & window_id ) ) . unwrap_or ( true ) && ( event_count > 0 || since_last > minimum_update_interval ) ; if should_emit_update { let since_start = now . duration_since ( loop_ctxt . loop_start ) . into ( ) ; app . duration . since_start = since_start ; app . duration . since_prev_update = since_last ; app . time = app . duration . since_start . secs ( ) as _ ; // Emit an update event. let update = update_event ( loop_ctxt . loop_start , & mut loop_ctxt . last_update ) ; if let Some ( event_fn ) = loop_ctxt . event_fn { let event = E :: from ( update . clone ( ) ) ; event_fn ( & app , & mut model , event ) ; } if let Some ( update_fn ) = loop_ctxt . update_fn { update_fn ( & app , & mut model , update ) ; } } // If the window has been removed, continue. if app . window ( window_id ) . is_none ( ) { continue ; } view_frame ( app , & model , window_id , swapchain_image_index , swapchain_image_acquire_future , loop_ctxt . default_view . as_ref ( ) , ) ; } loop_ctxt . last_loop_end = Instant :: now ( ) ; // See if the loop mode has changed. If so, break. match app . loop_mode ( ) { LoopMode :: RefreshSync { minimum_update_interval : mli , windows : w , } => { minimum_update_interval = mli ; windows = w ; } loop_mode => { let reason = BreakReason :: NewLoopMode ( loop_mode ) ; return Break { model , reason } ; } } } }
Run the application loop under the `RefreshSync` mode.
Run the application loop under the ` RefreshSync ` mode .
app
&mut App
model
M
loop_ctxt
&mut LoopContext<M, E>
minimum_update_interval
Duration
windows
Option<HashSet<window::Id>>