fluffl 0.0.1

A cross-platform multimedia layer that exposes opengl,sockets,and audio utilities for desktop and broswer
Documentation
use super::event_util::FlufflEvent;
use super::*;

use event_util::constants::*;

use std::sync::Arc;
use std::rc::Rc;
use std::cell::{Cell,RefCell};


use glow::*;
use sdl2::event::Event;
use sdl2::keyboard::Scancode; 
use sdl2::mouse::MouseButton; 

/// a very simple macro to shorten up text a little bit
macro_rules! push_event {
    ( $event_pump:ident , $event:expr  ) => {
        $event_pump.as_mut().unwrap().push_event($event)
    };
}


#[allow(dead_code)]
/// A cross-platform window handler, use it to set up opengl and listen to input devices in a platform
/// agnostic fashion
pub struct FlufflWindow {
    glue_event: Option<FlufflEvent>,
    sdl_state: sdl2::Sdl,
    sdl_gl_context: sdl2::video::GLContext,
    sdl_event_pump: sdl2::EventPump,
    gl: Arc<Box<Context>>,
    render_loop: Option<RenderLoop<sdl2::video::Window>>,
    audio_context: Arc<RefCell<FlufflAudioContext>> ,
    pub video_ss: sdl2::VideoSubsystem, 
    window_width:u32,
    window_height:u32,
}

impl FlufflWindow {
    //moves renderloop out of glue_window and calls it
    fn get_render_loop(&mut self) -> impl glow::HasRenderLoop {
        self.render_loop.take().unwrap()
    }

    /// Loops infinitely unless caller mutates `running` to false. Just executes the user defined taske over and over while also \
    /// doing basic matenence for events and the window 
    /// # Arguments
    /// * `fluffl_window` an initalized fluffl window
    /// * `app_state` is the variables and memory that is needed throughout the entire lifespan of the program
    /// * `core_loop` is the user-defined 'main_loop'
    pub fn main_loop<Loop,State>(mut fluffl_window:Self, app_state:State,core_loop: impl Fn(FlufflWindowPtr,Rc<Cell<bool>>,Rc<RefCell<State>>)->Loop + Copy + 'static)
    where
        Loop: std::future::Future<Output=()>,
        State: 'static,
    {
        let render_loop = fluffl_window.get_render_loop();
        let window_ptr = FlufflWindowPtr { ptr: Arc::new(RefCell::new(fluffl_window)) };
        let aux_data_ptr = Rc::new(RefCell::new(app_state));
        
        render_loop.run(move |running| {
            window_ptr.window_mut().collect_events();
            let local_run = Rc::new(Cell::new(*running));
            let f = core_loop(window_ptr.clone(), local_run.clone(), aux_data_ptr.clone()) ;
            futures::executor::block_on( f ) ;
            *running = local_run.get()
        });
    }
}

impl WindowManager for FlufflWindow {
    fn width(&self)->u32{
        self.window_width
    }

    fn height(&self)->u32{
        self.window_height
    }
    fn audio_context(&self) ->Arc<RefCell<FlufflAudioContext>> {
        self.audio_context.clone()
    }

    fn gl(&self) ->Arc<Box<Context>> {
        self.gl.clone()
    }
    fn get_events(&mut self) -> &mut FlufflEvent {
        self.glue_event.as_mut().unwrap()
    }

    fn init(config: &str) -> Result<Self, FlufflError> {
        let settings = FlufflWindowConfigs::new().parser_config_file(config);

        // Create a context from a sdl2 window
        let sdl = sdl2::init()?;
        let audio = sdl.audio()?;
        let video = sdl.video()?;

        let gl_attr = video.gl_attr();
        gl_attr.set_context_profile(sdl2::video::GLProfile::Core);
        gl_attr.set_context_version(settings.context_major, settings.context_minor);

        let win_builder =  video
            .window(settings.title.as_str(), settings.width, settings.height);

        let build_window_according_to_settings = |mut builder: sdl2::video::WindowBuilder| {
            let mut  builder_ref = builder.opengl(); 
            if settings.resizable {
                builder_ref = builder.resizable();
            }
            if settings.resizable == false && settings.fullscreen {
                builder_ref = builder.fullscreen();
            }
            builder_ref.build()
        };

        let window = build_window_according_to_settings(win_builder)?;

        let gl_context = window.gl_create_context()?;
        let context = unsafe{
            glow::Context::from_loader_function(|s| video.gl_get_proc_address(s) as *const _)};

        let render_loop = Some(glow::RenderLoop::<sdl2::video::Window>::from_sdl_window(
            window,
        ));

        let event_loop = sdl.event_pump()?;

        Ok(Self {
            sdl_gl_context: gl_context,
            sdl_event_pump: event_loop,
            glue_event: Some(FlufflEvent::new()),
            gl: Arc::new(Box::new(context)),
            render_loop,
            window_width:settings.width,
            window_height:settings.height, 
            sdl_state: sdl, 
            audio_context: Arc::new(RefCell::new(FlufflAudioContext{  audio_ss:audio })), 
            video_ss:video,
        })
    }

    
}

impl From<String> for FlufflError {
    fn from(string: String) -> Self {
        Self::WindowInitError(string)
    }
}

impl From<sdl2::video::WindowBuildError> for FlufflError {
    fn from(build_err: sdl2::video::WindowBuildError) -> Self {
        FlufflError::WindowInitError(build_err.to_string())
    }
}

impl HasEventCollection for FlufflWindow{
    //Basically passes events from SDL's event queue into a more Generic Queue
    fn collect_events(&mut self) {
        let mut gevent = self.glue_event.take();
        let mut width_update = None; 
        let mut height_update = None;
        self.sdl_event_pump
            .poll_iter()
            .for_each(|event| match event {
                Event::Quit { .. } => {
                    push_event!(gevent,EventKind::Quit);
                }
                Event::Window {  win_event , ..} =>{
                    match win_event {
                        sdl2::event::WindowEvent::Resized(width,height) =>{
                            push_event!(gevent,EventKind::Resize{width,height} );
                            width_update = Some(width as u32); 
                            height_update = Some(height as u32); 
                        },
                        _ => (),
                    }   
                }
                
                Event::KeyUp { scancode, .. } => {
                    match scancode{
                        Some(Scancode::A) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_A } ),
                        Some(Scancode::B) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_B } ),
                        Some(Scancode::C) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_C } ),
                        Some(Scancode::D) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_D } ),
                        Some(Scancode::E) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_E } ),
                        Some(Scancode::F) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_F } ),
                        Some(Scancode::G) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_G } ),
                        Some(Scancode::H) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_H } ),
                        Some(Scancode::I) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_I } ),
                        Some(Scancode::J) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_J } ),
                        Some(Scancode::K) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_K } ),
                        Some(Scancode::L) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_L } ),
                        Some(Scancode::M) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_M } ),
                        Some(Scancode::N) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_N } ),
                        Some(Scancode::O) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_O } ),
                        Some(Scancode::P) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_P } ),
                        Some(Scancode::Q) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_Q } ),
                        Some(Scancode::R) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_R } ),
                        Some(Scancode::S) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_S } ),
                        Some(Scancode::T) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_T } ),
                        Some(Scancode::U) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_U } ),
                        Some(Scancode::V) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_V } ),
                        Some(Scancode::W) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_W } ),
                        Some(Scancode::X) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_X } ),
                        Some(Scancode::Y) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_Y } ),
                        Some(Scancode::Z) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::KEY_Z } ),
                        Some(Scancode::Num0) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::NUM_0 } ),
                        Some(Scancode::Num1) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::NUM_1 } ),
                        Some(Scancode::Num2) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::NUM_2 } ),
                        Some(Scancode::Num3) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::NUM_3 } ),
                        Some(Scancode::Num4) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::NUM_4 } ),
                        Some(Scancode::Num5) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::NUM_5 } ),
                        Some(Scancode::Num6) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::NUM_6 } ),
                        Some(Scancode::Num7) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::NUM_7 } ),
                        Some(Scancode::Num8) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::NUM_8 } ),
                        Some(Scancode::Num9) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::NUM_9 } ),
                        Some(Scancode::Return) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::ENTER } ),
                        Some(Scancode::Escape) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::ESC } ),
                        Some(Scancode::Tab) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::TAB} ),
                        Some(Scancode::LShift) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::SHIFT_L} ),
                        Some(Scancode::RShift) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::SHIFT_R} ),
                        Some(Scancode::Space) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::SPACE } ),
                        Some(Scancode::Minus) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::MINUS } ),
                        Some(Scancode::Equals) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::EQUALS } ),
                        Some(Scancode::LeftBracket) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::BRACKET_LEFT } ),
                        Some(Scancode::RightBracket) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::BRAKET_RIGHT } ),
                        Some(Scancode::Backslash) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::BACKSLASH } ),
                        Some(Scancode::NonUsHash) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::NUM_2 } ),
                        Some(Scancode::Semicolon) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::COLON } ),
                        Some(Scancode::Apostrophe) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::QUOTE } ),
                        Some(Scancode::Grave) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::BACK_QUOTE } ),
                        Some(Scancode::Comma) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::COMMA } ),
                        Some(Scancode::Period) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::PERIOD } ),
                        Some(Scancode::Slash) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::FORWARD_SLASH } ),
                        Some(Scancode::CapsLock) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::CAPSLOCK } ),
                        Some(Scancode::LCtrl) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::CTRL_L } ),
                        Some(Scancode::RCtrl) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::CTRL_R } ),
                        Some(Scancode::LAlt) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::ALT_L } ),
                        Some(Scancode::RAlt) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::ALT_R } ),
                        Some(Scancode::F1) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::F1 } ),
                        Some(Scancode::F2) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::F2 } ),
                        Some(Scancode::F3) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::F3 } ),
                        Some(Scancode::F4) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::F4 } ),
                        Some(Scancode::F5) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::F5 } ),
                        Some(Scancode::F6) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::F6 } ),
                        Some(Scancode::F7) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::F7 } ),
                        Some(Scancode::F8) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::F8 } ),
                        Some(Scancode::F9) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::F9 } ),
                        Some(Scancode::F10) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::F10 } ),
                        Some(Scancode::F11) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::F11 } ),
                        Some(Scancode::F12) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::F12 } ),
                        Some(Scancode::PrintScreen) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::PRINT_SCREEN } ),
                        Some(Scancode::ScrollLock) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::SCROLL_LOCK } ),
                        Some(Scancode::Pause) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::PAUSE } ),
                        Some(Scancode::Delete) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::DELETE } ),
                        Some(Scancode::End) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::END } ),
                        Some(Scancode::PageDown) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::PAGE_DOWN } ),
                        Some(Scancode::PageUp) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::PAGE_UP } ),
                        Some(Scancode::Left) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::ARROW_LEFT } ),
                        Some(Scancode::Right) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::ARROW_RIGHT } ),
                        Some(Scancode::Up) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::ARROW_UP } ),
                        Some(Scancode::Down) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::ARROW_DOWN } ),
                        Some(Scancode::Backspace) => push_event!(gevent,EventKind::KeyUp{ code: KeyCode::BACKSPACE } ),
                        _ => (),
                    }
                },
                Event::KeyDown { scancode,.. } =>{
                    match scancode{
                        Some(Scancode::A) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_A } ),
                        Some(Scancode::B) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_B } ),
                        Some(Scancode::C) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_C } ),
                        Some(Scancode::D) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_D } ),
                        Some(Scancode::E) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_E } ),
                        Some(Scancode::F) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_F } ),
                        Some(Scancode::G) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_G } ),
                        Some(Scancode::H) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_H } ),
                        Some(Scancode::I) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_I } ),
                        Some(Scancode::J) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_J } ),
                        Some(Scancode::K) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_K } ),
                        Some(Scancode::L) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_L } ),
                        Some(Scancode::M) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_M } ),
                        Some(Scancode::N) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_N } ),
                        Some(Scancode::O) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_O } ),
                        Some(Scancode::P) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_P } ),
                        Some(Scancode::Q) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_Q } ),
                        Some(Scancode::R) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_R } ),
                        Some(Scancode::S) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_S } ),
                        Some(Scancode::T) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_T } ),
                        Some(Scancode::U) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_U } ),
                        Some(Scancode::V) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_V } ),
                        Some(Scancode::W) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_W } ),
                        Some(Scancode::X) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_X } ),
                        Some(Scancode::Y) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_Y } ),
                        Some(Scancode::Z) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::KEY_Z } ),
                        Some(Scancode::Num0) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::NUM_0 } ),
                        Some(Scancode::Num1) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::NUM_1 } ),
                        Some(Scancode::Num2) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::NUM_2 } ),
                        Some(Scancode::Num3) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::NUM_3 } ),
                        Some(Scancode::Num4) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::NUM_4 } ),
                        Some(Scancode::Num5) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::NUM_5 } ),
                        Some(Scancode::Num6) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::NUM_6 } ),
                        Some(Scancode::Num7) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::NUM_7 } ),
                        Some(Scancode::Num8) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::NUM_8 } ),
                        Some(Scancode::Num9) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::NUM_9 } ),
                        Some(Scancode::Return) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::ENTER } ),
                        Some(Scancode::Escape) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::ESC } ),
                        Some(Scancode::Tab) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::TAB} ),
                        Some(Scancode::LShift) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::SHIFT_L} ),
                        Some(Scancode::RShift) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::SHIFT_R} ),
                        Some(Scancode::Space) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::SPACE } ),
                        Some(Scancode::Minus) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::MINUS } ),
                        Some(Scancode::Equals) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::EQUALS } ),
                        Some(Scancode::LeftBracket) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::BRACKET_LEFT } ),
                        Some(Scancode::RightBracket) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::BRAKET_RIGHT } ),
                        Some(Scancode::Backslash) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::BACKSLASH } ),
                        Some(Scancode::NonUsHash) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::NUM_2 } ),
                        Some(Scancode::Semicolon) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::COLON } ),
                        Some(Scancode::Apostrophe) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::QUOTE } ),
                        Some(Scancode::Grave) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::BACK_QUOTE } ),
                        Some(Scancode::Comma) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::COMMA } ),
                        Some(Scancode::Period) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::PERIOD } ),
                        Some(Scancode::Slash) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::FORWARD_SLASH } ),
                        Some(Scancode::CapsLock) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::CAPSLOCK } ),
                        Some(Scancode::LCtrl) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::CTRL_L } ),
                        Some(Scancode::RCtrl) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::CTRL_R } ),
                        Some(Scancode::LAlt) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::ALT_L } ),
                        Some(Scancode::RAlt) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::ALT_R } ),
                        Some(Scancode::F1) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::F1 } ),
                        Some(Scancode::F2) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::F2 } ),
                        Some(Scancode::F3) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::F3 } ),
                        Some(Scancode::F4) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::F4 } ),
                        Some(Scancode::F5) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::F5 } ),
                        Some(Scancode::F6) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::F6 } ),
                        Some(Scancode::F7) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::F7 } ),
                        Some(Scancode::F8) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::F8 } ),
                        Some(Scancode::F9) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::F9 } ),
                        Some(Scancode::F10) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::F10 } ),
                        Some(Scancode::F11) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::F11 } ),
                        Some(Scancode::F12) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::F12 } ),
                        Some(Scancode::PrintScreen) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::PRINT_SCREEN } ),
                        Some(Scancode::ScrollLock) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::SCROLL_LOCK } ),
                        Some(Scancode::Pause) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::PAUSE } ),
                        Some(Scancode::Delete) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::DELETE } ),
                        Some(Scancode::End) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::END } ),
                        Some(Scancode::PageDown) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::PAGE_DOWN } ),
                        Some(Scancode::PageUp) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::PAGE_UP } ),
                        Some(Scancode::Left) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::ARROW_LEFT } ),
                        Some(Scancode::Right) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::ARROW_RIGHT } ),
                        Some(Scancode::Up) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::ARROW_UP } ),
                        Some(Scancode::Down) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::ARROW_DOWN } ),
                        Some(Scancode::Backspace) => push_event!(gevent,EventKind::KeyDown{ code: KeyCode::BACKSPACE } ),
                        _ => (),
                    }
                },
                Event::MouseButtonDown { mouse_btn, x,y ,.. } =>{
                    match mouse_btn{
                        MouseButton::Left => push_event!(gevent,EventKind::MouseDown{ button_code: MouseCode::LEFT_BUTTON, x, y} ),
                        MouseButton::Right => push_event!(gevent,EventKind::MouseDown{ button_code: MouseCode::RIGHT_BUTTON, x, y} ),
                        MouseButton::Middle =>push_event!(gevent,EventKind::MouseDown{ button_code: MouseCode::WHEEL{  direction:0}, x, y} ),
                        _=>(),
                    }
                },
                Event::MouseButtonUp { mouse_btn, x,y ,.. } =>{
                    match mouse_btn{
                        MouseButton::Left => push_event!(gevent,EventKind::MouseUp{ button_code: MouseCode::LEFT_BUTTON, x, y} ),
                        MouseButton::Right => push_event!(gevent,EventKind::MouseUp{ button_code: MouseCode::RIGHT_BUTTON, x, y} ),
                        MouseButton::Middle =>push_event!(gevent,EventKind::MouseUp{ button_code: MouseCode::WHEEL{direction:0}, x, y} ),
                        _=>(),
                    }
                },
                Event::MouseMotion { x, y,xrel,yrel,.. } =>{
                   push_event!(gevent,EventKind::MouseMove{ x, y ,dx:xrel, dy:yrel} );
                },
                Event::MouseWheel{ y , .. } => {
                    push_event!(gevent,EventKind::MouseWheel{ button_code: MouseCode::WHEEL{ direction:y } });
                },
                _ => (),
            });

        width_update.map(|width|  self.window_width = width); 
        height_update.map(|height| self.window_height = height);
        //make sure to give the pollevent back
        self.glue_event = gevent;
    }
}