nexus\api\data_link/
mod.rs

1//! Data link for sharing resources.
2//!
3//! Enable the `"mumble"` or `"mumble_json"` feature for Mumble link bindings.
4
5mod nexus;
6
7/// Mumble link bindings.
8#[cfg(feature = "mumble")]
9pub mod mumble;
10
11/// RealTime API link bindings.
12#[cfg(feature = "rtapi")]
13pub mod rtapi;
14
15pub use self::nexus::*;
16
17#[cfg(feature = "mumble")]
18pub use self::mumble::{get_mumble_link, get_mumble_link_ptr, read_mumble_link, MumbleLink};
19
20use crate::{util::str_to_c, AddonApi, DataLinkApi};
21use std::{
22    ffi::{c_char, c_void},
23    mem,
24};
25
26pub type RawDataGetResource =
27    unsafe extern "C-unwind" fn(identifier: *const c_char) -> *const c_void;
28
29pub type RawDataShareResource =
30    unsafe extern "C-unwind" fn(identifier: *const c_char, resource_size: usize) -> *mut c_void;
31
32/// Returns a pointer to a shared resource.
33pub fn get_resource<T>(identifier: impl AsRef<str>) -> *const T {
34    let identifier = str_to_c(identifier, "failed to convert data link identifier");
35    let DataLinkApi { get, .. } = AddonApi::get().data_link;
36    unsafe { get(identifier.as_ptr()).cast() }
37}
38
39/// Reads a shared resource.
40///
41/// # Safety
42/// The caller must ensure the data associated with the given identifier is of type `T`.
43pub unsafe fn read_resource<T>(identifier: impl AsRef<str>) -> Option<T> {
44    let ptr = get_resource::<T>(identifier);
45    let valid = !ptr.is_null();
46    valid.then(|| unsafe { ptr.read_volatile() })
47}
48
49/// Creates a new shared resource.
50pub fn share_resource<T>(identifier: impl AsRef<str>) -> *mut T {
51    let identifier = str_to_c(identifier, "failed to convert data link identifier");
52    let DataLinkApi { share, .. } = AddonApi::get().data_link;
53    let size = mem::size_of::<T>();
54    unsafe { share(identifier.as_ptr(), size).cast() }
55}