use std::sync::atomic::{AtomicBool, Ordering};
use crate::error::check;
use crate::{c_chars_to_string, sys, Error, Result};
static INITIALIZED: AtomicBool = AtomicBool::new(false);
#[derive(Debug)]
pub struct Runtime {
_private: (),
}
impl Runtime {
pub fn new() -> Result<Self> {
Self::with_framework(sys::NRT_FRAMEWORK_TYPE_NO_FW, "", "")
}
pub fn with_framework(
framework: sys::nrt_framework_type_t,
fw_version: &str,
fal_version: &str,
) -> Result<Self> {
if INITIALIZED.swap(true, Ordering::SeqCst) {
return Err(Error::AlreadyInitialized);
}
let init = || -> Result<()> {
let fw_version = std::ffi::CString::new(fw_version)?;
let fal_version = std::ffi::CString::new(fal_version)?;
let status =
unsafe { sys::nrt_init(framework, fw_version.as_ptr(), fal_version.as_ptr()) };
check(status, "nrt_init")
};
if let Err(err) = init() {
INITIALIZED.store(false, Ordering::SeqCst);
return Err(err);
}
Ok(Self { _private: () })
}
pub fn total_vnc_count(&self) -> Result<u32> {
let mut count = 0;
check(unsafe { sys::nrt_get_total_vnc_count(&mut count) }, "nrt_get_total_vnc_count")?;
Ok(count)
}
pub fn visible_vnc_count(&self) -> Result<u32> {
let mut count = 0;
check(unsafe { sys::nrt_get_visible_vnc_count(&mut count) }, "nrt_get_visible_vnc_count")?;
Ok(count)
}
}
impl Drop for Runtime {
fn drop(&mut self) {
unsafe { sys::nrt_close() };
INITIALIZED.store(false, Ordering::SeqCst);
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Version {
pub major: u64,
pub minor: u64,
pub patch: u64,
pub maintenance: u64,
pub detail: String,
pub git_hash: String,
}
pub fn version() -> Result<Version> {
let mut v = sys::nrt_version_t::default();
let status = unsafe { sys::nrt_get_version(&mut v, std::mem::size_of::<sys::nrt_version_t>()) };
check(status, "nrt_get_version")?;
Ok(Version {
major: v.rt_major,
minor: v.rt_minor,
patch: v.rt_patch,
maintenance: v.rt_maintenance,
detail: c_chars_to_string(&v.rt_detail),
git_hash: c_chars_to_string(&v.git_hash),
})
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InstanceInfo {
pub family: u32,
pub size: u32,
pub arch_name: String,
pub device_revision: String,
}
pub fn instance_info() -> Result<InstanceInfo> {
let mut info = sys::nrt_instance_info_t::default();
let status = unsafe {
sys::nrt_get_instance_info(&mut info, std::mem::size_of::<sys::nrt_instance_info_t>())
};
check(status, "nrt_get_instance_info")?;
Ok(InstanceInfo {
family: info.family,
size: info.size,
arch_name: c_chars_to_string(&info.arch_name),
device_revision: c_chars_to_string(&info.device_revision),
})
}