Skip to content

Commit 7a3ff27

Browse files
committed
Add Variant::object_id()
1 parent 8ad9cb0 commit 7a3ff27

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

godot-core/src/builtin/variant/mod.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,14 @@ impl Variant {
4646

4747
/// Create a variant holding a non-nil value.
4848
///
49-
/// Equivalent to `value.to_variant()`.
49+
/// Equivalent to [`value.to_variant()`][ToGodot::to_variant], but consumes the argument.
5050
pub fn from<T: ToGodot>(value: T) -> Self {
5151
value.to_variant()
5252
}
5353

5454
/// ⚠️ Convert to type `T`, panicking on failure.
5555
///
56-
/// Equivalent to `T::from_variant(&self)`.
56+
/// Equivalent to [`T::from_variant(&self)`][FromGodot::from_variant].
5757
///
5858
/// # Panics
5959
/// When this variant holds a different type.
@@ -63,14 +63,14 @@ impl Variant {
6363

6464
/// Convert to type `T`, returning `Err` on failure.
6565
///
66-
/// Equivalent to `T::try_from_variant(&self)`.
66+
/// Equivalent to [`T::try_from_variant(&self)`][FromGodot::try_from_variant].
6767
pub fn try_to<T: FromGodot>(&self) -> Result<T, ConvertError> {
6868
T::try_from_variant(self)
6969
}
7070

7171
/// Checks whether the variant is empty (`null` value in GDScript).
7272
///
73-
/// See also [`Self::get_type`].
73+
/// See also [`get_type()`][Self::get_type].
7474
pub fn is_nil(&self) -> bool {
7575
// Use get_type() rather than sys_type(), to also cover nullptr OBJECT as NIL
7676
self.get_type() == VariantType::NIL
@@ -79,8 +79,8 @@ impl Variant {
7979
/// Returns the type that is currently held by this variant.
8080
///
8181
/// If this variant holds a type `Object` but no instance (represented as a null object pointer), then `Nil` will be returned for
82-
/// consistency. This may deviate from Godot behavior -- for example, calling `Node::get_node_or_null()` with an invalid
83-
/// path returns a variant that has type `Object` but acts like `Nil` for all practical purposes.
82+
/// consistency. This may deviate from Godot behavior -- for example, calling [`Node::get_node_or_null()`][crate::classes::Node::get_node_or_null]
83+
/// with an invalid path returns a variant that has type `Object` but acts like `Nil` for all practical purposes.
8484
pub fn get_type(&self) -> VariantType {
8585
let sys_type = self.sys_type();
8686

@@ -106,6 +106,20 @@ impl Variant {
106106
}
107107
}
108108

109+
/// For variants holding an object, returns the object's instance ID.
110+
///
111+
/// If the variant is not an object, returns `None`.
112+
///
113+
/// If the object is dead, the instance ID is still returned. Use [`Variant::try_to::<Gd<T>>()`][Self::try_to]
114+
/// to retrieve only live objects.
115+
#[cfg(since_api = "4.4")]
116+
pub fn object_id(&self) -> Option<crate::obj::InstanceId> {
117+
// SAFETY: safe to call for non-object variants (returns 0).
118+
let raw_id: u64 = unsafe { interface_fn!(variant_get_object_instance_id)(self.var_sys()) };
119+
120+
crate::obj::InstanceId::try_from_u64(raw_id)
121+
}
122+
109123
/// ⚠️ Calls the specified `method` with the given `args`.
110124
///
111125
/// Supports `Object` as well as built-ins with methods (e.g. `Array`, `Vector3`, `GString`, etc.).

itest/rust/src/builtin_tests/containers/variant_test.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,27 @@ fn variant_get_type() {
186186
assert_eq!(variant.get_type(), VariantType::BASIS)
187187
}
188188

189+
#[cfg(since_api = "4.4")]
190+
#[itest]
191+
fn variant_object_id() {
192+
let variant = Variant::nil();
193+
assert_eq!(variant.object_id(), None);
194+
195+
let variant = Variant::from(77);
196+
assert_eq!(variant.object_id(), None);
197+
198+
let node = Node::new_alloc();
199+
let id = node.instance_id();
200+
201+
let variant = node.to_variant();
202+
assert_eq!(variant.object_id(), Some(id));
203+
204+
node.free();
205+
206+
// When freed, variant still returns the object ID.
207+
assert_eq!(variant.object_id(), Some(id));
208+
}
209+
189210
#[itest]
190211
fn variant_equal() {
191212
assert_eq!(Variant::nil(), ().to_variant());

0 commit comments

Comments
 (0)