//! Container for `GHOST_SystemHandle` use super::*; use handle::*; use std::{ ptr::NonNull, ops::Drop, }; /// Represents the active GHOST system. /// /// This is global state, and only one can exist at once time. /// # Usage /// Create with the `create()` function. When the instance is dropped, the system is attempted to be disposed of. /// This is not an associated function, to specify that creating the system is a global event, not an associated one. /// /// # Panics /// On debug builds a failed dispose on drop will panic. You can call `try_drop()` to attempt the dispose manually. #[derive(Debug)] pub struct System(NonNull>); impl System { pub(crate) unsafe fn new_unchecked(from: *mut Handle) -> Self { Self(NonNull::new_unchecked(from)) } /// Specifies whether debug messages are to be enabled for the specific system handle. pub fn debug_messages(&mut self, enable: bool) { unsafe { api::GHOST_SystemInitDebug(self.as_raw(), enable as libc::c_int); } } /// Try to dispose the system now, returning the result. pub fn try_drop(self) -> error::GhostResult { let res = unsafe { api::GHOST_DisposeSystem(self.0.as_ptr()) }; std::mem::forget(self); res.into() } #[inline] pub fn inner_handle(&mut self) -> GHOST_SystemHandle { self.0.as_ptr() } } impl handle::AsHandle for System { #[inline] fn as_handle(&mut self) -> &mut Handle { unsafe{self.0.as_mut()} } #[inline] fn as_raw(&mut self) -> *mut Handle { self.inner_handle() } } impl Drop for System { fn drop(&mut self) { unsafe { let ptr = self.0.as_ptr(); debug!(api::GHOST_DisposeSystem(ptr).into_result().expect("Failed to dispose system"); {let _ = api::GHOST_DisposeSystem(ptr);}); } } } /// Create the one and only system. /// /// You must not call `create()` again as long as the system lives. After dropping the system it may or may not be safe to call this again. pub fn create() -> error::GhostResult { unsafe { let ptr = from_null!(api::GHOST_CreateSystem()); Ok(System::new_unchecked(ptr)) } }