Skip to content

Commit 6a5d19d

Browse files
authored
Merge pull request #1004 from godot-rust/doc/callable-static-limitations
Document + test limitations of `Callable::from_local_static()`
2 parents b619959 + 8f2da0a commit 6a5d19d

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

godot-core/src/builtin/callable.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,12 @@ type CallableCustomInfo = sys::GDExtensionCallableCustomInfo2;
2323

2424
/// A `Callable` represents a function in Godot.
2525
///
26-
/// Usually a callable is a reference to an `Object` and a method name, this is a standard callable. But can
27-
/// also be a custom callable, which is usually created from `bind`, `unbind`, or a GDScript lambda. See
28-
/// [`Callable::is_custom`].
29-
///
30-
/// Currently, it is impossible to use `bind` and `unbind` in GDExtension, see [godot-cpp#802].
31-
///
32-
/// [godot-cpp#802]: https://github.com/godotengine/godot-cpp/issues/802
26+
/// Callables can be created in many ways:
27+
/// - From an `Object` and a (non-static) method name. This is a _standard_ callable.
28+
/// - From a GDScript class name and a static function name. (This typically works because classes are instances of `GDScript`).
29+
/// - From a GDScript lambda function.
30+
/// - By modifying an existing `Callable` with [`bind()`][Self::bind] or [`unbind()`][Self::unbind].
31+
/// - By creating a custom callable from Rust.
3332
///
3433
/// # Godot docs
3534
///
@@ -72,6 +71,11 @@ impl Callable {
7271
/// Note that due to varying support across different engine versions, the resulting `Callable` has unspecified behavior for
7372
/// methods such as [`method_name()`][Self::method_name], [`object()`][Self::object], [`object_id()`][Self::object_id] or
7473
/// [`get_argument_count()`][Self::arg_len] among others. It is recommended to only use this for calling the function.
74+
///
75+
/// # Compatibility
76+
/// Up until and including Godot 4.3, this method has some limitations:
77+
/// - [`is_valid()`][Self::is_valid] will return `false`, even though the call itself succeeds.
78+
/// - You cannot use statics to connect signals to such callables. Use the new typed signal API instead.
7579
pub fn from_local_static(
7680
class_name: impl meta::AsArg<StringName>,
7781
function_name: impl meta::AsArg<StringName>,

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,22 @@ fn callable_static() {
106106
assert_eq!(callable.object(), None);
107107
assert_eq!(callable.object_id(), None);
108108
assert_eq!(callable.method_name(), None);
109+
assert!(callable.is_custom());
110+
assert!(callable.is_valid());
109111
} else {
110112
assert!(callable.object().is_some());
111113
assert!(callable.object_id().is_some());
112114
assert_eq!(callable.method_name(), Some("concat_array".into()));
113115
assert_eq!(callable.to_string(), "GDScriptNativeClass::concat_array");
116+
assert!(!callable.is_custom());
117+
118+
// Surprisingly false, but call still works (see test below).
119+
// What DOESN'T work is connecting 4.3 static methods to signals via this approach.
120+
assert!(!callable.is_valid());
114121
}
115122

123+
assert!(!callable.is_null());
124+
116125
// Calling works consistently everywhere.
117126
let result = callable.callv(&varray![
118127
10,

0 commit comments

Comments
 (0)