Entry Points
We need to wire everything together. Because we are targeting both Desktop (binary) and Web (library), we have two entry points.
1. The Module Structure
First, expose our core modules. Create src/core/mod.rs:
pub mod entry_point;
pub mod renderer;
pub mod window;
2. The Shared Runner
Create src/core/entry_point.rs. This file contains the logic to start the event loop, which is shared by both platforms.
use winit::event_loop::EventLoop;
use crate::core::window::Win;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
#[allow(dead_code)]
pub fn run() -> anyhow::Result<()> {
// Initialize logging based on platform
#[cfg(not(target_arch = "wasm32"))]
{
env_logger::init();
}
#[cfg(target_arch = "wasm32")]
{
console_log::init_with_level(log::Level::Info).unwrap();
}
// Create the Event Loop
let event_loop = EventLoop::with_user_event().build().unwrap();
// Create our Window wrapper
// Note: On WASM, we pass the event_loop reference to create the proxy
let mut win = Win::new(
#[cfg(target_arch = "wasm32")]
&event_loop,
);
// Start the application
event_loop.run_app(&mut win).unwrap();
Ok(())
}
// This function is called by JavaScript when the WASM module loads
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen(start)]
pub fn run_web() -> Result<(), wasm_bindgen::JsValue> {
console_error_panic_hook::set_once(); // Better error messages in browser console
run().unwrap();
Ok(())
}
3. Native Entry Point (Desktop)
Modify src/main.rs. This is what runs when you execute `cargo run`.
mod core;
use crate::core::entry_point::run;
fn main() {
run().unwrap();
}
4. Web Entry Point (WASM)
Modify src/lib.rs. This is what `wasm-pack` compiles.
mod core;
// The actual entry point 'run_web' is inside core/entry_point.rs
// and marked with #[wasm_bindgen(start)], so it will be automatically invoked.
💡 Logic Flow
1. Desktop: main() -> run() -> EventLoop -> Win::resumed() -> Renderer::new()
2. Web: JS imports WASM -> run_web() -> run() -> EventLoop -> Win::resumed() -> Renderer::new()