use cocoa::{
base::{id, nil},
foundation::NSAutoreleasePool,
};
use objc::{msg_send, sel, sel_impl};
use std::ops::Deref;
#[derive(Debug)]
pub struct IdRef(id);
impl IdRef {
pub fn new(i: id) -> IdRef {
IdRef(i)
}
#[allow(dead_code)]
pub fn retain(i: id) -> IdRef {
if i != nil {
let _: id = unsafe { msg_send![i, retain] };
}
IdRef(i)
}
pub fn non_nil(self) -> Option<IdRef> {
if self.0 == nil {
None
} else {
Some(self)
}
}
}
impl Drop for IdRef {
fn drop(&mut self) {
if self.0 != nil {
with_autorelease_pool(|| unsafe {
let _: () = msg_send![self.0, release];
});
}
}
}
impl Deref for IdRef {
type Target = id;
fn deref<'a>(&'a self) -> &'a id {
&self.0
}
}
impl Clone for IdRef {
fn clone(&self) -> IdRef {
if self.0 != nil {
let _: id = unsafe { msg_send![self.0, retain] };
}
IdRef(self.0)
}
}
#[derive(Debug)]
pub struct AutoreleasePool(id);
impl AutoreleasePool {
pub fn new() -> Self {
Self(unsafe { NSAutoreleasePool::new(nil) })
}
}
impl Drop for AutoreleasePool {
fn drop(&mut self) {
let () = unsafe { msg_send![self.0, release] };
}
}
pub fn with_autorelease_pool<T>(f: impl FnOnce() -> T) -> T {
let _arp = AutoreleasePool::new();
f()
}