Skip to content

Commit 64bf8d2

Browse files
committed
from_instance_id is main-thread only
1 parent 6198574 commit 64bf8d2

2 files changed

Lines changed: 18 additions & 5 deletions

File tree

godot-core/src/meta/error/convert_error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ pub(crate) enum ErrorKind {
164164
FromGodot(FromGodotError),
165165
FromFfi(FromFfiError),
166166
FromVariant(FromVariantError),
167+
InvalidThread,
167168
// FromAnyArray(ArrayMismatch), -- needed if AnyArray downcasts return ConvertError one day.
168169
Custom(Option<Cause>),
169170
}
@@ -174,6 +175,7 @@ impl fmt::Display for ErrorKind {
174175
Self::FromGodot(from_godot) => write!(f, "{from_godot}"),
175176
Self::FromVariant(from_variant) => write!(f, "{from_variant}"),
176177
Self::FromFfi(from_ffi) => write!(f, "{from_ffi}"),
178+
Self::InvalidThread => write!(f, "InstanceID can not be converted outside main-thread"),
177179
Self::Custom(cause) => match cause {
178180
Some(c) => write!(f, "{c}"),
179181
None => write!(f, "custom error"),

godot-core/src/obj/gd.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use godot_ffi::is_main_thread;
1313
use sys::{SysPtr as _, static_assert_eq_size_align};
1414

1515
use crate::builtin::{Callable, NodePath, StringName, Variant};
16-
use crate::meta::error::{ConvertError, FromFfiError};
16+
use crate::meta::error::{ConvertError, ErrorKind, FromFfiError};
1717
use crate::meta::shape::GodotShape;
1818
use crate::meta::{
1919
AsArg, ClassId, Element, FromGodot, GodotConvert, GodotNullableType, GodotType, RefArg, ToGodot,
@@ -226,9 +226,15 @@ where
226226
impl<T: GodotClass> Gd<T> {
227227
/// Looks up the given instance ID and returns the associated object, if possible.
228228
///
229-
/// If no such instance ID is registered, or if the dynamic type of the object behind that instance ID
230-
/// is not compatible with `T`, then `None` is returned.
229+
/// # Errors
230+
/// - If no such instance ID is registered, or if the dynamic type of the object behind that instance ID
231+
/// is not compatible with `T`, then `Err(...)` is returned.
232+
/// - If called outside the main-thread, then `Err(...)` is returned as well.
231233
pub fn try_from_instance_id(instance_id: InstanceId) -> Result<Self, ConvertError> {
234+
if !sys::is_main_thread() {
235+
return Err(ConvertError::with_kind(ErrorKind::InvalidThread));
236+
}
237+
232238
let ptr = classes::object_ptr_from_id(instance_id);
233239

234240
// SAFETY: assumes that the returned GDExtensionObjectPtr is convertible to Object* (i.e. C++ upcast doesn't modify the pointer)
@@ -243,10 +249,15 @@ impl<T: GodotClass> Gd<T> {
243249
/// Corresponds to Godot's global function `instance_from_id()`.
244250
///
245251
/// # Panics
246-
/// If no such instance ID is registered, or if the dynamic type of the object behind that instance ID
247-
/// is not compatible with `T`.
252+
/// - If no such instance ID is registered, or if the dynamic type of the object behind that instance ID
253+
/// is not compatible with `T`.
254+
/// - If called on a different thread than the main-thread.
248255
#[doc(alias = "instance_from_id")]
249256
pub fn from_instance_id(instance_id: InstanceId) -> Self {
257+
if !sys::is_main_thread() {
258+
panic!("Gd::instance_from_id is can not be called outside the main-thread");
259+
}
260+
250261
Self::try_from_instance_id(instance_id).unwrap_or_else(|err| {
251262
panic!(
252263
"Instance ID {} does not belong to a valid object of class '{}': {}",

0 commit comments

Comments
 (0)