mtl_foundation/
notification.rs1use std::ffi::c_void;
28use std::ptr::NonNull;
29
30use mtl_sys::{class, msg_send_0, msg_send_1, sel};
31
32use crate::dictionary::Dictionary;
33use crate::object::{Object, Referencing};
34use crate::string::String;
35
36pub type NotificationName = *mut String;
40
41#[repr(transparent)]
45#[derive(Clone)]
46pub struct Notification(NonNull<c_void>);
47
48impl Notification {
49 #[inline]
53 pub fn name(&self) -> *mut String {
54 unsafe { msg_send_0(self.as_ptr(), sel!(name)) }
55 }
56
57 #[inline]
61 pub fn object(&self) -> *mut Object {
62 unsafe { msg_send_0(self.as_ptr(), sel!(object)) }
63 }
64
65 #[inline]
69 pub fn user_info(&self) -> *mut Dictionary {
70 unsafe { msg_send_0(self.as_ptr(), sel!(userInfo)) }
71 }
72
73 #[inline]
79 pub unsafe fn from_ptr(ptr: *mut c_void) -> Option<Self> {
80 NonNull::new(ptr).map(Self)
81 }
82}
83
84impl Referencing for Notification {
85 #[inline]
86 fn as_ptr(&self) -> *const c_void {
87 self.0.as_ptr()
88 }
89}
90
91unsafe impl Send for Notification {}
92unsafe impl Sync for Notification {}
93
94impl std::fmt::Debug for Notification {
95 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96 f.debug_struct("Notification")
97 .field("ptr", &self.0)
98 .finish()
99 }
100}
101
102#[repr(transparent)]
106#[derive(Clone)]
107pub struct NotificationCenter(NonNull<c_void>);
108
109impl NotificationCenter {
110 #[inline]
114 pub fn default_center() -> Option<Self> {
115 unsafe {
116 let ptr: *mut c_void =
117 msg_send_0(class!(NSNotificationCenter).as_ptr(), sel!(defaultCenter));
118 Self::from_ptr(ptr)
119 }
120 }
121
122 #[inline]
129 pub fn add_observer(
130 &self,
131 name: NotificationName,
132 object: *mut Object,
133 queue: *mut c_void,
134 block: *const c_void,
135 ) -> *mut Object {
136 unsafe {
137 mtl_sys::msg_send_4(
138 self.as_ptr(),
139 sel!(addObserverForName:object:queue:usingBlock:),
140 name,
141 object,
142 queue,
143 block,
144 )
145 }
146 }
147
148 #[inline]
152 pub fn remove_observer(&self, observer: &Object) {
153 unsafe {
154 let _: () = msg_send_1(self.as_ptr(), sel!(removeObserver:), observer.as_ptr());
155 }
156 }
157
158 #[inline]
164 pub unsafe fn from_ptr(ptr: *mut c_void) -> Option<Self> {
165 NonNull::new(ptr).map(Self)
166 }
167}
168
169impl Referencing for NotificationCenter {
170 #[inline]
171 fn as_ptr(&self) -> *const c_void {
172 self.0.as_ptr()
173 }
174}
175
176unsafe impl Send for NotificationCenter {}
177unsafe impl Sync for NotificationCenter {}
178
179impl std::fmt::Debug for NotificationCenter {
180 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
181 f.debug_struct("NotificationCenter")
182 .field("ptr", &self.0)
183 .finish()
184 }
185}
186
187#[cfg(test)]
188mod tests {
189 use super::*;
190
191 #[test]
192 fn test_notification_size() {
193 assert_eq!(
194 std::mem::size_of::<Notification>(),
195 std::mem::size_of::<*mut c_void>()
196 );
197 }
198
199 #[test]
200 fn test_notification_center_size() {
201 assert_eq!(
202 std::mem::size_of::<NotificationCenter>(),
203 std::mem::size_of::<*mut c_void>()
204 );
205 }
206}