├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── index.html └── src ├── emscripten.rs └── main.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | [root] 2 | name = "rust_to_js" 3 | version = "0.1.0" 4 | dependencies = [ 5 | "sdl2 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", 6 | ] 7 | 8 | [[package]] 9 | name = "bitflags" 10 | version = "0.7.0" 11 | source = "registry+https://github.com/rust-lang/crates.io-index" 12 | 13 | [[package]] 14 | name = "lazy_static" 15 | version = "0.2.5" 16 | source = "registry+https://github.com/rust-lang/crates.io-index" 17 | 18 | [[package]] 19 | name = "libc" 20 | version = "0.2.21" 21 | source = "registry+https://github.com/rust-lang/crates.io-index" 22 | 23 | [[package]] 24 | name = "num" 25 | version = "0.1.37" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | dependencies = [ 28 | "num-integer 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", 29 | "num-iter 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", 30 | "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 31 | ] 32 | 33 | [[package]] 34 | name = "num-integer" 35 | version = "0.1.33" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | dependencies = [ 38 | "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 39 | ] 40 | 41 | [[package]] 42 | name = "num-iter" 43 | version = "0.1.33" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | dependencies = [ 46 | "num-integer 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", 47 | "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 48 | ] 49 | 50 | [[package]] 51 | name = "num-traits" 52 | version = "0.1.37" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | 55 | [[package]] 56 | name = "rand" 57 | version = "0.3.15" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | dependencies = [ 60 | "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", 61 | ] 62 | 63 | [[package]] 64 | name = "sdl2" 65 | version = "0.29.0" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | dependencies = [ 68 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 69 | "lazy_static 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 70 | "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", 71 | "num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 72 | "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 73 | "sdl2-sys 0.27.2 (registry+https://github.com/rust-lang/crates.io-index)", 74 | ] 75 | 76 | [[package]] 77 | name = "sdl2-sys" 78 | version = "0.27.2" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | dependencies = [ 81 | "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", 82 | ] 83 | 84 | [metadata] 85 | "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" 86 | "checksum lazy_static 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4732c563b9a21a406565c4747daa7b46742f082911ae4753f390dc9ec7ee1a97" 87 | "checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135" 88 | "checksum num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "98b15ba84e910ea7a1973bccd3df7b31ae282bf9d8bd2897779950c9b8303d40" 89 | "checksum num-integer 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "21e4df1098d1d797d27ef0c69c178c3fab64941559b290fcae198e0825c9c8b5" 90 | "checksum num-iter 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d1891bd7b936f12349b7d1403761c8a0b85a18b148e9da4429d5d102c1a41e" 91 | "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99" 92 | "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d" 93 | "checksum sdl2 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f19efbd3c828d45e721636b377bd663f2075beaafcd9ec7f299563fede1482f7" 94 | "checksum sdl2-sys 0.27.2 (registry+https://github.com/rust-lang/crates.io-index)" = "37cfe343db4cd2159cab098096fff52e92d513c2a5b1ee06abbfd5db5323a64d" 95 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_to_js" 3 | version = "0.1.0" 4 | authors = ["Michał Kalbarczyk "] 5 | 6 | [dependencies] 7 | sdl2 = "0.29.0" 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rust_to_js 2 | 3 | An example of Rust code that compiles to javascript. 4 | 5 | This is an example described in this artice: 6 | 7 | https://blog.fazibear.me/definitive-guide-to-rust-sdl-2-and-emscripten-93d707b22bbb 8 | 9 | Have fun! 10 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Emscripten-Generated Code 7 | 92 | 93 | 94 |
95 |
Downloading...
96 | 97 | 98 | Resize canvas 99 | Lock/hide mouse pointer     100 | 102 | 103 | 104 | 105 |
106 | 107 |
108 | 109 |
110 | 111 |
112 | 113 | 114 | 190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /src/emscripten.rs: -------------------------------------------------------------------------------- 1 | #[cfg(target_os = "emscripten")] 2 | pub mod emscripten { 3 | use std::cell::RefCell; 4 | use std::ptr::null_mut; 5 | use std::os::raw::{c_int, c_void, c_float}; 6 | 7 | #[allow(non_camel_case_types)] 8 | type em_callback_func = unsafe extern fn(); 9 | 10 | extern { 11 | pub fn emscripten_set_main_loop(func: em_callback_func, fps: c_int, simulate_infinite_loop: c_int); 12 | pub fn emscripten_cancel_main_loop(); 13 | pub fn emscripten_get_now() -> c_float; 14 | } 15 | 16 | thread_local!(static MAIN_LOOP_CALLBACK: RefCell<*mut c_void> = RefCell::new(null_mut())); 17 | 18 | pub fn set_main_loop_callback(callback: F) where F: FnMut() { 19 | MAIN_LOOP_CALLBACK.with(|log| { 20 | *log.borrow_mut() = &callback as *const _ as *mut c_void; 21 | }); 22 | 23 | unsafe { emscripten_set_main_loop(wrapper::, 0, 1); } 24 | 25 | unsafe extern "C" fn wrapper() where F: FnMut() { 26 | MAIN_LOOP_CALLBACK.with(|z| { 27 | let closure = *z.borrow_mut() as *mut F; 28 | (*closure)(); 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate sdl2; 2 | 3 | use std::process; 4 | use sdl2::rect::{Rect}; 5 | use sdl2::event::{Event}; 6 | use sdl2::keyboard::Keycode; 7 | 8 | #[cfg(target_os = "emscripten")] 9 | pub mod emscripten; 10 | 11 | fn main() { 12 | let ctx = sdl2::init().unwrap(); 13 | let video_ctx = ctx.video().unwrap(); 14 | 15 | let window = match video_ctx 16 | .window("rust_to_js", 640, 480) 17 | .position_centered() 18 | .opengl() 19 | .build() { 20 | Ok(window) => window, 21 | Err(err) => panic!("failed to create window: {}", err) 22 | }; 23 | 24 | let mut renderer = match window 25 | .renderer() 26 | .build() { 27 | Ok(renderer) => renderer, 28 | Err(err) => panic!("failed to create renderer: {}", err) 29 | }; 30 | 31 | let mut rect = Rect::new(10, 10, 10, 10); 32 | let black = sdl2::pixels::Color::RGB(0, 0, 0); 33 | let white = sdl2::pixels::Color::RGB(255, 255, 255); 34 | 35 | let mut events = ctx.event_pump().unwrap(); 36 | 37 | let mut main_loop = || { 38 | for event in events.poll_iter() { 39 | match event { 40 | Event::Quit {..} | Event::KeyDown {keycode: Some(Keycode::Escape), ..} => { 41 | process::exit(1); 42 | }, 43 | Event::KeyDown { keycode: Some(Keycode::Left), ..} => { 44 | rect.x -= 10; 45 | }, 46 | Event::KeyDown { keycode: Some(Keycode::Right), ..} => { 47 | rect.x += 10; 48 | }, 49 | Event::KeyDown { keycode: Some(Keycode::Up), ..} => { 50 | rect.y -= 10; 51 | }, 52 | Event::KeyDown { keycode: Some(Keycode::Down), ..} => { 53 | rect.y += 10; 54 | }, 55 | _ => {} 56 | } 57 | } 58 | 59 | let _ = renderer.set_draw_color(black); 60 | let _ = renderer.clear(); 61 | let _ = renderer.set_draw_color(white); 62 | let _ = renderer.fill_rect(rect); 63 | let _ = renderer.present(); 64 | }; 65 | 66 | #[cfg(target_os = "emscripten")] 67 | use emscripten::{emscripten}; 68 | 69 | #[cfg(target_os = "emscripten")] 70 | emscripten::set_main_loop_callback(main_loop); 71 | 72 | #[cfg(not(target_os = "emscripten"))] 73 | loop { main_loop(); } 74 | } 75 | --------------------------------------------------------------------------------