@@ -411,7 +411,7 @@ impl<T: GodotClass> Gd<T> {
411
411
#[ doc( hidden) ]
412
412
pub fn script_sys ( & self ) -> sys:: GDExtensionScriptLanguagePtr
413
413
where
414
- T : Inherits < crate :: classes:: ScriptLanguage > ,
414
+ T : Inherits < classes:: ScriptLanguage > ,
415
415
{
416
416
self . raw . script_sys ( )
417
417
}
@@ -553,6 +553,43 @@ where
553
553
}
554
554
}
555
555
556
+ /// _The methods in this impl block are only available for objects `T` that are reference-counted,
557
+ /// i.e. anything that inherits `RefCounted`._ <br><br>
558
+ impl < T > Gd < T >
559
+ where
560
+ T : GodotClass + Bounds < Memory = bounds:: MemRefCounted > ,
561
+ {
562
+ /// Makes sure that `self` does not share references with other `Gd` instances.
563
+ ///
564
+ /// If `self` is unique, i.e. its reference count is 1, then `Ok(self)` is returned.
565
+ ///
566
+ /// If `self` is shared or not reference-counted (`T=Object` pointing to a dynamic type that is manually managed),
567
+ /// then `Err((self, NotUniqueError))` is returned. You can thus reuse the original object (first element in the tuple).
568
+ ///
569
+ /// ## Example
570
+ ///
571
+ /// ```no_run
572
+ /// use godot::prelude::*;
573
+ /// use godot::meta::error::NotUniqueError;
574
+ ///
575
+ /// let unique = RefCounted::new_gd();
576
+ /// assert!(unique.try_to_unique().is_ok());
577
+ ///
578
+ /// let shared = RefCounted::new_gd();
579
+ /// let shared2 = shared.clone();
580
+ /// assert!(shared.try_to_unique().is_err());
581
+ /// ```
582
+ pub fn try_to_unique ( mut self ) -> Result < Self , ( Self , NotUniqueError ) > {
583
+ use crate :: obj:: bounds:: DynMemory as _;
584
+
585
+ match <T as Bounds >:: DynMemory :: get_ref_count ( & self . raw ) {
586
+ Some ( 1 ) => Ok ( self ) ,
587
+ Some ( ref_count) => Err ( ( self , NotUniqueError :: Shared { ref_count } ) ) ,
588
+ None => Err ( ( self , NotUniqueError :: NotRefCounted ) ) ,
589
+ }
590
+ }
591
+ }
592
+
556
593
// ----------------------------------------------------------------------------------------------------------------------------------------------
557
594
// Trait impls
558
595
@@ -737,83 +774,5 @@ impl<T: GodotClass> std::hash::Hash for Gd<T> {
737
774
impl < T : GodotClass > std:: panic:: UnwindSafe for Gd < T > { }
738
775
impl < T : GodotClass > std:: panic:: RefUnwindSafe for Gd < T > { }
739
776
740
- /// Error stemming from the non-uniqueness of the [`Gd`] instance.
741
- ///
742
- /// Keeping track of the uniqueness of references can be crucial in many applications, especially if we want to ensure
743
- /// that the passed [`Gd`] reference will be possessed by only one different object instance or function in its lifetime.
744
- ///
745
- /// Only applicable to [`GodotClass`] objects that inherit from [`RefCounted`](crate::gen::classes::RefCounted). To check the
746
- /// uniqueness, call the `check()` associated method.
747
- ///
748
- /// ## Example
749
- ///
750
- /// ```no_run
751
- /// use godot::prelude::*;
752
- /// use godot::obj::NotUniqueError;
753
- ///
754
- /// let shared = RefCounted::new_gd();
755
- /// let cloned = shared.clone();
756
- /// let result = NotUniqueError::check(shared);
757
- ///
758
- /// assert!(result.is_err());
759
- ///
760
- /// if let Err(error) = result {
761
- /// assert_eq!(error.get_reference_count(), 2)
762
- /// }
763
- /// ```
764
- #[ derive( Debug ) ]
765
- pub struct NotUniqueError {
766
- reference_count : i32 ,
767
- }
768
-
769
- impl NotUniqueError {
770
- /// check [`Gd`] reference uniqueness.
771
- ///
772
- /// Checks the [`Gd`] of the [`GodotClass`](crate::obj::GodotClass) that inherits from [`RefCounted`](crate::gen::classes::RefCounted)
773
- /// if it is an unique reference to the object.
774
- ///
775
- /// ## Example
776
- ///
777
- /// ```no_run
778
- /// use godot::prelude::*;
779
- /// use godot::obj::NotUniqueError;
780
- ///
781
- /// let unique = RefCounted::new_gd();
782
- /// assert!(NotUniqueError::check(unique).is_ok());
783
- ///
784
- /// let shared = RefCounted::new_gd();
785
- /// let cloned = shared.clone();
786
- /// assert!(NotUniqueError::check(shared).is_err());
787
- /// assert!(NotUniqueError::check(cloned).is_err());
788
- /// ```
789
- pub fn check < T > ( rc : Gd < T > ) -> Result < Gd < T > , Self >
790
- where
791
- T : Inherits < crate :: gen:: classes:: RefCounted > ,
792
- {
793
- let rc = rc. upcast :: < crate :: gen:: classes:: RefCounted > ( ) ;
794
- let reference_count = rc. get_reference_count ( ) ;
795
-
796
- if reference_count != 1 {
797
- Err ( Self { reference_count } )
798
- } else {
799
- Ok ( rc. cast :: < T > ( ) )
800
- }
801
- }
802
-
803
- /// Get the detected reference count
804
- pub fn get_reference_count ( & self ) -> i32 {
805
- self . reference_count
806
- }
807
- }
808
-
809
- impl std:: error:: Error for NotUniqueError { }
810
-
811
- impl std:: fmt:: Display for NotUniqueError {
812
- fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
813
- write ! (
814
- f,
815
- "pointer is not unique, current reference count: {}" ,
816
- self . reference_count
817
- )
818
- }
819
- }
777
+ #[ deprecated = "Moved to `godot::meta::error`" ]
778
+ pub use crate :: meta:: error:: NotUniqueError ;
0 commit comments