TUTORIAL / 05
Work with asynchronous results
Await a future, read a stream and update a reactive value from Rust.
1. Await one result
The primes example returns a future from Rust. The Haxe caller can await its value or register a handler.
pub fn count(limit: i32) -> Result<Future<i32>, &'static str> {
if limit < 0 {
return Err("a negative limit");
}
Ok(spawn_blocking(move || {
let count = (2..limit).filter(|number| is_prime(*number)).count();
Ok::<_, Failure>(count as i32)
}))
}
var count = Primes.count(100000).await();
Sys.println('$count primes below 100000');
await() waits on this thread. For event-loop delivery, use Primes.count(1000).then(count -> Sys.println(count)). The handler runs on the Haxe delivery thread. spawn_blocking uses a native worker thread; on threadless builds it runs before returning. Use spawn or stepped for cooperative work.
2. Read every item
var found = [for (prime in Primes.below(30)) prime];
Sys.println(found.join(" "));
2 3 5 7 11 13 17 19 23 29
Iteration reads items in order. The stream ends when Rust drops its last sender. Use listen for event-loop delivery; a stream’s failure is delivered after earlier items.
3. Follow the latest value
The thermostat example publishes a Rust signal. Haxe derives a value from it and controls delivery explicitly:
pub fn turn(&mut self, degrees: f64) -> f64 {
self.degrees += degrees;
self.source.set(self.degrees);
self.degrees
}
hxn.Loop.manual = true;
var thermostat = new Thermostat(20);
var target = thermostat.target();
// Derived from the signal, and recomputed when it changes.
var state = new hxn.Computed(() -> target.value > 21 ? "heating" : "idle");
// Runs now, and again whenever anything it read has changed.
hxn.Reactive.effect(() -> Sys.println('set to ${target.value}: ${state.value}'));
thermostat.turn(1.5);
hxn.Loop.sync();
// Two changes before a delivery are delivered as one: a signal
// reports only its latest value.
thermostat.turn(1);
thermostat.turn(-0.5);
hxn.Loop.sync();
set to 20: idle
set to 21.5: heating
set to 22: heating
A signal delivers the latest state; the two final turns produce one update. Computed tracks the values it reads, and Reactive.effect reruns when they change. Manual loops call Loop.sync(); otherwise hxn uses the Haxe event loop.
Run the examples
From the repository root, run the complete example:
cd examples/primes
hxn run hl
Full Rust and Haxe source ↗ · Use hxn run cpp for hxcpp.
For the signal example, return to the repository root and run cd examples/thermostat, then hxn run hl.