Skip to content

Commit 978867c

Browse files
committed
Move ToSignalObject -> meta::ObjectToOwned
1 parent f5eee5c commit 978867c

File tree

5 files changed

+55
-35
lines changed

5 files changed

+55
-35
lines changed

godot-core/src/meta/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ mod class_id;
4848
mod element_type;
4949
mod godot_convert;
5050
mod method_info;
51+
mod object_to_owned;
5152
mod param_tuple;
5253
mod property_info;
5354
mod signature;
@@ -67,6 +68,7 @@ pub use class_id::{ClassId, ClassName};
6768
pub use element_type::{ElementScript, ElementType};
6869
pub use godot_convert::{FromGodot, GodotConvert, ToGodot};
6970
pub use method_info::MethodInfo;
71+
pub use object_to_owned::ObjectToOwned;
7072
pub use param_tuple::{InParamTuple, OutParamTuple, ParamTuple};
7173
pub use property_info::{PropertyHintInfo, PropertyInfo};
7274
#[cfg(feature = "trace")]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) godot-rust; Bromeon and contributors.
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
6+
*/
7+
8+
use crate::obj::{Gd, GodotClass, WithBaseField};
9+
10+
/// Obtain owned `Gd` from either `&self` or `&Gd`.
11+
///
12+
/// This trait allows passing either `Gd<T>` or `C` (where `C: WithBaseField`) to functions that need an owned `Gd<T>`.
13+
///
14+
/// This is primarily used for signal connection methods in [`TypedSignal`][crate::registry::signal::TypedSignal] and
15+
/// [`ConnectBuilder`][crate::registry::signal::ConnectBuilder], where you can pass either a `&Gd` (outside) or `&SomeClass`
16+
/// (from within `impl` block) as the receiver object.
17+
///
18+
/// # Similar traits
19+
/// - [`UniformObjectDeref`][crate::meta::UniformObjectDeref] provides unified dereferencing of user and engine classes.
20+
/// - [`AsArg`][crate::meta::AsArg] enables general argument conversions for Godot APIs.
21+
pub trait ObjectToOwned<T: GodotClass> {
22+
/// Converts the object reference to an owned `Gd<T>`.
23+
fn object_to_owned(&self) -> Gd<T>;
24+
}
25+
26+
impl<T: GodotClass> ObjectToOwned<T> for Gd<T> {
27+
fn object_to_owned(&self) -> Gd<T> {
28+
self.clone()
29+
}
30+
}
31+
32+
impl<C: WithBaseField> ObjectToOwned<C> for C {
33+
fn object_to_owned(&self) -> Gd<C> {
34+
WithBaseField::to_gd(self)
35+
}
36+
}

godot-core/src/meta/uniform_object_deref.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ use crate::obj::{Gd, GdMut, GdRef, GodotClass, WithBaseField};
6060
/// abstract_over_objects(&user_obj);
6161
/// }
6262
/// ```
63+
///
64+
/// # Similar traits
65+
/// - [`ObjectToOwned`][crate::meta::ObjectToOwned] provides conversion from `&self` or `&Gd<T>` to owned `Gd<T>`.
6366
//
6467
// The crate `https://crates.io/crates/disjoint_impls` handles this in a more user-friendly way, we should
6568
// consider using it if disjoint impls are going to be frequently used.

godot-core/src/registry/signal/connect_builder.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ use crate::builtin::Callable;
1111
use crate::builtin::{GString, Variant};
1212
use crate::classes::object::ConnectFlags;
1313
use crate::meta;
14-
use crate::meta::InParamTuple;
14+
use crate::meta::{InParamTuple, ObjectToOwned};
1515
use crate::obj::{bounds, Bounds, Gd, GodotClass, WithSignals};
1616
use crate::registry::signal::signal_receiver::{IndirectSignalReceiver, SignalReceiver};
17-
use crate::registry::signal::{ConnectHandle, ToSignalObj, TypedSignal};
17+
use crate::registry::signal::{ConnectHandle, TypedSignal};
1818

1919
/// Builder for customizing signal connections.
2020
///
@@ -239,15 +239,15 @@ impl<C: WithSignals, Ps: InParamTuple + 'static> ConnectBuilder<'_, '_, C, Ps> {
239239
/// - If you need cross-thread signals, use [`connect_sync()`](#method.connect_sync) instead (requires feature "experimental-threads").
240240
pub fn connect_other_mut<F, OtherC>(
241241
self,
242-
object: &impl ToSignalObj<OtherC>,
242+
object: &impl ObjectToOwned<OtherC>,
243243
mut method: F,
244244
) -> ConnectHandle
245245
where
246246
OtherC: GodotClass + Bounds<Declarer = bounds::DeclUser>,
247247
for<'c_rcv> F: SignalReceiver<&'c_rcv mut OtherC, Ps>,
248248
for<'c_rcv> IndirectSignalReceiver<'c_rcv, &'c_rcv mut OtherC, Ps, F>: From<&'c_rcv mut F>,
249249
{
250-
let mut gd = object.to_signal_obj();
250+
let mut gd = object.object_to_owned();
251251

252252
let godot_fn = make_godot_fn(move |args| {
253253
let mut guard = Gd::bind_mut(&mut gd);
@@ -256,7 +256,7 @@ impl<C: WithSignals, Ps: InParamTuple + 'static> ConnectBuilder<'_, '_, C, Ps> {
256256
.call(&mut *guard, args);
257257
});
258258

259-
self.inner_connect_godot_fn::<F>(godot_fn, &object.to_signal_obj())
259+
self.inner_connect_godot_fn::<F>(godot_fn, &object.object_to_owned())
260260
}
261261

262262
/// Connect a method with any `&mut Gd<OtherC>` as the first parameter (user + engine classes).
@@ -272,23 +272,23 @@ impl<C: WithSignals, Ps: InParamTuple + 'static> ConnectBuilder<'_, '_, C, Ps> {
272272
/// - If you need cross-thread signals, use [`connect_sync()`](#method.connect_sync) instead (requires feature "experimental-threads").
273273
pub fn connect_other_gd<F, OtherC>(
274274
self,
275-
object: &impl ToSignalObj<OtherC>,
275+
object: &impl ObjectToOwned<OtherC>,
276276
mut method: F,
277277
) -> ConnectHandle
278278
where
279279
OtherC: GodotClass,
280280
F: SignalReceiver<Gd<OtherC>, Ps>,
281281
for<'c_rcv> IndirectSignalReceiver<'c_rcv, Gd<OtherC>, Ps, F>: From<&'c_rcv mut F>,
282282
{
283-
let gd = object.to_signal_obj();
283+
let gd = object.object_to_owned();
284284

285285
let godot_fn = make_godot_fn(move |args| {
286286
IndirectSignalReceiver::from(&mut method)
287287
.function()
288288
.call(gd.clone(), args);
289289
});
290290

291-
self.inner_connect_godot_fn::<F>(godot_fn, &object.to_signal_obj())
291+
self.inner_connect_godot_fn::<F>(godot_fn, &object.object_to_owned())
292292
}
293293

294294
/// Connect to this signal using a thread-safe function, allows the signal to be called across threads.

godot-core/src/registry/signal/typed_signal.rs

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,10 @@ use super::{make_callable_name, make_godot_fn, ConnectBuilder, ConnectHandle, Si
1313
use crate::builtin::{Callable, Variant};
1414
use crate::classes::object::ConnectFlags;
1515
use crate::meta;
16-
use crate::meta::{InParamTuple, UniformObjectDeref};
17-
use crate::obj::{Gd, GodotClass, WithBaseField, WithSignals};
16+
use crate::meta::{InParamTuple, ObjectToOwned, UniformObjectDeref};
17+
use crate::obj::{Gd, GodotClass, WithSignals};
1818
use crate::registry::signal::signal_receiver::{IndirectSignalReceiver, SignalReceiver};
1919

20-
// TODO(v0.4): find more general name for trait.
21-
/// Object part of the signal receiver (handler).
22-
///
23-
/// Functionality overlaps partly with [`meta::AsObjectArg`] and [`meta::AsArg<ObjectArg>`]. Can however not directly be replaced
24-
/// with `AsObjectArg`, since that allows nullability and doesn't require `&mut T`. Maybe there's a way to reuse them though.
25-
pub trait ToSignalObj<C: GodotClass> {
26-
fn to_signal_obj(&self) -> Gd<C>;
27-
}
28-
29-
impl<C: GodotClass> ToSignalObj<C> for Gd<C> {
30-
fn to_signal_obj(&self) -> Gd<C> {
31-
self.clone()
32-
}
33-
}
34-
35-
impl<C: WithBaseField> ToSignalObj<C> for C {
36-
fn to_signal_obj(&self) -> Gd<C> {
37-
WithBaseField::to_gd(self)
38-
}
39-
}
40-
4120
// ----------------------------------------------------------------------------------------------------------------------------------------------
4221

4322
/// Type-safe version of a Godot signal.
@@ -234,23 +213,23 @@ impl<C: WithSignals, Ps: InParamTuple + 'static> TypedSignal<'_, C, Ps> {
234213
/// The parameter `object` can be of 2 different "categories":
235214
/// - Any `&Gd<OtherC>` (e.g.: `&Gd<Node>`, `&Gd<CustomUserClass>`).
236215
/// - `&OtherC`, as long as `OtherC` is a user class that contains a `base` field (it implements the
237-
/// [`WithBaseField`](WithBaseField) trait).
216+
/// [`WithBaseField`][crate::obj::WithBaseField] trait).
238217
///
239218
/// ---
240219
///
241220
/// - To connect to methods on the object that owns this signal, use [`connect_self()`][Self::connect_self].
242221
/// - If you need [`connect flags`](ConnectFlags) or cross-thread signals, use [`builder()`][Self::builder].
243222
pub fn connect_other<F, OtherC, Declarer>(
244223
&self,
245-
object: &impl ToSignalObj<OtherC>,
224+
object: &impl ObjectToOwned<OtherC>,
246225
mut method: F,
247226
) -> ConnectHandle
248227
where
249228
OtherC: UniformObjectDeref<Declarer>,
250229
for<'c_rcv> F: SignalReceiver<&'c_rcv mut OtherC, Ps> + 'static,
251230
for<'c_rcv> IndirectSignalReceiver<'c_rcv, &'c_rcv mut OtherC, Ps, F>: From<&'c_rcv mut F>,
252231
{
253-
let mut gd = object.to_signal_obj();
232+
let mut gd = object.object_to_owned();
254233

255234
let godot_fn = make_godot_fn(move |args| {
256235
let mut target = OtherC::object_as_mut(&mut gd);
@@ -260,6 +239,6 @@ impl<C: WithSignals, Ps: InParamTuple + 'static> TypedSignal<'_, C, Ps> {
260239
.call(target_mut, args);
261240
});
262241

263-
self.inner_connect_godot_fn::<F>(godot_fn, &object.to_signal_obj())
242+
self.inner_connect_godot_fn::<F>(godot_fn, &object.object_to_owned())
264243
}
265244
}

0 commit comments

Comments
 (0)