From ae5e2c6c734894d71b2034a498a858b7997c5d3d Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector0193@gmail.com>
Date: Thu, 21 May 2020 04:27:31 +0200
Subject: Introduce `Program` and `State`

---
 winit/src/application.rs | 535 +++++++++++++++++++----------------------------
 winit/src/debug/basic.rs | 211 -------------------
 winit/src/debug/null.rs  |  46 ----
 winit/src/lib.rs         |  14 +-
 4 files changed, 215 insertions(+), 591 deletions(-)
 delete mode 100644 winit/src/debug/basic.rs
 delete mode 100644 winit/src/debug/null.rs

(limited to 'winit/src')

diff --git a/winit/src/application.rs b/winit/src/application.rs
index ccab19f1..fcba47b3 100644
--- a/winit/src/application.rs
+++ b/winit/src/application.rs
@@ -1,9 +1,10 @@
 use crate::{
-    conversion, mouse, Cache, Clipboard, Command, Debug, Element, Executor,
-    Mode, Proxy, Runtime, Settings, Size, Subscription, UserInterface,
+    conversion, mouse, Clipboard, Command, Debug, Executor, Mode, Proxy,
+    Runtime, Settings, Size, Subscription,
 };
 use iced_graphics::window;
 use iced_graphics::Viewport;
+use iced_native::program::{self, Program};
 
 /// An interactive, native cross-platform application.
 ///
@@ -16,22 +17,7 @@ use iced_graphics::Viewport;
 ///
 /// When using an [`Application`] with the `debug` feature enabled, a debug view
 /// can be toggled by pressing `F12`.
-pub trait Application: Sized {
-    /// The graphics backend to use to draw the [`Application`].
-    ///
-    /// [`Application`]: trait.Application.html
-    type Compositor: window::Compositor;
-
-    /// The [`Executor`] that will run commands and subscriptions.
-    ///
-    /// [`Executor`]: trait.Executor.html
-    type Executor: Executor;
-
-    /// The type of __messages__ your [`Application`] will produce.
-    ///
-    /// [`Application`]: trait.Application.html
-    type Message: std::fmt::Debug + Send;
-
+pub trait Application: Program {
     /// The data needed to initialize your [`Application`].
     ///
     /// [`Application`]: trait.Application.html
@@ -60,18 +46,6 @@ pub trait Application: Sized {
     /// [`Application`]: trait.Application.html
     fn title(&self) -> String;
 
-    /// Handles a __message__ and updates the state of the [`Application`].
-    ///
-    /// 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.
-    ///
-    /// [`Application`]: trait.Application.html
-    /// [`Command`]: struct.Command.html
-    fn update(&mut self, message: Self::Message) -> Command<Self::Message>;
-
     /// Returns the event `Subscription` for the current state of the
     /// application.
     ///
@@ -85,19 +59,6 @@ pub trait Application: Sized {
         Subscription::none()
     }
 
-    /// Returns the widgets to display in the [`Application`].
-    ///
-    /// These widgets can produce __messages__ based on user interaction.
-    ///
-    /// [`Application`]: trait.Application.html
-    fn view(
-        &mut self,
-    ) -> Element<
-        '_,
-        Self::Message,
-        <Self::Compositor as window::Compositor>::Renderer,
-    >;
-
     /// Returns the current [`Application`] mode.
     ///
     /// The runtime will automatically transition your application if a new mode
@@ -109,309 +70,237 @@ pub trait Application: Sized {
     fn mode(&self) -> Mode {
         Mode::Windowed
     }
+}
 
-    /// Runs the [`Application`] with the provided [`Settings`].
-    ///
-    /// On native platforms, this method will take control of the current thread
-    /// and __will NOT return__.
-    ///
-    /// It should probably be that last thing you call in your `main` function.
-    ///
-    /// [`Application`]: trait.Application.html
-    /// [`Settings`]: struct.Settings.html
-    fn run(
-        settings: Settings<Self::Flags>,
-        backend_settings: <Self::Compositor as window::Compositor>::Settings,
-    ) where
-        Self: 'static,
-    {
-        use iced_graphics::window::Compositor as _;
-        use winit::{
-            event::{self, WindowEvent},
-            event_loop::{ControlFlow, EventLoop},
-        };
-
-        let mut debug = Debug::new();
-
-        debug.startup_started();
-        let event_loop = EventLoop::with_user_event();
-        let mut external_messages = Vec::new();
-
-        let mut runtime = {
-            let executor = Self::Executor::new().expect("Create executor");
-
-            Runtime::new(executor, Proxy::new(event_loop.create_proxy()))
-        };
-
-        let flags = settings.flags;
-        let (mut application, init_command) =
-            runtime.enter(|| Self::new(flags));
-        runtime.spawn(init_command);
-
-        let subscription = application.subscription();
-        runtime.track(subscription);
-
-        let mut title = application.title();
-        let mut mode = application.mode();
-
-        let window = settings
-            .window
-            .into_builder(&title, mode, event_loop.primary_monitor())
-            .build(&event_loop)
-            .expect("Open window");
-
-        let physical_size = window.inner_size();
-        let mut viewport = Viewport::with_physical_size(
-            Size::new(physical_size.width, physical_size.height),
-            window.scale_factor(),
-        );
-        let mut resized = false;
-
-        let clipboard = Clipboard::new(&window);
-        let mut compositor = Self::Compositor::new(backend_settings.clone());
-
-        let surface = compositor.create_surface(&window);
-        let mut renderer = compositor.create_renderer(backend_settings);
-
-        let mut swap_chain = compositor.create_swap_chain(
-            &surface,
-            physical_size.width,
-            physical_size.height,
-        );
-
-        let user_interface = build_user_interface(
-            &mut application,
-            Cache::default(),
-            &mut renderer,
-            viewport.logical_size(),
-            &mut debug,
-        );
-
-        debug.draw_started();
-        let mut primitive = user_interface.draw(&mut renderer);
-        debug.draw_finished();
-
-        let mut cache = Some(user_interface.into_cache());
-        let mut events = Vec::new();
-        let mut mouse_interaction = mouse::Interaction::default();
-        let mut modifiers = winit::event::ModifiersState::default();
-        debug.startup_finished();
-
-        window.request_redraw();
-
-        event_loop.run(move |event, _, control_flow| match event {
-            event::Event::MainEventsCleared => {
-                if events.is_empty() && external_messages.is_empty() {
-                    return;
-                }
-
-                let mut user_interface = build_user_interface(
-                    &mut application,
-                    cache.take().unwrap(),
-                    &mut renderer,
+pub fn run<A, E, C>(
+    settings: Settings<A::Flags>,
+    compositor_settings: C::Settings,
+) where
+    A: Application + 'static,
+    E: Executor + 'static,
+    C: window::Compositor<Renderer = A::Renderer> + 'static,
+{
+    use winit::{
+        event,
+        event_loop::{ControlFlow, EventLoop},
+    };
+
+    let mut debug = Debug::new();
+    debug.startup_started();
+
+    let event_loop = EventLoop::with_user_event();
+    let mut runtime = {
+        let executor = E::new().expect("Create executor");
+        let proxy = Proxy::new(event_loop.create_proxy());
+
+        Runtime::new(executor, proxy)
+    };
+
+    let flags = settings.flags;
+    let (application, init_command) = runtime.enter(|| A::new(flags));
+    runtime.spawn(init_command);
+
+    let subscription = application.subscription();
+    runtime.track(subscription);
+
+    let mut title = application.title();
+    let mut mode = application.mode();
+
+    let window = settings
+        .window
+        .into_builder(&title, mode, event_loop.primary_monitor())
+        .build(&event_loop)
+        .expect("Open window");
+
+    let clipboard = Clipboard::new(&window);
+    let mut mouse_interaction = mouse::Interaction::default();
+    let mut modifiers = winit::event::ModifiersState::default();
+
+    let physical_size = window.inner_size();
+    let mut viewport = Viewport::with_physical_size(
+        Size::new(physical_size.width, physical_size.height),
+        window.scale_factor(),
+    );
+    let mut resized = false;
+
+    let (mut compositor, mut renderer) = C::new(compositor_settings);
+
+    let surface = compositor.create_surface(&window);
+
+    let mut swap_chain = compositor.create_swap_chain(
+        &surface,
+        physical_size.width,
+        physical_size.height,
+    );
+
+    let mut state = program::State::new(
+        application,
+        viewport.logical_size(),
+        &mut renderer,
+        &mut debug,
+    );
+    debug.startup_finished();
+
+    event_loop.run(move |event, _, control_flow| match event {
+        event::Event::MainEventsCleared => {
+            let command = runtime.enter(|| {
+                state.update(
+                    clipboard.as_ref().map(|c| c as _),
                     viewport.logical_size(),
+                    &mut renderer,
                     &mut debug,
-                );
-
-                debug.event_processing_started();
-                events
-                    .iter()
-                    .cloned()
-                    .for_each(|event| runtime.broadcast(event));
-
-                let mut messages = user_interface.update(
-                    events.drain(..),
-                    clipboard
-                        .as_ref()
-                        .map(|c| c as &dyn iced_native::Clipboard),
-                    &renderer,
-                );
-                messages.extend(external_messages.drain(..));
-                debug.event_processing_finished();
-
-                if messages.is_empty() {
-                    debug.draw_started();
-                    primitive = user_interface.draw(&mut renderer);
-                    debug.draw_finished();
-
-                    cache = Some(user_interface.into_cache());
-                } else {
-                    // When there are messages, we are forced to rebuild twice
-                    // for now :^)
-                    let temp_cache = user_interface.into_cache();
-
-                    for message in messages {
-                        log::debug!("Updating");
-
-                        debug.log_message(&message);
+                )
+            });
 
-                        debug.update_started();
-                        let command =
-                            runtime.enter(|| application.update(message));
-                        runtime.spawn(command);
-                        debug.update_finished();
-                    }
+            // If the application was updated
+            if let Some(command) = command {
+                runtime.spawn(command);
 
-                    let subscription = application.subscription();
-                    runtime.track(subscription);
+                let program = state.program();
 
-                    // Update window title
-                    let new_title = application.title();
+                // Update subscriptions
+                let subscription = program.subscription();
+                runtime.track(subscription);
 
-                    if title != new_title {
-                        window.set_title(&new_title);
+                // Update window title
+                let new_title = program.title();
 
-                        title = new_title;
-                    }
+                if title != new_title {
+                    window.set_title(&new_title);
 
-                    // Update window mode
-                    let new_mode = application.mode();
-
-                    if mode != new_mode {
-                        window.set_fullscreen(conversion::fullscreen(
-                            window.current_monitor(),
-                            new_mode,
-                        ));
-
-                        mode = new_mode;
-                    }
-
-                    let user_interface = build_user_interface(
-                        &mut application,
-                        temp_cache,
-                        &mut renderer,
-                        viewport.logical_size(),
-                        &mut debug,
-                    );
-
-                    debug.draw_started();
-                    primitive = user_interface.draw(&mut renderer);
-                    debug.draw_finished();
-
-                    cache = Some(user_interface.into_cache());
+                    title = new_title;
                 }
 
-                window.request_redraw();
-            }
-            event::Event::UserEvent(message) => {
-                external_messages.push(message);
-            }
-            event::Event::RedrawRequested(_) => {
-                debug.render_started();
+                // Update window mode
+                let new_mode = program.mode();
 
-                if resized {
-                    let physical_size = viewport.physical_size();
-
-                    swap_chain = compositor.create_swap_chain(
-                        &surface,
-                        physical_size.width,
-                        physical_size.height,
-                    );
+                if mode != new_mode {
+                    window.set_fullscreen(conversion::fullscreen(
+                        window.current_monitor(),
+                        new_mode,
+                    ));
 
-                    resized = false;
+                    mode = new_mode;
                 }
+            }
 
-                let new_mouse_interaction = compositor.draw(
-                    &mut renderer,
-                    &mut swap_chain,
-                    &viewport,
-                    &primitive,
-                    &debug.overlay(),
+            window.request_redraw();
+        }
+        event::Event::UserEvent(message) => {
+            state.queue_message(message);
+        }
+        event::Event::RedrawRequested(_) => {
+            debug.render_started();
+
+            if resized {
+                let physical_size = viewport.physical_size();
+
+                swap_chain = compositor.create_swap_chain(
+                    &surface,
+                    physical_size.width,
+                    physical_size.height,
                 );
 
-                debug.render_finished();
+                resized = false;
+            }
 
-                if new_mouse_interaction != mouse_interaction {
-                    window.set_cursor_icon(conversion::mouse_interaction(
-                        new_mouse_interaction,
-                    ));
+            let new_mouse_interaction = compositor.draw(
+                &mut renderer,
+                &mut swap_chain,
+                &viewport,
+                state.primitive(),
+                &debug.overlay(),
+            );
 
-                    mouse_interaction = new_mouse_interaction;
-                }
+            debug.render_finished();
 
-                // TODO: Handle animations!
-                // Maybe we can use `ControlFlow::WaitUntil` for this.
-            }
-            event::Event::WindowEvent {
-                event: window_event,
-                ..
-            } => {
-                match window_event {
-                    WindowEvent::Resized(new_size) => {
-                        let size = Size::new(new_size.width, new_size.height);
-
-                        viewport = Viewport::with_physical_size(
-                            size,
-                            window.scale_factor(),
-                        );
-                        resized = true;
-                    }
-                    WindowEvent::CloseRequested => {
-                        *control_flow = ControlFlow::Exit;
-                    }
-                    WindowEvent::ModifiersChanged(new_modifiers) => {
-                        modifiers = new_modifiers;
-                    }
-                    #[cfg(target_os = "macos")]
-                    WindowEvent::KeyboardInput {
-                        input:
-                            winit::event::KeyboardInput {
-                                virtual_keycode:
-                                    Some(winit::event::VirtualKeyCode::Q),
-                                state: winit::event::ElementState::Pressed,
-                                ..
-                            },
-                        ..
-                    } if modifiers.logo() => {
-                        *control_flow = ControlFlow::Exit;
-                    }
-                    #[cfg(feature = "debug")]
-                    WindowEvent::KeyboardInput {
-                        input:
-                            winit::event::KeyboardInput {
-                                virtual_keycode:
-                                    Some(winit::event::VirtualKeyCode::F12),
-                                state: winit::event::ElementState::Pressed,
-                                ..
-                            },
-                        ..
-                    } => debug.toggle(),
-                    _ => {}
-                }
+            if new_mouse_interaction != mouse_interaction {
+                window.set_cursor_icon(conversion::mouse_interaction(
+                    new_mouse_interaction,
+                ));
 
-                if let Some(event) = conversion::window_event(
-                    &window_event,
-                    viewport.scale_factor(),
-                    modifiers,
-                ) {
-                    events.push(event);
-                }
+                mouse_interaction = new_mouse_interaction;
             }
-            _ => {
-                *control_flow = ControlFlow::Wait;
+
+            // TODO: Handle animations!
+            // Maybe we can use `ControlFlow::WaitUntil` for this.
+        }
+        event::Event::WindowEvent {
+            event: window_event,
+            ..
+        } => {
+            handle_window_event(
+                &window_event,
+                &window,
+                control_flow,
+                &mut modifiers,
+                &mut viewport,
+                &mut resized,
+                &mut debug,
+            );
+
+            if let Some(event) = conversion::window_event(
+                &window_event,
+                viewport.scale_factor(),
+                modifiers,
+            ) {
+                state.queue_event(event.clone());
+                runtime.broadcast(event);
             }
-        })
-    }
+        }
+        _ => {
+            *control_flow = ControlFlow::Wait;
+        }
+    })
 }
 
-fn build_user_interface<'a, A: Application>(
-    application: &'a mut A,
-    cache: Cache,
-    renderer: &mut <A::Compositor as window::Compositor>::Renderer,
-    size: Size,
-    debug: &mut Debug,
-) -> UserInterface<
-    'a,
-    A::Message,
-    <A::Compositor as window::Compositor>::Renderer,
-> {
-    debug.view_started();
-    let view = application.view();
-    debug.view_finished();
-
-    debug.layout_started();
-    let user_interface = UserInterface::build(view, size, cache, renderer);
-    debug.layout_finished();
-
-    user_interface
+pub fn handle_window_event(
+    event: &winit::event::WindowEvent<'_>,
+    window: &winit::window::Window,
+    control_flow: &mut winit::event_loop::ControlFlow,
+    modifiers: &mut winit::event::ModifiersState,
+    viewport: &mut Viewport,
+    resized: &mut bool,
+    _debug: &mut Debug,
+) {
+    use winit::{event::WindowEvent, event_loop::ControlFlow};
+
+    match event {
+        WindowEvent::Resized(new_size) => {
+            let size = Size::new(new_size.width, new_size.height);
+
+            *viewport =
+                Viewport::with_physical_size(size, window.scale_factor());
+            *resized = true;
+        }
+        WindowEvent::CloseRequested => {
+            *control_flow = ControlFlow::Exit;
+        }
+        WindowEvent::ModifiersChanged(new_modifiers) => {
+            *modifiers = *new_modifiers;
+        }
+        #[cfg(target_os = "macos")]
+        WindowEvent::KeyboardInput {
+            input:
+                winit::event::KeyboardInput {
+                    virtual_keycode: Some(winit::event::VirtualKeyCode::Q),
+                    state: winit::event::ElementState::Pressed,
+                    ..
+                },
+            ..
+        } if modifiers.logo() => {
+            *control_flow = ControlFlow::Exit;
+        }
+        #[cfg(feature = "debug")]
+        WindowEvent::KeyboardInput {
+            input:
+                winit::event::KeyboardInput {
+                    virtual_keycode: Some(winit::event::VirtualKeyCode::F12),
+                    state: winit::event::ElementState::Pressed,
+                    ..
+                },
+            ..
+        } => _debug.toggle(),
+        _ => {}
+    }
 }
diff --git a/winit/src/debug/basic.rs b/winit/src/debug/basic.rs
deleted file mode 100644
index d46edba6..00000000
--- a/winit/src/debug/basic.rs
+++ /dev/null
@@ -1,211 +0,0 @@
-use std::{collections::VecDeque, time};
-
-#[derive(Debug)]
-pub struct Debug {
-    is_enabled: bool,
-
-    startup_start: time::Instant,
-    startup_duration: time::Duration,
-
-    update_start: time::Instant,
-    update_durations: TimeBuffer,
-
-    view_start: time::Instant,
-    view_durations: TimeBuffer,
-
-    layout_start: time::Instant,
-    layout_durations: TimeBuffer,
-
-    event_start: time::Instant,
-    event_durations: TimeBuffer,
-
-    draw_start: time::Instant,
-    draw_durations: TimeBuffer,
-
-    render_start: time::Instant,
-    render_durations: TimeBuffer,
-
-    message_count: usize,
-    last_messages: VecDeque<String>,
-}
-
-impl Debug {
-    pub fn new() -> Self {
-        let now = time::Instant::now();
-
-        Self {
-            is_enabled: false,
-            startup_start: now,
-            startup_duration: time::Duration::from_secs(0),
-
-            update_start: now,
-            update_durations: TimeBuffer::new(200),
-
-            view_start: now,
-            view_durations: TimeBuffer::new(200),
-
-            layout_start: now,
-            layout_durations: TimeBuffer::new(200),
-
-            event_start: now,
-            event_durations: TimeBuffer::new(200),
-
-            draw_start: now,
-            draw_durations: TimeBuffer::new(200),
-
-            render_start: now,
-            render_durations: TimeBuffer::new(50),
-
-            message_count: 0,
-            last_messages: VecDeque::new(),
-        }
-    }
-
-    pub fn toggle(&mut self) {
-        self.is_enabled = !self.is_enabled;
-    }
-
-    pub fn startup_started(&mut self) {
-        self.startup_start = time::Instant::now();
-    }
-
-    pub fn startup_finished(&mut self) {
-        self.startup_duration = time::Instant::now() - self.startup_start;
-    }
-
-    pub fn update_started(&mut self) {
-        self.update_start = time::Instant::now();
-    }
-
-    pub fn update_finished(&mut self) {
-        self.update_durations
-            .push(time::Instant::now() - self.update_start);
-    }
-
-    pub fn view_started(&mut self) {
-        self.view_start = time::Instant::now();
-    }
-
-    pub fn view_finished(&mut self) {
-        self.view_durations
-            .push(time::Instant::now() - self.view_start);
-    }
-
-    pub fn layout_started(&mut self) {
-        self.layout_start = time::Instant::now();
-    }
-
-    pub fn layout_finished(&mut self) {
-        self.layout_durations
-            .push(time::Instant::now() - self.layout_start);
-    }
-
-    pub fn event_processing_started(&mut self) {
-        self.event_start = time::Instant::now();
-    }
-
-    pub fn event_processing_finished(&mut self) {
-        self.event_durations
-            .push(time::Instant::now() - self.event_start);
-    }
-
-    pub fn draw_started(&mut self) {
-        self.draw_start = time::Instant::now();
-    }
-
-    pub fn draw_finished(&mut self) {
-        self.draw_durations
-            .push(time::Instant::now() - self.draw_start);
-    }
-
-    pub fn render_started(&mut self) {
-        self.render_start = time::Instant::now();
-    }
-
-    pub fn render_finished(&mut self) {
-        self.render_durations
-            .push(time::Instant::now() - self.render_start);
-    }
-
-    pub fn log_message<Message: std::fmt::Debug>(&mut self, message: &Message) {
-        self.last_messages.push_back(format!("{:?}", message));
-
-        if self.last_messages.len() > 10 {
-            let _ = self.last_messages.pop_front();
-        }
-
-        self.message_count += 1;
-    }
-
-    pub fn overlay(&self) -> Vec<String> {
-        if !self.is_enabled {
-            return Vec::new();
-        }
-
-        let mut lines = Vec::new();
-
-        fn key_value<T: std::fmt::Debug>(key: &str, value: T) -> String {
-            format!("{} {:?}", key, value)
-        }
-
-        lines.push(format!(
-            "{} {} - {}",
-            env!("CARGO_PKG_NAME"),
-            env!("CARGO_PKG_VERSION"),
-            env!("CARGO_PKG_REPOSITORY"),
-        ));
-        lines.push(key_value("Startup:", self.startup_duration));
-        lines.push(key_value("Update:", self.update_durations.average()));
-        lines.push(key_value("View:", self.view_durations.average()));
-        lines.push(key_value("Layout:", self.layout_durations.average()));
-        lines.push(key_value(
-            "Event processing:",
-            self.event_durations.average(),
-        ));
-        lines.push(key_value(
-            "Primitive generation:",
-            self.draw_durations.average(),
-        ));
-        lines.push(key_value("Render:", self.render_durations.average()));
-        lines.push(key_value("Message count:", self.message_count));
-        lines.push(String::from("Last messages:"));
-        lines.extend(
-            self.last_messages.iter().map(|msg| format!("    {}", msg)),
-        );
-
-        lines
-    }
-}
-
-#[derive(Debug)]
-struct TimeBuffer {
-    head: usize,
-    size: usize,
-    contents: Vec<time::Duration>,
-}
-
-impl TimeBuffer {
-    fn new(capacity: usize) -> TimeBuffer {
-        TimeBuffer {
-            head: 0,
-            size: 0,
-            contents: vec![time::Duration::from_secs(0); capacity],
-        }
-    }
-
-    fn push(&mut self, duration: time::Duration) {
-        self.head = (self.head + 1) % self.contents.len();
-        self.contents[self.head] = duration;
-        self.size = (self.size + 1).min(self.contents.len());
-    }
-
-    fn average(&self) -> time::Duration {
-        let sum: time::Duration = if self.size == self.contents.len() {
-            self.contents[..].iter().sum()
-        } else {
-            self.contents[..self.size].iter().sum()
-        };
-
-        sum / self.size.max(1) as u32
-    }
-}
diff --git a/winit/src/debug/null.rs b/winit/src/debug/null.rs
deleted file mode 100644
index 2a9430cd..00000000
--- a/winit/src/debug/null.rs
+++ /dev/null
@@ -1,46 +0,0 @@
-#[derive(Debug)]
-pub struct Debug;
-
-impl Debug {
-    pub fn new() -> Self {
-        Self
-    }
-
-    pub fn startup_started(&mut self) {}
-
-    pub fn startup_finished(&mut self) {}
-
-    pub fn update_started(&mut self) {}
-
-    pub fn update_finished(&mut self) {}
-
-    pub fn view_started(&mut self) {}
-
-    pub fn view_finished(&mut self) {}
-
-    pub fn layout_started(&mut self) {}
-
-    pub fn layout_finished(&mut self) {}
-
-    pub fn event_processing_started(&mut self) {}
-
-    pub fn event_processing_finished(&mut self) {}
-
-    pub fn draw_started(&mut self) {}
-
-    pub fn draw_finished(&mut self) {}
-
-    pub fn render_started(&mut self) {}
-
-    pub fn render_finished(&mut self) {}
-
-    pub fn log_message<Message: std::fmt::Debug>(
-        &mut self,
-        _message: &Message,
-    ) {
-    }
-
-    pub fn overlay(&self) -> Vec<String> {
-        Vec::new()
-    }
-}
diff --git a/winit/src/lib.rs b/winit/src/lib.rs
index 9cf5dc0d..d3af9ae9 100644
--- a/winit/src/lib.rs
+++ b/winit/src/lib.rs
@@ -25,26 +25,18 @@
 pub use iced_native::*;
 pub use winit;
 
+pub mod application;
 pub mod conversion;
 pub mod settings;
 
-mod application;
 mod clipboard;
 mod mode;
 mod proxy;
 
-// We disable debug capabilities on release builds unless the `debug` feature
-// is explicitly enabled.
-#[cfg(feature = "debug")]
-#[path = "debug/basic.rs"]
-mod debug;
-#[cfg(not(feature = "debug"))]
-#[path = "debug/null.rs"]
-mod debug;
-
 pub use application::Application;
 pub use clipboard::Clipboard;
-pub use debug::Debug;
 pub use mode::Mode;
 pub use proxy::Proxy;
 pub use settings::Settings;
+
+pub use iced_graphics::Viewport;
-- 
cgit