Skip to content

Commit 334a8d3

Browse files
authored
Merge pull request #990 from godot-rust/qol/callable-cleanup
Clean up `Callable` + tests, fix `check.sh test`
2 parents 06dcda7 + 1625cac commit 334a8d3

File tree

3 files changed

+124
-93
lines changed

3 files changed

+124
-93
lines changed

godot-core/src/builtin/callable.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ impl Callable {
307307
/// _Godot equivalent: `get_method`_
308308
///
309309
/// [godot#73052]: https://github.com/godotengine/godot/issues/73052
310+
#[doc(alias = "get_method")]
310311
pub fn method_name(&self) -> Option<StringName> {
311312
let method_name = self.as_inner().get_method();
312313
if method_name.is_empty() {
@@ -384,19 +385,28 @@ impl Callable {
384385
self.as_inner().is_valid()
385386
}
386387

388+
/// Returns a copy of the callable, ignoring `args` user arguments.
389+
///
390+
/// Despite its name, this does **not** directly undo previous `bind()` calls. See
391+
/// [Godot docs](https://docs.godotengine.org/en/latest/classes/class_callable.html#class-callable-method-unbind) for up-to-date semantics.
387392
pub fn unbind(&self, args: usize) -> Callable {
388393
self.as_inner().unbind(args as i64)
389394
}
390395

391396
#[cfg(since_api = "4.3")]
392-
#[doc(alias = "get_argument_count")]
393-
pub fn arg_len(&self) -> usize {
397+
pub fn get_argument_count(&self) -> usize {
394398
self.as_inner().get_argument_count() as usize
395399
}
396400

397-
#[doc(alias = "get_bound_arguments_count")]
398-
pub fn bound_args_len(&self) -> i64 {
399-
self.as_inner().get_bound_arguments_count()
401+
/// Get number of bound arguments.
402+
///
403+
/// Note: for Godot < 4.4, this function returns incorrect results when applied on a callable that used `unbind()`.
404+
/// See [#98713](https://github.com/godotengine/godot/pull/98713) for details.
405+
pub fn get_bound_arguments_count(&self) -> usize {
406+
// This does NOT fix the bug before Godot 4.4, just cap it at zero. unbind() will still erroneously decrease the bound arguments count.
407+
let alleged_count = self.as_inner().get_bound_arguments_count();
408+
409+
alleged_count.max(0) as usize
400410
}
401411

402412
#[doc(hidden)]

godot-macros/src/lib.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -710,10 +710,23 @@ pub fn derive_godot_class(input: TokenStream) -> TokenStream {
710710
/// `#[rpc]` implies `#[func]`. You can use both attributes together, if you need to configure other `#[func]`-specific keys.
711711
///
712712
/// For example, the following method declarations are all equivalent:
713-
/// ```
713+
/// ```no_run
714+
/// # // Polyfill without full codegen.
715+
/// # #![allow(non_camel_case_types)]
716+
/// # #[cfg(not(feature = "codegen-full"))]
717+
/// # enum RpcMode { DISABLED, ANY_PEER, AUTHORITY }
718+
/// # #[cfg(not(feature = "codegen-full"))]
719+
/// # enum TransferMode { UNRELIABLE, UNRELIABLE_ORDERED, RELIABLE }
720+
/// # #[cfg(not(feature = "codegen-full"))]
721+
/// # pub struct RpcConfig { pub rpc_mode: RpcMode, pub transfer_mode: TransferMode, pub call_local: bool, pub channel: u32 }
722+
/// # #[cfg(not(feature = "codegen-full"))]
723+
/// # impl Default for RpcConfig { fn default() -> Self { todo!("never called") } }
724+
/// # #[cfg(feature = "codegen-full")]
714725
/// use godot::classes::multiplayer_api::RpcMode;
726+
/// # #[cfg(feature = "codegen-full")]
715727
/// use godot::classes::multiplayer_peer::TransferMode;
716728
/// use godot::prelude::*;
729+
/// # #[cfg(feature = "codegen-full")]
717730
/// use godot::register::RpcConfig;
718731
///
719732
/// # #[derive(GodotClass)]

0 commit comments

Comments
 (0)