commonlibsse_ng\re\b/
BSTEvent.rs1use core::ptr::NonNull;
2
3use crate::re::BSAtomic::BSSpinLock;
4use crate::re::BSTArray::BSTArray;
5
6#[commonlibsse_ng_derive_internal::ffi_enum]
8#[repr(u8)]
9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub enum BSEventNotifyControl {
11 Continue = 0,
12 Stop = 1,
13}
14
15#[derive(Debug)]
16pub struct BSTEventSink<Event> {
17 pub vtable: Option<NonNull<BSTEventSinkVtbl<Event>>>,
18}
19const _: () = assert!(core::mem::size_of::<BSTEventSink<*mut ()>>() == 0x8);
20
21impl<Event> BSTEventSink<Event> {
22 pub unsafe fn process_event(
24 &mut self,
25 event: *const Self,
26 event_source: *const BSTEventSource<Event>,
27 ) -> BSEventNotifyControl {
28 self.vtable
29 .map(|ptr| unsafe { ptr.as_ref() })
30 .and_then(|vtable| {
31 unsafe { (vtable.ProcessEvent)(self, event, event_source) }.to_enum()
32 })
33 .unwrap_or(BSEventNotifyControl::Stop)
34 }
35}
36
37pub struct BSTEventSinkVtbl<Event> {
38 pub CxxDrop: unsafe extern "C" fn(this: *mut BSTEventSink<Event>),
40
41 pub ProcessEvent: unsafe extern "C" fn(
42 this: *mut BSTEventSink<Event>,
43 event: *const BSTEventSink<Event>,
44 eventSource: *const BSTEventSource<Event>,
45 ) -> BSEventNotifyControl_CEnum,
46}
47
48#[repr(C)]
49#[derive(Debug)]
50pub struct BSTEventSource<Event> {
51 pub sinks: BSTArray<*mut BSTEventSink<Event>>,
52 pub pendingRegisters: BSTArray<*mut BSTEventSink<Event>>,
53 pub pendingUnregisters: BSTArray<*mut BSTEventSink<Event>>,
54 pub lock: BSSpinLock,
55 pub notifying: bool,
56 pub pad51: u8,
57 pub pad52: u16,
58 pub pad54: u32,
59}
60const _: () = {
61 assert!(core::mem::offset_of!(BSTEventSource<*mut ()>, sinks) == 0x00);
62 assert!(core::mem::offset_of!(BSTEventSource<*mut ()>, pendingRegisters) == 0x18);
63 assert!(core::mem::offset_of!(BSTEventSource<*mut ()>, pendingUnregisters) == 0x30);
64 assert!(core::mem::offset_of!(BSTEventSource<*mut ()>, lock) == 0x48);
65 assert!(core::mem::offset_of!(BSTEventSource<*mut ()>, notifying) == 0x50);
66 assert!(core::mem::offset_of!(BSTEventSource<*mut ()>, pad51) == 0x51);
67 assert!(core::mem::offset_of!(BSTEventSource<*mut ()>, pad52) == 0x52);
68 assert!(core::mem::offset_of!(BSTEventSource<*mut ()>, pad54) == 0x54);
69
70 assert!(core::mem::size_of::<BSTEventSource<*mut ()>>() == 0x58);
71};
72
73impl<Event> BSTEventSource<Event> {
74 #[inline]
75 pub const fn new() -> Self {
76 Self {
77 sinks: BSTArray::new(),
78 pendingRegisters: BSTArray::new(),
79 pendingUnregisters: BSTArray::new(),
80 lock: BSSpinLock::new(),
81 notifying: false,
82 pad51: 0,
83 pad52: 0,
84 pad54: 0,
85 }
86 }
87
88 pub fn add_event_sink(&mut self, sink: *mut BSTEventSink<Event>) {
89 let _guard = self.lock.lock();
90
91 if sink.is_null() {
92 return;
93 }
94
95 if self.notifying {
96 if !self.pendingRegisters.contains(&sink) {
97 self.pendingRegisters.push(sink);
98 }
99 } else if !self.sinks.contains(&sink) {
100 self.sinks.push(sink);
101 }
102
103 self.pendingUnregisters.retain(|&s| s != sink);
104 }
105
106 pub fn remove_event_sink(&mut self, sink: *mut BSTEventSink<Event>) {
107 let _guard = self.lock.lock();
108
109 if self.notifying {
110 if !self.pendingUnregisters.contains(&sink) {
111 self.pendingUnregisters.push(sink);
112 }
113 } else {
114 self.sinks.retain(|&s| s != sink);
115 }
116
117 self.pendingUnregisters.retain(|&s| s != sink);
118 }
119
120 pub unsafe fn send_event(&mut self, event: *const BSTEventSink<Event>) {
122 let _guard = self.lock.lock();
123
124 let was_notifying = self.notifying;
125 self.notifying = true;
126
127 if !was_notifying && !self.pendingRegisters.is_empty() {
128 for sink in self.pendingRegisters.drain(..) {
129 if !self.sinks.contains(&sink) {
130 self.sinks.push(sink);
131 }
132 }
133 }
134
135 for sink in self.sinks.iter() {
136 let ret = unsafe { (**sink).process_event(event, self) };
137 if !self.pendingUnregisters.contains(sink) && ret == BSEventNotifyControl::Stop {
138 break;
139 }
140 }
141
142 self.notifying = was_notifying;
143
144 if !was_notifying && !self.pendingUnregisters.is_empty() {
145 for sink in self.pendingUnregisters.drain(..) {
146 self.sinks.retain(|&s| s != sink);
147 }
148 }
149 }
150}
151
152impl<Event> Default for BSTEventSource<Event> {
153 #[inline]
154 fn default() -> Self {
155 Self::new()
156 }
157}