pub mod abi;
pub mod clock;
pub mod entry;
pub mod marshal;
pub mod platform;
pub mod ring;
pub mod runtime;
pub mod vtable;
#[cfg(target_os = "macos")]
pub mod cf;
use std::os::raw::c_void;
use std::sync::Arc;
use crate::driver::AnyDriver;
use crate::raw::runtime::{DriverObject, DriverRuntime};
pub type RawObjectId = u32;
pub type RawOsStatus = i32;
pub unsafe fn driver_factory_dispatch(
allocator: *const c_void,
requested_type_uuid: *const c_void,
create: fn() -> Arc<dyn AnyDriver>,
) -> *mut c_void {
let _ = (allocator, requested_type_uuid);
let runtime = DriverRuntime::new(create());
let object = Box::new(DriverObject::new(vtable::driver_interface(), runtime));
Box::into_raw(object).cast::<c_void>()
}
#[cfg(test)]
mod tests {
use super::*;
use crate::driver::{Driver, DriverInstance};
use crate::raw::abi::AudioServerPlugInDriverRef;
use crate::{DeviceSpec, IoBuffer, RealtimeContext};
struct NullDriver;
impl Driver for NullDriver {
const NAME: &'static str = "tympan-aspl raw factory driver";
const MANUFACTURER: &'static str = "tympan-aspl";
const VERSION: &'static str = "0.0.0";
fn new() -> Self {
Self
}
fn device(&self) -> DeviceSpec {
DeviceSpec::new("com.tympan.test.raw", "Raw Factory", Self::MANUFACTURER)
}
fn process_io(&mut self, _rt: &RealtimeContext, _buffer: &mut IoBuffer<'_>) {}
}
fn create() -> Arc<dyn AnyDriver> {
Arc::new(DriverInstance::<NullDriver>::new())
}
#[test]
fn factory_dispatch_builds_a_live_driver_object() {
let ptr = unsafe { driver_factory_dispatch(core::ptr::null(), core::ptr::null(), create) };
assert!(!ptr.is_null());
let driver_ref = ptr.cast::<*const abi::AudioServerPlugInDriverInterface>();
let object = unsafe { DriverObject::from_ref(driver_ref) }.unwrap();
assert_eq!(object.refcount().count(), 1);
assert!(core::ptr::eq(
unsafe { *driver_ref },
vtable::driver_interface(),
));
assert_eq!(
object.runtime().info().name,
"tympan-aspl raw factory driver"
);
let remaining = unsafe { entry::release(ptr) };
assert_eq!(remaining, 0);
}
#[test]
fn factory_dispatch_drives_a_full_lifecycle_through_the_vtable() {
let ptr = unsafe { driver_factory_dispatch(core::ptr::null(), core::ptr::null(), create) };
let driver_ref: AudioServerPlugInDriverRef = ptr.cast();
unsafe {
assert_eq!(
entry::initialize(driver_ref, core::ptr::null_mut()),
crate::OsStatus::OK.as_i32()
);
assert_eq!(
entry::start_io(driver_ref, 2, 0),
crate::OsStatus::OK.as_i32()
);
assert_eq!(
entry::stop_io(driver_ref, 2, 0),
crate::OsStatus::OK.as_i32()
);
assert_eq!(entry::release(ptr), 0);
}
}
#[test]
fn raw_aliases_match_safe_wrapper_widths() {
use core::mem::size_of;
assert_eq!(size_of::<RawObjectId>(), size_of::<crate::AudioObjectId>());
assert_eq!(size_of::<RawOsStatus>(), size_of::<crate::OsStatus>());
}
}