|
8 | 8 | use crate::builtin::{
|
9 | 9 | GString, StringName, VariantArray, VariantDispatch, VariantOperator, VariantType,
|
10 | 10 | };
|
11 |
| -use crate::meta::error::ConvertError; |
| 11 | +use crate::meta::error::{ConvertError, ErrorKind, FromVariantError}; |
12 | 12 | use crate::meta::{arg_into_ref, ArrayElement, AsArg, FromGodot, ToGodot};
|
13 | 13 | use godot_ffi as sys;
|
14 | 14 | use std::{fmt, ptr};
|
@@ -110,10 +110,47 @@ impl Variant {
|
110 | 110 | ///
|
111 | 111 | /// If the variant is not an object, returns `None`.
|
112 | 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")] |
| 113 | + /// # Panics |
| 114 | + /// If the variant holds an object and that object is dead. |
| 115 | + /// |
| 116 | + /// If you want to detect this case, use [`try_to::<Gd<...>>()`](Self::try_to). If you want to retrieve the previous instance ID of a |
| 117 | + /// freed object for whatever reason, use [`object_id_unchecked()`][Self::object_id_unchecked]. This method is only available from |
| 118 | + /// Godot 4.4 onwards. |
116 | 119 | pub fn object_id(&self) -> Option<crate::obj::InstanceId> {
|
| 120 | + #[cfg(since_api = "4.4")] |
| 121 | + { |
| 122 | + assert!( |
| 123 | + self.get_type() != VariantType::OBJECT || self.is_object_alive(), |
| 124 | + "Variant::object_id(): object has been freed" |
| 125 | + ); |
| 126 | + self.object_id_unchecked() |
| 127 | + } |
| 128 | + |
| 129 | + #[cfg(before_api = "4.4")] |
| 130 | + { |
| 131 | + match self.try_to::<crate::obj::Gd<crate::classes::Object>>() { |
| 132 | + Ok(obj) => Some(obj.instance_id_unchecked()), |
| 133 | + Err(c) |
| 134 | + if matches!( |
| 135 | + c.kind(), |
| 136 | + ErrorKind::FromVariant(FromVariantError::DeadObject) |
| 137 | + ) => |
| 138 | + { |
| 139 | + panic!("Variant::object_id(): object has been freed") |
| 140 | + } |
| 141 | + _ => None, // other conversion errors |
| 142 | + } |
| 143 | + } |
| 144 | + } |
| 145 | + |
| 146 | + /// For variants holding an object, returns the object's instance ID. |
| 147 | + /// |
| 148 | + /// If the variant is not an object, returns `None`. |
| 149 | + /// |
| 150 | + /// If the object is dead, the instance ID is still returned, similar to [`Gd::instance_id_unchecked()`][crate::obj::Gd::instance_id_unchecked]. |
| 151 | + /// Unless you have a very good reason to use this, we recommend using [`object_id()`][Self::object_id] instead. |
| 152 | + #[cfg(since_api = "4.4")] |
| 153 | + pub fn object_id_unchecked(&self) -> Option<crate::obj::InstanceId> { |
117 | 154 | // SAFETY: safe to call for non-object variants (returns 0).
|
118 | 155 | let raw_id: u64 = unsafe { interface_fn!(variant_get_object_instance_id)(self.var_sys()) };
|
119 | 156 |
|
|
0 commit comments