pub struct EngineHost { /* private fields */ }Expand description
A shared, thread-safe front end to one engine.
The engine is a single-threaded-apartment COM object: its wrappers are
deliberately neither Send nor Sync, and driving one from several
threads does not work. A server, though, is inherently multi-threaded.
This resolves that by giving the engine a thread of its own. Callers submit work; the engine thread runs it and sends the answer back. Because the work is a closure rather than a fixed command list, the whole API is reachable without enumerating it:
use rs_teststand_bridge::EngineHost;
let host = EngineHost::start()?;
let version = host.with_engine(|engine| engine.version_string()).await??;
println!("TestStand {version}");The same thread polls the message queue and broadcasts what it finds, so a host can serve requests and forward progress at once, which is what an IPC layer needs and what a single-threaded caller cannot do.
Implementations§
Source§impl EngineHost
impl EngineHost
Sourcepub async fn with_engine<F, T>(&self, work: F) -> Result<T, Error>
pub async fn with_engine<F, T>(&self, work: F) -> Result<T, Error>
Runs a closure against the engine and waits for its result.
The closure runs on the engine’s thread, so it may use any part of the
API. Its result must be Send to come back.
The outer error means the engine thread is gone; the inner one is whatever the closure produced.
§Errors
Error if the engine thread has stopped.
Sourcepub fn subscribe(&self) -> Receiver<MessageEvent>
pub fn subscribe(&self) -> Receiver<MessageEvent>
Receives every message posted from now on.
Each subscriber gets its own copy. One that falls further behind than the backlog is told how many it missed rather than quietly losing them.
Sourcepub fn subscriber_count(&self) -> usize
pub fn subscriber_count(&self) -> usize
How many subscribers are currently listening.