macro_rules! _run_driver_step_run_frame_body {
(@check
$runtime:expr, $backend:expr, $app:expr, $renderer:expr, $presenter:expr,
scene_of($scene_of:expr), $events:ident, $control:ident,
$on_continue:expr, $on_stop:expr $(,$break:expr)?) => {
if !$runtime.can_advance() {
return Err(RunDriverFrameError::InvalidPhase($runtime.phase()));
}
$crate::_run_driver_step_run_frame_body!(@body
$runtime, $backend, $app, $renderer, $presenter,
$scene_of(&*$app), $events, $control,
$on_continue, $on_stop $(,$break)?
);
};
(@check
$runtime:expr, $backend:expr, $app:expr, $renderer:expr, $presenter:expr,
scene($scene:expr), $events:ident, $control:ident,
$on_continue:expr, $on_stop:expr $(,$break:expr)?) => {
if !$runtime.can_advance() {
return Err(RunDriverFrameError::InvalidPhase($runtime.phase()));
}
$crate::_run_driver_step_run_frame_body!(@body
$runtime, $backend, $app, $renderer, $presenter,
$scene, $events, $control,
$on_continue, $on_stop $(,$break)?
);
};
($runtime:expr, $backend:expr, $app:expr, $renderer:expr, $presenter:expr,
scene_of($scene_of:expr), $events:ident, $control:ident,
$on_continue:expr, $on_stop:expr $(,$break:expr)?) => {
$crate::_run_driver_step_run_frame_body!(@body
$runtime, $backend, $app, $renderer, $presenter,
$scene_of(&*$app), $events, $control,
$on_continue, $on_stop $(,$break)?
);
};
($runtime:expr, $backend:expr, $app:expr, $renderer:expr, $presenter:expr,
scene($scene:expr), $events:ident, $control:ident,
$on_continue:expr, $on_stop:expr $(,$break:expr)?) => {
$crate::_run_driver_step_run_frame_body!(@body
$runtime, $backend, $app, $renderer, $presenter,
$scene, $events, $control,
$on_continue, $on_stop $(,$break)?
);
};
(@body
$runtime:expr, $backend:expr, $app:expr, $renderer:expr, $presenter:expr,
$scene_or_projection:expr, $events:ident, $control:ident,
$on_continue:expr, $on_stop:expr $(,$break:expr)?) => {
let written = $backend.collect_events($events)
.map_err(RunDriverFrameError::Backend)?;
let $events = &$events[..written];
let step = RunStep::new($runtime.tick(), $runtime.phase(), $events);
let $control = $app.run_step(step)
.map_err(RunDriverFrameError::App)?;
let mut frame = $backend.frame($runtime.tick(), $runtime.phase(), $events);
let scene = $scene_or_projection;
let artifact = $renderer.run_render(&mut frame, scene)
.map_err(RunDriverFrameError::Render)?;
$presenter.run_present(&mut frame, artifact)
.map_err(RunDriverFrameError::Present)?;
match $control {
RunControl::Continue => { $on_continue; }
RunControl::Stop => {
$on_stop;
$($break)?
}
}
};
}
pub(crate) use _run_driver_step_run_frame_body;