Skip to content

Commit 7a094fa

Browse files
committed
from_instance_id is main-thread only
1 parent 82defa0 commit 7a094fa

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ pub(crate) enum ErrorKind {
163163
FromGodot(FromGodotError),
164164
FromFfi(FromFfiError),
165165
FromVariant(FromVariantError),
166+
InvalidThread,
166167
// FromAnyArray(ArrayMismatch), -- needed if AnyArray downcasts return ConvertError one day.
167168
Custom(Option<Cause>),
168169
}
@@ -173,6 +174,7 @@ impl fmt::Display for ErrorKind {
173174
Self::FromGodot(from_godot) => write!(f, "{from_godot}"),
174175
Self::FromVariant(from_variant) => write!(f, "{from_variant}"),
175176
Self::FromFfi(from_ffi) => write!(f, "{from_ffi}"),
177+
Self::InvalidThread => write!(f, "InstanceID can not be converted outside main-thread"),
176178
Self::Custom(cause) => match cause {
177179
Some(c) => write!(f, "{c}"),
178180
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::{
1818
AsArg, ClassId, Element, FromGodot, GodotConvert, GodotType, PropertyHintInfo, RefArg, ToGodot,
1919
};
@@ -209,9 +209,15 @@ where
209209
impl<T: GodotClass> Gd<T> {
210210
/// Looks up the given instance ID and returns the associated object, if possible.
211211
///
212-
/// If no such instance ID is registered, or if the dynamic type of the object behind that instance ID
213-
/// is not compatible with `T`, then `None` is returned.
212+
/// # Errors
213+
/// - If no such instance ID is registered, or if the dynamic type of the object behind that instance ID
214+
/// is not compatible with `T`, then `Err(...)` is returned.
215+
/// - If called outside the main-thread, then `Err(...)` is returned as well.
214216
pub fn try_from_instance_id(instance_id: InstanceId) -> Result<Self, ConvertError> {
217+
if !sys::is_main_thread() {
218+
return Err(ConvertError::with_kind(ErrorKind::InvalidThread));
219+
}
220+
215221
let ptr = classes::object_ptr_from_id(instance_id);
216222

217223
// SAFETY: assumes that the returned GDExtensionObjectPtr is convertible to Object* (i.e. C++ upcast doesn't modify the pointer)
@@ -226,10 +232,15 @@ impl<T: GodotClass> Gd<T> {
226232
/// Corresponds to Godot's global function `instance_from_id()`.
227233
///
228234
/// # Panics
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`.
235+
/// - If no such instance ID is registered, or if the dynamic type of the object behind that instance ID
236+
/// is not compatible with `T`.
237+
/// - If called on a different thread than the main-thread.
231238
#[doc(alias = "instance_from_id")]
232239
pub fn from_instance_id(instance_id: InstanceId) -> Self {
240+
if !sys::is_main_thread() {
241+
panic!("Gd::instance_from_id is can not be called outside the main-thread");
242+
}
243+
233244
Self::try_from_instance_id(instance_id).unwrap_or_else(|err| {
234245
panic!(
235246
"Instance ID {} does not belong to a valid object of class '{}': {}",

0 commit comments

Comments
 (0)