@@ -411,7 +411,7 @@ impl<T: GodotClass> Gd<T> {
411411 #[ doc( hidden) ]
412412 pub fn script_sys ( & self ) -> sys:: GDExtensionScriptLanguagePtr
413413 where
414- T : Inherits < crate :: classes:: ScriptLanguage > ,
414+ T : Inherits < classes:: ScriptLanguage > ,
415415 {
416416 self . raw . script_sys ( )
417417 }
@@ -553,6 +553,43 @@ where
553553 }
554554}
555555
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+
556593// ----------------------------------------------------------------------------------------------------------------------------------------------
557594// Trait impls
558595
@@ -737,83 +774,5 @@ impl<T: GodotClass> std::hash::Hash for Gd<T> {
737774impl < T : GodotClass > std:: panic:: UnwindSafe for Gd < T > { }
738775impl < T : GodotClass > std:: panic:: RefUnwindSafe for Gd < T > { }
739776
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