1use parking_lot::{Mutex, RwLock};
66use std::fmt::{self, Debug, Display};
67use std::marker::PhantomData;
68use std::mem;
69use std::sync::Arc;
70use std::time::Duration;
71
72use crate::export::NativeClass;
73
74pub unsafe trait UserData: Sized + Clone {
78 type Target: NativeClass;
79
80 fn new(val: Self::Target) -> Self;
84
85 fn into_user_data(self) -> *const libc::c_void;
91
92 unsafe fn consume_user_data_unchecked(ptr: *const libc::c_void) -> Self;
106
107 unsafe fn clone_from_user_data_unchecked(ptr: *const libc::c_void) -> Self;
120}
121
122pub trait Map: UserData {
124 type Err: Debug;
125
126 fn map<F, U>(&self, op: F) -> Result<U, Self::Err>
131 where
132 F: FnOnce(&Self::Target) -> U;
133}
134
135pub trait MapMut: UserData {
137 type Err: Debug;
138
139 fn map_mut<F, U>(&self, op: F) -> Result<U, Self::Err>
144 where
145 F: FnOnce(&mut Self::Target) -> U;
146}
147
148pub trait MapOwned: UserData {
150 type Err: Debug;
151
152 fn map_owned<F, U>(&self, op: F) -> Result<U, Self::Err>
158 where
159 F: FnOnce(Self::Target) -> U;
160}
161
162pub type DefaultUserData<T> = LocalCellData<T>;
165
166#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
168pub enum Infallible {}
169
170impl std::fmt::Display for Infallible {
171 #[inline]
172 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
173 write!(f, "operation that can't fail just failed")
174 }
175}
176
177#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
189pub enum DeadlockPolicy {
190 Allow,
192
193 Pessimistic,
196
197 Timeout(Duration),
200}
201
202pub trait LockOptions {
211 const DEADLOCK_POLICY: DeadlockPolicy;
212}
213
214#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
218pub struct DefaultLockPolicy;
219
220impl LockOptions for DefaultLockPolicy {
221 const DEADLOCK_POLICY: DeadlockPolicy = DeadlockPolicy::Allow;
222}
223
224#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
226pub enum LockFailed {
227 Pessimistic,
228 Timeout(Duration),
229}
230
231impl std::fmt::Display for LockFailed {
232 #[inline]
233 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
234 match self {
235 LockFailed::Timeout(wait) => write!(f, "failed to acquire lock within {wait:?}"),
236 LockFailed::Pessimistic => write!(f, "failed to acquire lock, it was already held"),
237 }
238 }
239}
240impl std::error::Error for LockFailed {}
241
242#[derive(Debug)]
247pub struct MutexData<T, OPT = DefaultLockPolicy> {
248 lock: Arc<Mutex<T>>,
249 _marker: PhantomData<OPT>,
250}
251
252unsafe impl<T, OPT> UserData for MutexData<T, OPT>
253where
254 T: NativeClass + Send,
255 OPT: LockOptions,
256{
257 type Target = T;
258
259 #[inline]
260 fn new(val: Self::Target) -> Self {
261 MutexData {
262 lock: Arc::new(Mutex::new(val)),
263 _marker: PhantomData,
264 }
265 }
266
267 #[inline]
268 fn into_user_data(self) -> *const libc::c_void {
269 Arc::into_raw(self.lock) as *const libc::c_void
270 }
271
272 #[inline]
273 unsafe fn consume_user_data_unchecked(ptr: *const libc::c_void) -> Self {
274 MutexData {
275 lock: Arc::from_raw(ptr as *const Mutex<T>),
276 _marker: PhantomData,
277 }
278 }
279
280 #[inline]
281 unsafe fn clone_from_user_data_unchecked(ptr: *const libc::c_void) -> Self {
282 let borrowed = Arc::from_raw(ptr as *const Mutex<T>);
283 let lock = borrowed.clone();
284 mem::forget(borrowed);
285 MutexData {
286 lock,
287 _marker: PhantomData,
288 }
289 }
290}
291
292impl<T, OPT> Map for MutexData<T, OPT>
293where
294 T: NativeClass + Send,
295 OPT: LockOptions,
296{
297 type Err = LockFailed;
298
299 #[inline]
300 fn map<F, U>(&self, op: F) -> Result<U, LockFailed>
301 where
302 F: FnOnce(&T) -> U,
303 {
304 self.map_mut(|val| op(val))
305 }
306}
307
308impl<T, OPT> MapMut for MutexData<T, OPT>
309where
310 T: NativeClass + Send,
311 OPT: LockOptions,
312{
313 type Err = LockFailed;
314
315 #[inline]
316 fn map_mut<F, U>(&self, op: F) -> Result<U, LockFailed>
317 where
318 F: FnOnce(&mut T) -> U,
319 {
320 let mut guard = match OPT::DEADLOCK_POLICY {
321 DeadlockPolicy::Allow => self.lock.lock(),
322 DeadlockPolicy::Pessimistic => self.lock.try_lock().ok_or(LockFailed::Pessimistic)?,
323 DeadlockPolicy::Timeout(dur) => self
324 .lock
325 .try_lock_for(dur)
326 .ok_or(LockFailed::Timeout(dur))?,
327 };
328
329 Ok(op(&mut *guard))
330 }
331}
332
333impl<T, OPT> Clone for MutexData<T, OPT> {
334 #[inline]
335 fn clone(&self) -> Self {
336 MutexData {
337 lock: self.lock.clone(),
338 _marker: PhantomData,
339 }
340 }
341}
342
343#[derive(Debug)]
348pub struct RwLockData<T, OPT = DefaultLockPolicy> {
349 lock: Arc<RwLock<T>>,
350 _marker: PhantomData<OPT>,
351}
352
353unsafe impl<T, OPT> UserData for RwLockData<T, OPT>
354where
355 T: NativeClass + Send + Sync,
356 OPT: LockOptions,
357{
358 type Target = T;
359
360 #[inline]
361 fn new(val: Self::Target) -> Self {
362 RwLockData {
363 lock: Arc::new(RwLock::new(val)),
364 _marker: PhantomData,
365 }
366 }
367
368 #[inline]
369 fn into_user_data(self) -> *const libc::c_void {
370 Arc::into_raw(self.lock) as *const libc::c_void
371 }
372
373 #[inline]
374 unsafe fn consume_user_data_unchecked(ptr: *const libc::c_void) -> Self {
375 RwLockData {
376 lock: Arc::from_raw(ptr as *const RwLock<T>),
377 _marker: PhantomData,
378 }
379 }
380
381 #[inline]
382 unsafe fn clone_from_user_data_unchecked(ptr: *const libc::c_void) -> Self {
383 let borrowed = Arc::from_raw(ptr as *const RwLock<T>);
384 let lock = borrowed.clone();
385 mem::forget(borrowed);
386 RwLockData {
387 lock,
388 _marker: PhantomData,
389 }
390 }
391}
392
393impl<T, OPT> Map for RwLockData<T, OPT>
394where
395 T: NativeClass + Send + Sync,
396 OPT: LockOptions,
397{
398 type Err = LockFailed;
399
400 #[inline]
401 fn map<F, U>(&self, op: F) -> Result<U, LockFailed>
402 where
403 F: FnOnce(&T) -> U,
404 {
405 let guard = match OPT::DEADLOCK_POLICY {
406 DeadlockPolicy::Allow => self.lock.read(),
407 DeadlockPolicy::Pessimistic => self.lock.try_read().ok_or(LockFailed::Pessimistic)?,
408 DeadlockPolicy::Timeout(dur) => self
409 .lock
410 .try_read_for(dur)
411 .ok_or(LockFailed::Timeout(dur))?,
412 };
413
414 Ok(op(&*guard))
415 }
416}
417
418impl<T, OPT> MapMut for RwLockData<T, OPT>
419where
420 T: NativeClass + Send + Sync,
421 OPT: LockOptions,
422{
423 type Err = LockFailed;
424
425 #[inline]
426 fn map_mut<F, U>(&self, op: F) -> Result<U, LockFailed>
427 where
428 F: FnOnce(&mut T) -> U,
429 {
430 let mut guard = match OPT::DEADLOCK_POLICY {
431 DeadlockPolicy::Allow => self.lock.write(),
432 DeadlockPolicy::Pessimistic => self.lock.try_write().ok_or(LockFailed::Pessimistic)?,
433 DeadlockPolicy::Timeout(dur) => self
434 .lock
435 .try_write_for(dur)
436 .ok_or(LockFailed::Timeout(dur))?,
437 };
438
439 Ok(op(&mut *guard))
440 }
441}
442
443impl<T, OPT> Clone for RwLockData<T, OPT> {
444 #[inline]
445 fn clone(&self) -> Self {
446 RwLockData {
447 lock: self.lock.clone(),
448 _marker: PhantomData,
449 }
450 }
451}
452
453#[derive(Debug)]
455pub struct ArcData<T>(Arc<T>);
456
457impl<T> ArcData<T> {
458 #[inline]
467 pub fn into_inner(self) -> Arc<T> {
468 self.0
469 }
470}
471
472unsafe impl<T> UserData for ArcData<T>
473where
474 T: NativeClass + Send + Sync,
475{
476 type Target = T;
477
478 #[inline]
479 fn new(val: Self::Target) -> Self {
480 ArcData(Arc::new(val))
481 }
482
483 #[inline]
484 fn into_user_data(self) -> *const libc::c_void {
485 Arc::into_raw(self.0) as *const libc::c_void
486 }
487
488 #[inline]
489 unsafe fn consume_user_data_unchecked(ptr: *const libc::c_void) -> Self {
490 ArcData(Arc::from_raw(ptr as *const T))
491 }
492
493 #[inline]
494 unsafe fn clone_from_user_data_unchecked(ptr: *const libc::c_void) -> Self {
495 let borrowed = Arc::from_raw(ptr as *const T);
496 let arc = borrowed.clone();
497 mem::forget(borrowed);
498 ArcData(arc)
499 }
500}
501
502impl<T> Map for ArcData<T>
503where
504 T: NativeClass + Send + Sync,
505{
506 type Err = Infallible;
507
508 #[inline]
509 fn map<F, U>(&self, op: F) -> Result<U, Infallible>
510 where
511 F: FnOnce(&T) -> U,
512 {
513 Ok(op(&*self.0))
514 }
515}
516
517impl<T> Clone for ArcData<T> {
518 #[inline]
519 fn clone(&self) -> Self {
520 ArcData(self.0.clone())
521 }
522}
523
524#[derive(Debug)]
536pub struct LocalCellData<T> {
537 inner: Arc<local_cell::LocalCell<T>>,
538}
539
540pub use self::local_cell::LocalCellError;
541
542mod local_cell {
543 use std::cell::{Ref, RefCell, RefMut};
544 use std::mem::ManuallyDrop;
545 use std::thread::{self, ThreadId};
546
547 #[derive(Debug)]
548 pub struct LocalCell<T> {
549 thread_id: ThreadId,
550 cell: RefCell<ManuallyDrop<T>>,
551 }
552
553 impl<T> Drop for LocalCell<T> {
554 fn drop(&mut self) {
555 if self.thread_id == thread::current().id() {
556 unsafe {
557 ManuallyDrop::drop(self.cell.get_mut());
558 }
559 }
560 }
561 }
562
563 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
565 pub enum LocalCellError {
566 DifferentThread {
567 original: ThreadId,
568 current: ThreadId,
569 },
570 BorrowFailed,
571 }
572
573 impl std::fmt::Display for LocalCellError {
574 #[inline]
575 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
576 match self {
577 LocalCellError::DifferentThread { original, current } => write!(
578 f,
579 "accessing from the wrong thread, expected {original:?} found {current:?}"
580 ),
581 LocalCellError::BorrowFailed => write!(
582 f,
583 "borrow failed; a &mut reference was requested, but one already exists. The cause is likely a re-entrant call \
584 (e.g. a GDNative Rust method calls to GDScript, which again calls a Rust method on the same object)"
585 ),
586 }
587 }
588 }
589
590 impl std::error::Error for LocalCellError {}
591
592 impl<T> LocalCell<T> {
593 #[inline]
594 pub fn new(val: T) -> Self {
595 LocalCell {
596 thread_id: thread::current().id(),
597 cell: RefCell::new(ManuallyDrop::new(val)),
598 }
599 }
600
601 #[inline]
602 fn inner(&self) -> Result<&RefCell<ManuallyDrop<T>>, LocalCellError> {
603 let current = thread::current().id();
604
605 if self.thread_id == current {
606 Ok(&self.cell)
607 } else {
608 Err(LocalCellError::DifferentThread {
609 original: self.thread_id,
610 current,
611 })
612 }
613 }
614
615 #[inline]
616 pub fn try_borrow(&self) -> Result<Ref<ManuallyDrop<T>>, LocalCellError> {
617 let inner = self.inner()?;
618 inner.try_borrow().map_err(|_| LocalCellError::BorrowFailed)
619 }
620
621 #[inline]
622 pub fn try_borrow_mut(&self) -> Result<RefMut<ManuallyDrop<T>>, LocalCellError> {
623 let inner = self.inner()?;
624 inner
625 .try_borrow_mut()
626 .map_err(|_| LocalCellError::BorrowFailed)
627 }
628 }
629
630 unsafe impl<T> Send for LocalCell<T> {}
633 unsafe impl<T> Sync for LocalCell<T> {}
634}
635
636unsafe impl<T> UserData for LocalCellData<T>
637where
638 T: NativeClass,
639{
640 type Target = T;
641
642 #[inline]
643 fn new(val: Self::Target) -> Self {
644 LocalCellData {
645 inner: Arc::new(local_cell::LocalCell::new(val)),
646 }
647 }
648
649 #[inline]
650 fn into_user_data(self) -> *const libc::c_void {
651 Arc::into_raw(self.inner) as *const libc::c_void
652 }
653
654 #[inline]
655 unsafe fn consume_user_data_unchecked(ptr: *const libc::c_void) -> Self {
656 LocalCellData {
657 inner: Arc::from_raw(ptr as *const local_cell::LocalCell<T>),
658 }
659 }
660
661 #[inline]
662 unsafe fn clone_from_user_data_unchecked(ptr: *const libc::c_void) -> Self {
663 let borrowed = Arc::from_raw(ptr as *const local_cell::LocalCell<T>);
664 let arc = borrowed.clone();
665 mem::forget(borrowed);
666 LocalCellData { inner: arc }
667 }
668}
669
670impl<T> Map for LocalCellData<T>
671where
672 T: NativeClass,
673{
674 type Err = LocalCellError;
675
676 #[inline]
677 fn map<F, U>(&self, op: F) -> Result<U, Self::Err>
678 where
679 F: FnOnce(&Self::Target) -> U,
680 {
681 self.inner.try_borrow().map(|r| op(&r))
682 }
683}
684
685impl<T> MapMut for LocalCellData<T>
686where
687 T: NativeClass,
688{
689 type Err = LocalCellError;
690
691 #[inline]
692 fn map_mut<F, U>(&self, op: F) -> Result<U, Self::Err>
693 where
694 F: FnOnce(&mut Self::Target) -> U,
695 {
696 self.inner.try_borrow_mut().map(|mut w| op(&mut w))
697 }
698}
699
700impl<T> Clone for LocalCellData<T> {
701 #[inline]
702 fn clone(&self) -> Self {
703 LocalCellData {
704 inner: self.inner.clone(),
705 }
706 }
707}
708
709#[derive(Copy, Debug)]
716pub struct Aether<T> {
717 _marker: PhantomData<T>,
718}
719
720unsafe impl<T> Send for Aether<T> {}
721unsafe impl<T> Sync for Aether<T> {}
722
723impl<T> Clone for Aether<T> {
724 #[inline]
725 fn clone(&self) -> Self {
726 Aether::default()
727 }
728}
729
730impl<T> Default for Aether<T> {
731 #[inline]
732 fn default() -> Self {
733 Aether {
734 _marker: PhantomData,
735 }
736 }
737}
738
739unsafe impl<T> UserData for Aether<T>
740where
741 T: NativeClass + Copy + Default,
742{
743 type Target = T;
744
745 #[inline]
746 fn new(_val: Self::Target) -> Self {
747 Aether::default()
748 }
749
750 #[inline]
751 fn into_user_data(self) -> *const libc::c_void {
752 1 as *const libc::c_void
753 }
754
755 #[inline]
756 unsafe fn consume_user_data_unchecked(_ptr: *const libc::c_void) -> Self {
757 Aether::default()
758 }
759
760 #[inline]
761 unsafe fn clone_from_user_data_unchecked(_ptr: *const libc::c_void) -> Self {
762 Aether::default()
763 }
764}
765
766impl<T> Map for Aether<T>
767where
768 T: NativeClass + Copy + Default,
769{
770 type Err = Infallible;
771
772 #[inline]
773 fn map<F, U>(&self, op: F) -> Result<U, Infallible>
774 where
775 F: FnOnce(&T) -> U,
776 {
777 Ok(op(&Default::default()))
778 }
779}
780
781pub struct Once<T>(Arc<atomic_take::AtomicTake<T>>);
784
785impl<T> Clone for Once<T> {
786 #[inline]
787 fn clone(&self) -> Self {
788 Once(Arc::clone(&self.0))
789 }
790}
791
792unsafe impl<T> UserData for Once<T>
793where
794 T: NativeClass + Send,
795{
796 type Target = T;
797
798 #[inline]
799 fn new(val: Self::Target) -> Self {
800 Once(Arc::new(atomic_take::AtomicTake::new(val)))
801 }
802
803 #[inline]
804 fn into_user_data(self) -> *const libc::c_void {
805 Arc::into_raw(self.0) as *const _
806 }
807
808 #[inline]
809 unsafe fn consume_user_data_unchecked(ptr: *const libc::c_void) -> Self {
810 Once(Arc::from_raw(ptr as *const _))
811 }
812
813 #[inline]
814 unsafe fn clone_from_user_data_unchecked(ptr: *const libc::c_void) -> Self {
815 let borrowed = Arc::from_raw(ptr as *const _);
816 let arc = Arc::clone(&borrowed);
817 mem::forget(borrowed);
818 Once(arc)
819 }
820}
821
822#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
823pub struct ValueTaken;
824
825impl std::error::Error for ValueTaken {}
826impl Display for ValueTaken {
827 #[inline]
828 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
829 write!(f, "this object has already been used once")
830 }
831}
832
833impl<T> MapOwned for Once<T>
834where
835 T: NativeClass + Send,
836{
837 type Err = ValueTaken;
838
839 #[inline]
845 fn map_owned<F, U>(&self, op: F) -> Result<U, Self::Err>
846 where
847 F: FnOnce(Self::Target) -> U,
848 {
849 let v = self.0.take().ok_or(ValueTaken)?;
850 Ok(op(v))
851 }
852}