#![cfg_attr(target_os = "emscripten", no_main)]
use std::cell::RefCell;
use std::sync::mpsc::{channel, Receiver, TryRecvError};
use wasm_bindgen::prelude::*;
type Report = (u64, bool);
ferroui_base::ferro_thread_local! {
static PENDING: RefCell<Option<Receiver<Report>>> = const { RefCell::new(None) };
static STATE: RefCell<String> = RefCell::new("state=idle".to_string());
}
#[wasm_bindgen(js_name = threadSpawnStart)]
pub fn thread_spawn_start() {
let (sender, receiver) = channel::<Report>();
let starter = std::thread::current().id();
let spawned = std::thread::Builder::new().name("thread_spawn".to_string()).spawn(move || {
let sum: u64 = (1..=1000u64).sum();
let _ = sender.send((sum, std::thread::current().id() != starter));
});
match spawned {
Ok(_) => {
PENDING.with(|pending| *pending.borrow_mut() = Some(receiver));
STATE.with(|state| *state.borrow_mut() = "state=running".to_string());
}
Err(error) => {
PENDING.with(|pending| *pending.borrow_mut() = None);
STATE.with(|state| *state.borrow_mut() = format!("state=failed error={error}"));
}
}
}
#[wasm_bindgen(js_name = threadSpawnState)]
pub fn thread_spawn_state() -> String {
let received = PENDING.with(|pending| pending.borrow().as_ref().map(|receiver| receiver.try_recv()));
match received {
Some(Ok((value, other_thread))) => {
PENDING.with(|pending| *pending.borrow_mut() = None);
STATE.with(|state| *state.borrow_mut() = format!("state=done value={value} other_thread={other_thread}"));
}
Some(Err(TryRecvError::Disconnected)) => {
PENDING.with(|pending| *pending.borrow_mut() = None);
STATE.with(|state| *state.borrow_mut() = "state=failed error=the thread ended without sending a value".to_string());
}
Some(Err(TryRecvError::Empty)) | None => {}
}
let state = STATE.with(|state| state.borrow().clone());
format!("atomics={} {state}", cfg!(target_feature = "atomics"))
}
#[cfg(not(target_os = "emscripten"))]
fn main() {
thread_spawn_start();
let mut state = thread_spawn_state();
while state.contains("state=running") {
std::thread::sleep(std::time::Duration::from_millis(1));
state = thread_spawn_state();
}
println!("{state}");
}