pub (super) async fn send_actions_to_window<RenderStream: Unpin+Stream<Item=Vec<RenderAction>>, EventPublisher: MessagePublisher<Message=DrawEvent>>(window: GlutinWindow, render_actions: RenderStream, events: EventPublisher, window_properties: WindowProperties) {
    // Read events from the render actions list
    let mut window          = window;
    let mut events          = events;
    let mut window_actions  = WindowUpdateStream { 
        render_stream:      render_actions, 
        title_stream:       follow(window_properties.title),
        size:               follow(window_properties.size),
        fullscreen:         follow(window_properties.fullscreen),
        has_decorations:    follow(window_properties.has_decorations),
        mouse_pointer:      follow(window_properties.mouse_pointer)
    };

    while let Some(next_action) = window_actions.next().await {
        match next_action {
            WindowUpdate::Render(next_action)   => {
                // Do nothing if there are no actions
                if next_action.len() == 0 {
                    continue;
                }

                let show_frame_buffer = if next_action[next_action.len() - 1] == RenderAction::ShowFrameBuffer {
                    // Typically this is the last instruction
                    true
                } else {
                    // Search harder if it's not the last instruction
                    next_action.iter().any(|item| item == &RenderAction::ShowFrameBuffer)
                };

                unsafe {
                    // TODO: report errors if we can't set the context rather than just stopping mysteriously

                    // Make the current context current
                    let current_context = window.context.take().expect("Window context");
                    let current_context = current_context.make_current();
                    let current_context = if let Ok(context) = current_context { context } else { break; };

                    // Get informtion about the current context
                    let size            = current_context.window().inner_size();
                    let width           = size.width as usize;
                    let height          = size.height as usize;

                    // Create the renderer (needs the OpenGL functions to be loaded)
                    if window.renderer.is_none() {
                        // Load the functions for the current context
                        // TODO: we're assuming they stay loaded to avoid loading them for every render, which might not be safe
                        // TODO: probably better to have the renderer load the functions itself (gl::load doesn't work well
                        // when we load GL twice, which could happen if we want to use the offscreen renderer)
                        gl::load_with(|symbol_name| {
                            current_context.get_proc_address(symbol_name)
                        });

                        // Create the renderer
                        window.renderer = Some(GlRenderer::new());
                    }

                    // Perform the rendering actions
                    window.renderer.as_mut().map(move |renderer| {
                        renderer.prepare_to_render_to_active_framebuffer(width, height);
                        renderer.render(next_action);
                    });

                    // Swap buffers to finish the drawing
                    if show_frame_buffer {
                        current_context.swap_buffers().ok();
                    }

                    // Release the current context
                    let context     = current_context.make_not_current();
                    let context     = if let Ok(context) = context { context } else { break; };
                    window.context  = Some(context);

                    // Notify that a new frame has been drawn
                    events.publish(DrawEvent::NewFrame).await;
                }
            }

            WindowUpdate::SetTitle(new_title)   => {
                window.context.as_ref().map(|ctxt| ctxt.window().set_title(&new_title));
            }

            WindowUpdate::SetSize((size_x, size_y)) => {
                window.context.as_ref().map(|ctxt| ctxt.window().set_inner_size(LogicalSize::new(size_x as f64, size_y as _)));
            }

            WindowUpdate::SetFullscreen(is_fullscreen) => {
                let fullscreen = if is_fullscreen { Some(Fullscreen::Borderless(None)) } else { None };
                window.context.as_ref().map(|ctxt| ctxt.window().set_fullscreen(fullscreen));
            }

            WindowUpdate::SetHasDecorations(decorations) => {
                window.context.as_ref().map(|ctxt| ctxt.window().set_decorations(decorations));
            }

            WindowUpdate::SetMousePointer(MousePointer::None) => {
                window.context.as_ref().map(|ctxt| ctxt.window().set_cursor_visible(false));
            }

            WindowUpdate::SetMousePointer(MousePointer::SystemDefault) => {
                window.context.as_ref().map(|ctxt| ctxt.window().set_cursor_visible(true));
            }
        }
    }

    // Window will close once the render actions are finished as we drop it here
}
///
/// Sends render actions to a window
///
Sends render actions to a window
Sends render actions to a window
pub (super) async fn send_actions_to_window<RenderStream: Unpin+Stream<Item=Vec<RenderAction>>, EventPublisher: MessagePublisher<Message=DrawEvent>>(window: GlutinWindow, render_actions: RenderStream, events: EventPublisher, window_properties: WindowProperties) {
    // Read events from the render actions list
    let mut window          = window;
    let mut events          = events;
    let mut window_actions  = WindowUpdateStream { 
        render_stream:      render_actions, 
        title_stream:       follow(window_properties.title),
        size:               follow(window_properties.size),
        fullscreen:         follow(window_properties.fullscreen),
        has_decorations:    follow(window_properties.has_decorations),
        mouse_pointer:      follow(window_properties.mouse_pointer)
    };
    while let Some(next_action) = window_actions.next().await {
        match next_action {
            WindowUpdate::Render(next_action)   => {
                // Do nothing if there are no actions
                if next_action.len() == 0 {
                    continue;
                }
                let show_frame_buffer = if next_action[next_action.len() - 1] == RenderAction::ShowFrameBuffer {
                    // Typically this is the last instruction
                    true
                } else {
                    // Search harder if it's not the last instruction
                    next_action.iter().any(|item| item == &RenderAction::ShowFrameBuffer)
                };
                unsafe {
                    // TODO: report errors if we can't set the context rather than just stopping mysteriously
                    // Make the current context current
                    let current_context = window.context.take().expect("Window context");
                    let current_context = current_context.make_current();
                    let current_context = if let Ok(context) = current_context { context } else { break; };
                    // Get informtion about the current context
                    let size            = current_context.window().inner_size();
                    let width           = size.width as usize;
                    let height          = size.height as usize;
                    // Create the renderer (needs the OpenGL functions to be loaded)
                    if window.renderer.is_none() {
                        // Load the functions for the current context
                        // TODO: we're assuming they stay loaded to avoid loading them for every render, which might not be safe
                        // TODO: probably better to have the renderer load the functions itself (gl::load doesn't work well
                        // when we load GL twice, which could happen if we want to use the offscreen renderer)
                        gl::load_with(|symbol_name| {
                            current_context.get_proc_address(symbol_name)
                        });
                        // Create the renderer
                        window.renderer = Some(GlRenderer::new());
                    }
                    // Perform the rendering actions
                    window.renderer.as_mut().map(move |renderer| {
                        renderer.prepare_to_render_to_active_framebuffer(width, height);
                        renderer.render(next_action);
                    });
                    // Swap buffers to finish the drawing
                    if show_frame_buffer {
                        current_context.swap_buffers().ok();
                    }
                    // Release the current context
                    let context     = current_context.make_not_current();
                    let context     = if let Ok(context) = context { context } else { break; };
                    window.context  = Some(context);
                    // Notify that a new frame has been drawn
                    events.publish(DrawEvent::NewFrame).await;
                }
            }
            WindowUpdate::SetTitle(new_title)   => {
                window.context.as_ref().map(|ctxt| ctxt.window().set_title(&new_title));
            }
            WindowUpdate::SetSize((size_x, size_y)) => {
                window.context.as_ref().map(|ctxt| ctxt.window().set_inner_size(LogicalSize::new(size_x as f64, size_y as _)));
            }
            WindowUpdate::SetFullscreen(is_fullscreen) => {
                let fullscreen = if is_fullscreen { Some(Fullscreen::Borderless(None)) } else { None };
                window.context.as_ref().map(|ctxt| ctxt.window().set_fullscreen(fullscreen));
            }
            WindowUpdate::SetHasDecorations(decorations) => {
                window.context.as_ref().map(|ctxt| ctxt.window().set_decorations(decorations));
            }
            WindowUpdate::SetMousePointer(MousePointer::None) => {
                window.context.as_ref().map(|ctxt| ctxt.window().set_cursor_visible(false));
            }
            WindowUpdate::SetMousePointer(MousePointer::SystemDefault) => {
                window.context.as_ref().map(|ctxt| ctxt.window().set_cursor_visible(true));
            }
        }
    }
    // Window will close once the render actions are finished as we drop it here
}
pub ( super ) async fn send_actions_to_window < RenderStream : Unpin + Stream < Item = Vec < RenderAction > > , EventPublisher : MessagePublisher < Message = DrawEvent > > ( window : GlutinWindow , render_actions : RenderStream , events : EventPublisher , window_properties : WindowProperties ) { // Read events from the render actions list let mut window = window ; let mut events = events ; let mut window_actions = WindowUpdateStream { render_stream : render_actions , title_stream : follow ( window_properties . title ) , size : follow ( window_properties . size ) , fullscreen : follow ( window_properties . fullscreen ) , has_decorations : follow ( window_properties . has_decorations ) , mouse_pointer : follow ( window_properties . mouse_pointer ) } ; while let Some ( next_action ) = window_actions . next ( ) . await { match next_action { WindowUpdate :: Render ( next_action ) => { // Do nothing if there are no actions if next_action . len ( ) == 0 { continue ; } let show_frame_buffer = if next_action [ next_action . len ( ) - 1 ] == RenderAction :: ShowFrameBuffer { // Typically this is the last instruction true } else { // Search harder if it's not the last instruction next_action . iter ( ) . any ( | item | item == & RenderAction :: ShowFrameBuffer ) } ; unsafe { // TODO: report errors if we can't set the context rather than just stopping mysteriously // Make the current context current let current_context = window . context . take ( ) . expect ( " " ) ; let current_context = current_context . make_current ( ) ; let current_context = if let Ok ( context ) = current_context { context } else { break ; } ; // Get informtion about the current context let size = current_context . window ( ) . inner_size ( ) ; let width = size . width as usize ; let height = size . height as usize ; // Create the renderer (needs the OpenGL functions to be loaded) if window . renderer . is_none ( ) { // Load the functions for the current context // TODO: we're assuming they stay loaded to avoid loading them for every render, which might not be safe // TODO: probably better to have the renderer load the functions itself (gl::load doesn't work well // when we load GL twice, which could happen if we want to use the offscreen renderer) gl :: load_with ( | symbol_name | { current_context . get_proc_address ( symbol_name ) } ) ; // Create the renderer window . renderer = Some ( GlRenderer :: new ( ) ) ; } // Perform the rendering actions window . renderer . as_mut ( ) . map ( move | renderer | { renderer . prepare_to_render_to_active_framebuffer ( width , height ) ; renderer . render ( next_action ) ; } ) ; // Swap buffers to finish the drawing if show_frame_buffer { current_context . swap_buffers ( ) . ok ( ) ; } // Release the current context let context = current_context . make_not_current ( ) ; let context = if let Ok ( context ) = context { context } else { break ; } ; window . context = Some ( context ) ; // Notify that a new frame has been drawn events . publish ( DrawEvent :: NewFrame ) . await ; } } WindowUpdate :: SetTitle ( new_title ) => { window . context . as_ref ( ) . map ( | ctxt | ctxt . window ( ) . set_title ( & new_title ) ) ; } WindowUpdate :: SetSize ( ( size_x , size_y ) ) => { window . context . as_ref ( ) . map ( | ctxt | ctxt . window ( ) . set_inner_size ( LogicalSize :: new ( size_x as f64 , size_y as _ ) ) ) ; } WindowUpdate :: SetFullscreen ( is_fullscreen ) => { let fullscreen = if is_fullscreen { Some ( Fullscreen :: Borderless ( None ) ) } else { None } ; window . context . as_ref ( ) . map ( | ctxt | ctxt . window ( ) . set_fullscreen ( fullscreen ) ) ; } WindowUpdate :: SetHasDecorations ( decorations ) => { window . context . as_ref ( ) . map ( | ctxt | ctxt . window ( ) . set_decorations ( decorations ) ) ; } WindowUpdate :: SetMousePointer ( MousePointer :: None ) => { window . context . as_ref ( ) . map ( | ctxt | ctxt . window ( ) . set_cursor_visible ( false ) ) ; } WindowUpdate :: SetMousePointer ( MousePointer :: SystemDefault ) => { window . context . as_ref ( ) . map ( | ctxt | ctxt . window ( ) . set_cursor_visible ( true ) ) ; } } } // Window will close once the render actions are finished as we drop it here }
Sends render actions to a window
Sends render actions to a window
window
GlutinWindow
render_actions
RenderStream
events
EventPublisher
window_properties
WindowProperties