Skip to content

Commit cd52ba1

Browse files
committed
from_instance_id is main-thread only
1 parent 1a42da5 commit cd52ba1

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
@@ -162,6 +162,7 @@ pub(crate) enum ErrorKind {
162162
FromGodot(FromGodotError),
163163
FromFfi(FromFfiError),
164164
FromVariant(FromVariantError),
165+
InvalidThread,
165166
// FromAnyArray(ArrayMismatch), -- needed if AnyArray downcasts return ConvertError one day.
166167
Custom(Option<Cause>),
167168
}
@@ -172,6 +173,7 @@ impl fmt::Display for ErrorKind {
172173
Self::FromGodot(from_godot) => write!(f, "{from_godot}"),
173174
Self::FromVariant(from_variant) => write!(f, "{from_variant}"),
174175
Self::FromFfi(from_ffi) => write!(f, "{from_ffi}"),
176+
Self::InvalidThread => write!(f, "InstanceID can not be converted outside main-thread"),
175177
Self::Custom(cause) => match cause {
176178
Some(c) => write!(f, "{c}"),
177179
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,
@@ -250,9 +250,15 @@ where
250250
impl<T: GodotClass> Gd<T> {
251251
/// Looks up the given instance ID and returns the associated object, if possible.
252252
///
253-
/// If no such instance ID is registered, or if the dynamic type of the object behind that instance ID
254-
/// is not compatible with `T`, then `None` is returned.
253+
/// # Errors
254+
/// - If no such instance ID is registered, or if the dynamic type of the object behind that instance ID
255+
/// is not compatible with `T`, then `Err(...)` is returned.
256+
/// - If called outside the main-thread, then `Err(...)` is returned as well.
255257
pub fn try_from_instance_id(instance_id: InstanceId) -> Result<Self, ConvertError> {
258+
if !sys::is_main_thread() {
259+
return Err(ConvertError::with_kind(ErrorKind::InvalidThread));
260+
}
261+
256262
let ptr = classes::object_ptr_from_id(instance_id);
257263

258264
// SAFETY: assumes that the returned GDExtensionObjectPtr is convertible to Object* (i.e. C++ upcast doesn't modify the pointer)
@@ -267,10 +273,15 @@ impl<T: GodotClass> Gd<T> {
267273
/// Corresponds to Godot's global function `instance_from_id()`.
268274
///
269275
/// # Panics
270-
/// If no such instance ID is registered, or if the dynamic type of the object behind that instance ID
271-
/// is not compatible with `T`.
276+
/// - If no such instance ID is registered, or if the dynamic type of the object behind that instance ID
277+
/// is not compatible with `T`.
278+
/// - If called on a different thread than the main-thread.
272279
#[doc(alias = "instance_from_id")]
273280
pub fn from_instance_id(instance_id: InstanceId) -> Self {
281+
if !sys::is_main_thread() {
282+
panic!("Gd::instance_from_id is can not be called outside the main-thread");
283+
}
284+
274285
Self::try_from_instance_id(instance_id).unwrap_or_else(|err| {
275286
panic!(
276287
"Instance ID {} does not belong to a valid object of class '{}': {}",

0 commit comments

Comments
 (0)