1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
#![allow(warnings)] #[cfg(unix)] extern crate sapp_linux as sapp; #[cfg(target_arch = "wasm32")] extern crate sapp_wasm as sapp; #[cfg(windows)] extern crate sapp_windows as sapp; pub mod conf; mod event; pub mod graphics; pub use event::*; pub use graphics::*; use std::ffi::CString; pub use sapp::{rand, RAND_MAX}; pub mod date { #[cfg(not(target_arch = "wasm32"))] pub fn now() -> f64 { use std::time::SystemTime; let time = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) .unwrap_or_else(|e| panic!(e)); time.as_secs_f64() } #[cfg(target_arch = "wasm32")] pub fn now() -> f64 { unsafe { sapp::time() as f64 } } } struct UserData { event_handler: Box<dyn EventHandler>, context: Context, } enum UserDataState { Uninitialized(Box<dyn 'static + FnOnce(&mut Context) -> Box<dyn event::EventHandler>>), Intialized(UserData), Empty, } extern "C" fn init(user_data: *mut ::std::os::raw::c_void) { let data: &mut UserDataState = unsafe { &mut *(user_data as *mut UserDataState) }; let empty = UserDataState::Empty; let f = std::mem::replace(data, empty); let f = if let UserDataState::Uninitialized(f) = f { f } else { panic!(); }; let mut context = graphics::Context::new(); let user_data = UserData { event_handler: f(&mut context), context, }; std::mem::replace(data, UserDataState::Intialized(user_data)); } extern "C" fn frame(user_data: *mut ::std::os::raw::c_void) { let data: &mut UserDataState = unsafe { &mut *(user_data as *mut UserDataState) }; let data = if let UserDataState::Intialized(ref mut data) = data { data } else { panic!() }; data.event_handler.update(&mut data.context); data.event_handler.draw(&mut data.context); } extern "C" fn event(event: *const sapp::sapp_event, user_data: *mut ::std::os::raw::c_void) { let data: &mut UserDataState = unsafe { &mut *(user_data as *mut UserDataState) }; let event = unsafe { &*event }; let data = if let UserDataState::Intialized(ref mut data) = data { data } else { panic!() }; match event.type_ { sapp::sapp_event_type_SAPP_EVENTTYPE_MOUSE_MOVE => { data.event_handler.mouse_motion_event( &mut data.context, event.mouse_x, event.mouse_y, 0., 0., ); } sapp::sapp_event_type_SAPP_EVENTTYPE_MOUSE_DOWN => { data.event_handler.mouse_button_down_event( &mut data.context, MouseButton::Left, event.mouse_x, event.mouse_y, ); } sapp::sapp_event_type_SAPP_EVENTTYPE_MOUSE_UP => { data.event_handler.mouse_button_up_event( &mut data.context, MouseButton::Left, event.mouse_x, event.mouse_y, ); } sapp::sapp_event_type_SAPP_EVENTTYPE_KEY_DOWN => { let keycode = KeyCode::from(event.key_code); data.event_handler .key_down_event(&mut data.context, keycode, KeyMods::No, false) } sapp::sapp_event_type_SAPP_EVENTTYPE_KEY_UP => { let keycode = KeyCode::from(event.key_code); data.event_handler .key_up_event(&mut data.context, keycode, KeyMods::No) } sapp::sapp_event_type_SAPP_EVENTTYPE_RESIZED => { data.context .resize(event.window_width as u32, event.window_height as u32); data.event_handler.resize_event( &mut data.context, event.window_width as f32, event.window_height as f32, ); } _ => {} } } pub fn start<F>(_conf: conf::Conf, f: F) where F: 'static + FnOnce(&mut Context) -> Box<dyn event::EventHandler>, { let mut desc: sapp::sapp_desc = unsafe { std::mem::zeroed() }; let title = CString::new("").unwrap_or_else(|e| panic!(e)); let mut user_data = Box::new(UserDataState::Uninitialized(Box::new(f))); desc.width = 800; desc.height = 600; desc.window_title = title.as_ptr(); desc.user_data = &mut *user_data as *mut _ as *mut _; desc.init_userdata_cb = Some(init); desc.frame_userdata_cb = Some(frame); desc.event_userdata_cb = Some(event); std::mem::forget(user_data); unsafe { sapp::sapp_run(&desc as *const _) }; }