use std::sync::Arc;
use sim_kernel::{
AbiVersion, Cx, Export, Lib, LibManifest, LibTarget, Linker, Result, Symbol, Version,
};
use crate::{
claims::publish_control_organ_claims_for_lib,
ops::{ControlFunction, abort_symbol, capture_symbol, prompt_symbol, resume_symbol},
policy::install_control_policy,
};
const CONTROL_LIB_ID: &str = "control";
pub struct ControlLib;
impl Lib for ControlLib {
fn manifest(&self) -> LibManifest {
LibManifest {
id: manifest_name(),
version: Version(env!("CARGO_PKG_VERSION").to_owned()),
abi: AbiVersion { major: 0, minor: 1 },
target: LibTarget::HostRegistered,
requires: Vec::new(),
capabilities: Vec::new(),
exports: control_exports(),
}
}
fn load(&self, cx: &mut sim_kernel::LoadCx, linker: &mut Linker<'_>) -> Result<()> {
for function in [
ControlFunction::prompt(),
ControlFunction::capture(),
ControlFunction::abort(),
ControlFunction::resume(),
] {
linker.function_value(function.symbol(), cx.factory().opaque(Arc::new(function))?)?;
}
Ok(())
}
}
pub fn install_control_lib(cx: &mut Cx) -> Result<()> {
let lib_id = match sim_lib_core::install_once_id(cx, &ControlLib)? {
Some(lib_id) => lib_id,
None => sim_lib_core::installed_lib_id(cx, &ControlLib).expect("control lib is loaded"),
};
install_control_policy(cx);
publish_control_organ_claims_for_lib(cx, lib_id)
}
pub fn control_exports() -> Vec<Export> {
[
prompt_symbol(),
capture_symbol(),
abort_symbol(),
resume_symbol(),
]
.into_iter()
.map(|symbol| Export::Function {
symbol,
function_id: None,
})
.collect()
}
pub fn manifest_name() -> Symbol {
Symbol::qualified("sim", CONTROL_LIB_ID)
}