Introduce window::Id to timing::Stage in iced_sentinel

This commit is contained in:
Héctor Ramón Jiménez 2024-02-28 15:25:45 +01:00
parent caecbf20ef
commit 8591e5a148
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
8 changed files with 97 additions and 62 deletions

View file

@ -2,10 +2,11 @@ use std::hash::Hash;
use std::sync::atomic::{self, AtomicU64};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
/// The id of the window.
///
/// Internally Iced reserves `window::Id::MAIN` for the first window spawned.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Id(u64);
static COUNT: AtomicU64 = AtomicU64::new(1);

View file

@ -1,6 +1,7 @@
pub use iced_core as core;
pub use iced_style as style;
use crate::core::window;
use crate::style::theme;
pub use internal::Timer;
@ -21,33 +22,34 @@ pub fn update_time() -> Timer {
internal::update_time()
}
pub fn view_time() -> Timer {
internal::view_time()
pub fn view_time(window: window::Id) -> Timer {
internal::view_time(window)
}
pub fn layout_time() -> Timer {
internal::layout_time()
pub fn layout_time(window: window::Id) -> Timer {
internal::layout_time(window)
}
pub fn interact_time() -> Timer {
internal::interact_time()
pub fn interact_time(window: window::Id) -> Timer {
internal::interact_time(window)
}
pub fn draw_time() -> Timer {
internal::draw_time()
pub fn draw_time(window: window::Id) -> Timer {
internal::draw_time(window)
}
pub fn render_time() -> Timer {
internal::render_time()
pub fn render_time(window: window::Id) -> Timer {
internal::render_time(window)
}
pub fn time(name: impl AsRef<str>) -> Timer {
internal::time(name)
pub fn time(window: window::Id, name: impl AsRef<str>) -> Timer {
internal::time(window, name)
}
#[cfg(feature = "enable")]
mod internal {
use crate::core::time::Instant;
use crate::core::window;
use crate::style::theme;
use iced_sentinel::client::{self, Client};
@ -74,28 +76,28 @@ mod internal {
timer(timing::Stage::Update)
}
pub fn view_time() -> Timer {
timer(timing::Stage::View)
pub fn view_time(window: window::Id) -> Timer {
timer(timing::Stage::View(window))
}
pub fn layout_time() -> Timer {
timer(timing::Stage::Layout)
pub fn layout_time(window: window::Id) -> Timer {
timer(timing::Stage::Layout(window))
}
pub fn interact_time() -> Timer {
timer(timing::Stage::Interact)
pub fn interact_time(window: window::Id) -> Timer {
timer(timing::Stage::Interact(window))
}
pub fn draw_time() -> Timer {
timer(timing::Stage::Draw)
pub fn draw_time(window: window::Id) -> Timer {
timer(timing::Stage::Draw(window))
}
pub fn render_time() -> Timer {
timer(timing::Stage::Render)
pub fn render_time(window: window::Id) -> Timer {
timer(timing::Stage::Render(window))
}
pub fn time(name: impl AsRef<str>) -> Timer {
timer(timing::Stage::Custom(name.as_ref().to_owned()))
pub fn time(window: window::Id, name: impl AsRef<str>) -> Timer {
timer(timing::Stage::Custom(window, name.as_ref().to_owned()))
}
fn timer(stage: timing::Stage) -> Timer {
@ -140,6 +142,7 @@ mod internal {
#[cfg(not(feature = "enable"))]
mod internal {
use crate::core::window;
use crate::style::theme;
pub fn theme_changed(_palette: theme::Palette) {}
@ -152,27 +155,27 @@ mod internal {
Timer
}
pub fn view_time() -> Timer {
pub fn view_time(_window: window::Id) -> Timer {
Timer
}
pub fn layout_time() -> Timer {
pub fn layout_time(_window: window::Id) -> Timer {
Timer
}
pub fn interact_time() -> Timer {
pub fn interact_time(_window: window::Id) -> Timer {
Timer
}
pub fn draw_time() -> Timer {
pub fn draw_time(_window: window::Id) -> Timer {
Timer
}
pub fn render_time() -> Timer {
pub fn render_time(_window: window::Id) -> Timer {
Timer
}
pub fn time(_name: impl AsRef<str>) -> Timer {
pub fn time(_window: window::Id, _name: impl AsRef<str>) -> Timer {
Timer
}

View file

@ -1,6 +1,35 @@
//! A multi-window application.
pub mod program;
pub mod state;
use crate::core::text;
use crate::core::window;
use crate::core::{Element, Renderer};
use crate::Command;
pub use program::Program;
pub use state::State;
/// The core of a user interface for a multi-window application following The Elm Architecture.
pub trait Program: Sized {
/// The graphics backend to use to draw the [`Program`].
type Renderer: Renderer + text::Renderer;
/// The type of __messages__ your [`Program`] will produce.
type Message: std::fmt::Debug + Send;
/// The theme used to draw the [`Program`].
type Theme;
/// Handles a __message__ and updates the state of the [`Program`].
///
/// This is where you define your __update logic__. All the __messages__,
/// produced by either user interactions or commands, will be handled by
/// this method.
///
/// Any [`Command`] returned will be executed immediately in the
/// background by shells.
fn update(&mut self, message: Self::Message) -> Command<Self::Message>;
/// Returns the widgets to display in the [`Program`] for the `window`.
///
/// These widgets can produce __messages__ based on user interaction.
fn view(
&self,
window: window::Id,
) -> Element<'_, Self::Message, Self::Theme, Self::Renderer>;
}

View file

@ -98,12 +98,12 @@ where
bounds,
);
let interact_timer = debug::interact_time();
let mut messages = Vec::new();
let uncaptured_events = user_interfaces.iter_mut().fold(
vec![],
|mut uncaptured_events, ui| {
let interact_timer = debug::interact_time();
let (_, event_statuses) = ui.update(
&self.queued_events,
cursor,
@ -111,6 +111,7 @@ where
clipboard,
&mut messages,
);
interact_timer.finish();
uncaptured_events.extend(
self.queued_events
@ -128,7 +129,6 @@ where
self.queued_events.clear();
messages.append(&mut self.queued_messages);
drop(interact_timer);
let commands = if messages.is_empty() {
let draw_timer = debug::draw_time();

View file

@ -2,6 +2,7 @@ use crate::core::event::{self, Event};
use crate::core::mouse;
use crate::core::renderer;
use crate::core::widget::operation::{self, Operation};
use crate::core::window;
use crate::core::{Clipboard, Size};
use crate::debug;
use crate::user_interface::{self, UserInterface};
@ -101,7 +102,7 @@ where
bounds,
);
let interact_timer = debug::interact_time();
let interact_timer = debug::interact_time(window::Id::MAIN);
let mut messages = Vec::new();
let (_, event_statuses) = user_interface.update(
@ -127,7 +128,7 @@ where
drop(interact_timer);
let command = if messages.is_empty() {
let draw_timer = debug::draw_time();
let draw_timer = debug::draw_time(window::Id::MAIN);
self.mouse_interaction =
user_interface.draw(renderer, theme, style, cursor);
drop(draw_timer);
@ -158,7 +159,7 @@ where
bounds,
);
let draw_timer = debug::draw_time();
let draw_timer = debug::draw_time(window::Id::MAIN);
self.mouse_interaction =
user_interface.draw(renderer, theme, style, cursor);
drop(draw_timer);
@ -213,11 +214,11 @@ fn build_user_interface<'a, P: Program>(
renderer: &mut P::Renderer,
size: Size,
) -> UserInterface<'a, P::Message, P::Theme, P::Renderer> {
let view_timer = debug::view_time();
let view_timer = debug::view_time(window::Id::MAIN);
let view = program.view();
drop(view_timer);
let layout_timer = debug::layout_time();
let layout_timer = debug::layout_time(window::Id::MAIN);
let user_interface = UserInterface::build(view, size, cache, renderer);
drop(layout_timer);

View file

@ -1,4 +1,5 @@
use crate::core::time::Duration;
use crate::core::window;
use serde::{Deserialize, Serialize};
@ -16,10 +17,10 @@ pub struct Timing {
pub enum Stage {
Boot,
Update,
View,
Layout,
Interact,
Draw,
Render,
Custom(String),
View(window::Id),
Layout(window::Id),
Interact(window::Id),
Draw(window::Id),
Render(window::Id),
Custom(window::Id, String),
}

View file

@ -379,7 +379,7 @@ async fn run_instance<A, E, C>(
if viewport_version != current_viewport_version {
let logical_size = state.logical_size();
let layout_timer = debug::layout_time();
let layout_timer = debug::layout_time(window::Id::MAIN);
user_interface = ManuallyDrop::new(
ManuallyDrop::into_inner(user_interface)
.relayout(logical_size, &mut renderer),
@ -431,7 +431,7 @@ async fn run_instance<A, E, C>(
runtime.broadcast(redraw_event, core::event::Status::Ignored);
let draw_timer = debug::draw_time();
let draw_timer = debug::draw_time(window::Id::MAIN);
let new_mouse_interaction = user_interface.draw(
&mut renderer,
state.theme(),
@ -451,7 +451,7 @@ async fn run_instance<A, E, C>(
mouse_interaction = new_mouse_interaction;
}
let render_timer = debug::render_time();
let render_timer = debug::render_time(window::Id::MAIN);
match compositor.present(
&mut renderer,
&mut surface,
@ -499,7 +499,7 @@ async fn run_instance<A, E, C>(
continue;
}
let interact_timer = debug::interact_time();
let interact_timer = debug::interact_time(window::Id::MAIN);
let (interface_state, statuses) = user_interface.update(
&events,
state.cursor(),
@ -600,11 +600,11 @@ pub fn build_user_interface<'a, A: Application>(
where
A::Theme: StyleSheet,
{
let view_timer = debug::view_time();
let view_timer = debug::view_time(window::Id::MAIN);
let view = application.view();
view_timer.finish();
let layout_timer = debug::layout_time();
let layout_timer = debug::layout_time(window::Id::MAIN);
let user_interface = UserInterface::build(view, size, cache, renderer);
layout_timer.finish();

View file

@ -509,7 +509,7 @@ async fn run_instance<A, E, C>(
&mut messages,
);
let draw_timer = debug::draw_time();
let draw_timer = debug::draw_time(id);
let new_mouse_interaction = ui.draw(
&mut window.renderer,
window.state.theme(),
@ -565,7 +565,7 @@ async fn run_instance<A, E, C>(
{
let logical_size = window.state.logical_size();
let layout_time = debug::layout_time();
let layout_time = debug::layout_time(id);
let ui = user_interfaces
.remove(&id)
.expect("Remove user interface");
@ -576,7 +576,7 @@ async fn run_instance<A, E, C>(
);
layout_time.finish();
let draw_time = debug::draw_time();
let draw_time = debug::draw_time(id);
let new_mouse_interaction = user_interfaces
.get_mut(&id)
.expect("Get user interface")
@ -612,7 +612,7 @@ async fn run_instance<A, E, C>(
window.state.viewport_version();
}
let render_time = debug::render_time();
let render_time = debug::render_time(id);
match compositor.present(
&mut window.renderer,
&mut window.surface,
@ -691,10 +691,10 @@ async fn run_instance<A, E, C>(
continue;
}
let interact_time = debug::interact_time();
let mut uis_stale = false;
for (id, window) in window_manager.iter_mut() {
let interact_time = debug::interact_time(id);
let mut window_events = vec![];
events.retain(|(window_id, event)| {
@ -737,8 +737,8 @@ async fn run_instance<A, E, C>(
{
runtime.broadcast(event, status);
}
}
interact_time.finish();
}
// TODO mw application update returns which window IDs to update
if !messages.is_empty() || uis_stale {
@ -806,11 +806,11 @@ fn build_user_interface<'a, A: Application>(
where
A::Theme: StyleSheet,
{
let view_timer = debug::view_time();
let view_timer = debug::view_time(id);
let view = application.view(id);
view_timer.finish();
let layout_timer = debug::layout_time();
let layout_timer = debug::layout_time(id);
let user_interface = UserInterface::build(view, size, cache, renderer);
layout_timer.finish();