use std::{marker::PhantomData, os::raw::c_void, ptr::NonNull};
use libcogcore_sys as sys;
use crate::{Error, Result};
pub(crate) struct ObjectPtr<T> {
ptr: NonNull<T>,
_not_send_sync: PhantomData<*mut T>,
}
impl<T> ObjectPtr<T> {
pub(crate) fn from_owned(ptr: *mut T, context: &'static str) -> Result<Self> {
let ptr = NonNull::new(ptr).ok_or(Error::Null(context))?;
Ok(Self {
ptr,
_not_send_sync: PhantomData,
})
}
pub(crate) fn from_borrowed(ptr: *mut T, context: &'static str) -> Result<Self> {
let ptr = NonNull::new(ptr).ok_or(Error::Null(context))?;
let raw = ptr.as_ptr().cast::<c_void>();
let owned = unsafe { sys::g_object_ref(raw) };
let ptr = NonNull::new(owned.cast::<T>()).ok_or(Error::Null(context))?;
Ok(Self {
ptr,
_not_send_sync: PhantomData,
})
}
pub(crate) fn as_ptr(&self) -> *mut T {
self.ptr.as_ptr()
}
}
impl<T> Clone for ObjectPtr<T> {
fn clone(&self) -> Self {
let raw = self.ptr.as_ptr().cast::<c_void>();
let owned = unsafe { sys::g_object_ref(raw) };
let ptr = NonNull::new(owned.cast::<T>()).expect("g_object_ref returned null");
Self {
ptr,
_not_send_sync: PhantomData,
}
}
}
impl<T> Drop for ObjectPtr<T> {
fn drop(&mut self) {
let raw = self.ptr.as_ptr().cast::<c_void>();
unsafe { sys::g_object_unref(raw) };
}
}