Skip to content

Commit 6d88430

Browse files
committed
Reduce code duplication in Storage
1 parent 62a7381 commit 6d88430

File tree

5 files changed

+104
-107
lines changed

5 files changed

+104
-107
lines changed

godot-core/src/registry/class.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,13 @@ pub fn auto_register_classes(init_level: InitLevel) {
216216
// but it is much slower and doesn't guarantee that all the dependent classes will be already loaded in most cases.
217217
register_classes_and_dyn_traits(&mut map, init_level);
218218

219-
// actually register all the classes
219+
// Actually register all the classes.
220220
for info in map.into_values() {
221+
#[cfg(feature = "debug-log")]
222+
let class_name = info.class_name;
223+
221224
register_class_raw(info);
225+
222226
out!("Class {class_name} loaded.");
223227
}
224228

godot-core/src/storage/instance_storage.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* License, v. 2.0. If a copy of the MPL was not distributed with this
55
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
66
*/
7+
78
use godot_ffi as sys;
89
use std::cell::Cell;
910
use std::ptr;

godot-core/src/storage/mod.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,71 @@ mod multi_threaded;
1111
#[cfg_attr(feature = "experimental-threads", allow(dead_code))]
1212
mod single_threaded;
1313

14+
use godot_ffi::out;
1415
pub use instance_storage::*;
16+
use std::any::type_name;
17+
18+
// ----------------------------------------------------------------------------------------------------------------------------------------------
19+
// Shared code for submodules
20+
21+
fn bind_failed<T>(err: Box<dyn std::error::Error>) -> ! {
22+
let ty = type_name::<T>();
23+
panic!(
24+
"Gd<T>::bind() failed, already bound; T = {ty}.\n \
25+
Make sure to use `self.base_mut()` or `self.base()` instead of `self.to_gd()` when possible.\n \
26+
Details: {err}."
27+
)
28+
}
29+
30+
fn bind_mut_failed<T>(err: Box<dyn std::error::Error>) -> ! {
31+
let ty = type_name::<T>();
32+
panic!(
33+
"Gd<T>::bind_mut() failed, already bound; T = {ty}.\n \
34+
Make sure to use `self.base_mut()` instead of `self.to_gd()` when possible.\n \
35+
Details: {err}."
36+
)
37+
}
38+
39+
fn bug_inaccessible<T>(err: Box<dyn std::error::Error>) -> ! {
40+
// We should never hit this, except maybe in extreme cases like having more than
41+
// `usize::MAX` borrows.
42+
let ty = type_name::<T>();
43+
panic!(
44+
"`base_mut()` failed for type T = {ty}.\n \
45+
This is most likely a bug, please report it.\n \
46+
Details: {err}."
47+
)
48+
}
49+
50+
fn log_construct<T>() {
51+
out!(
52+
" Storage::construct <{ty}>",
53+
ty = type_name::<T>()
54+
);
55+
}
56+
57+
fn log_inc_ref<T: StorageRefCounted>(storage: &T) {
58+
out!(
59+
" Storage::on_inc_ref (rc={rc}) <{ty}> -- {base:?}",
60+
rc = T::godot_ref_count(storage),
61+
base = storage.base(),
62+
ty = type_name::<T>(),
63+
);
64+
}
65+
66+
fn log_dec_ref<T: StorageRefCounted>(storage: &T) {
67+
out!(
68+
" | Storage::on_dec_ref (rc={rc}) <{ty}> -- {base:?}",
69+
rc = T::godot_ref_count(storage),
70+
base = storage.base(),
71+
ty = type_name::<T>(),
72+
);
73+
}
74+
75+
fn log_drop<T: StorageRefCounted>(storage: &T) {
76+
out!(
77+
" Storage::drop (rc={rc}) <{base:?}>",
78+
rc = storage.godot_ref_count(),
79+
base = storage.base(),
80+
);
81+
}

godot-core/src/storage/multi_threaded.rs

Lines changed: 14 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
66
*/
77

8-
use std::any::type_name;
98
use std::sync::atomic::{AtomicU32, Ordering};
109

1110
#[cfg(not(feature = "experimental-threads"))]
@@ -15,7 +14,6 @@ use godot_cell::panicking::{GdCell, InaccessibleGuard, MutGuard, RefGuard};
1514
use godot_cell::blocking::{GdCell, InaccessibleGuard, MutGuard, RefGuard};
1615

1716
use crate::obj::{Base, GodotClass};
18-
use crate::out;
1917
use crate::storage::{AtomicLifecycle, Lifecycle, Storage, StorageRefCounted};
2018

2119
pub struct InstanceStorage<T: GodotClass> {
@@ -42,7 +40,8 @@ unsafe impl<T: GodotClass> Storage for InstanceStorage<T> {
4240
user_instance: Self::Instance,
4341
base: Base<<Self::Instance as GodotClass>::Base>,
4442
) -> Self {
45-
out!(" Storage::construct <{}>", type_name::<T>());
43+
super::log_construct::<T>();
44+
4645
Self {
4746
user_instance: GdCell::new(user_instance),
4847
base,
@@ -60,29 +59,15 @@ unsafe impl<T: GodotClass> Storage for InstanceStorage<T> {
6059
}
6160

6261
fn get(&self) -> RefGuard<'_, T> {
63-
self.user_instance.borrow().unwrap_or_else(|err| {
64-
panic!(
65-
"\
66-
Gd<T>::bind() failed, already bound; T = {}.\n \
67-
Make sure to use `self.base_mut()` or `self.base()` instead of `self.to_gd()` when possible.\n \
68-
Details: {err}.\
69-
",
70-
type_name::<T>()
71-
)
72-
})
62+
self.user_instance
63+
.borrow()
64+
.unwrap_or_else(|e| super::bind_failed::<T>(e))
7365
}
7466

7567
fn get_mut(&self) -> MutGuard<'_, T> {
76-
self.user_instance.borrow_mut().unwrap_or_else(|err| {
77-
panic!(
78-
"\
79-
Gd<T>::bind_mut() failed, already bound; T = {}.\n \
80-
Make sure to use `self.base_mut()` instead of `self.to_gd()` when possible.\n \
81-
Details: {err}.\
82-
",
83-
type_name::<T>()
84-
)
85-
})
68+
self.user_instance
69+
.borrow_mut()
70+
.unwrap_or_else(|e| super::bind_mut_failed::<T>(e))
8671
}
8772

8873
fn get_inaccessible<'a: 'b, 'b>(
@@ -91,18 +76,7 @@ unsafe impl<T: GodotClass> Storage for InstanceStorage<T> {
9176
) -> InaccessibleGuard<'b, T> {
9277
self.user_instance
9378
.make_inaccessible(value)
94-
.unwrap_or_else(|err| {
95-
// We should never hit this, except maybe in extreme cases like having more than
96-
// `usize::MAX` borrows.
97-
panic!(
98-
"\
99-
`base_mut()` failed for type T = {}.\n \
100-
This is most likely a bug, please report it.\n \
101-
Details: {err}.\
102-
",
103-
type_name::<T>()
104-
)
105-
})
79+
.unwrap_or_else(|e| super::bug_inaccessible::<T>(e))
10680
}
10781

10882
fn get_lifecycle(&self) -> Lifecycle {
@@ -121,29 +95,19 @@ impl<T: GodotClass> StorageRefCounted for InstanceStorage<T> {
12195

12296
fn on_inc_ref(&self) {
12397
self.godot_ref_count.fetch_add(1, Ordering::Relaxed);
124-
out!(
125-
" Storage::on_inc_ref (rc={}) <{:?}>",
126-
self.godot_ref_count(),
127-
self.base,
128-
);
98+
99+
super::log_inc_ref(self);
129100
}
130101

131102
fn on_dec_ref(&self) {
132103
self.godot_ref_count.fetch_sub(1, Ordering::Relaxed);
133-
out!(
134-
" | Storage::on_dec_ref (rc={}) <{:?}>",
135-
self.godot_ref_count(),
136-
self.base,
137-
);
104+
105+
super::log_dec_ref(self);
138106
}
139107
}
140108

141109
impl<T: GodotClass> Drop for InstanceStorage<T> {
142110
fn drop(&mut self) {
143-
out!(
144-
" Storage::drop (rc={}) <{:?}>",
145-
self.godot_ref_count(),
146-
self.base(),
147-
);
111+
super::log_drop(self);
148112
}
149113
}

godot-core/src/storage/single_threaded.rs

Lines changed: 17 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
66
*/
77

8-
use std::any::type_name;
98
use std::cell;
109

1110
#[cfg(not(feature = "experimental-threads"))]
@@ -15,7 +14,7 @@ use godot_cell::panicking::{GdCell, InaccessibleGuard, MutGuard, RefGuard};
1514
use godot_cell::blocking::{GdCell, InaccessibleGuard, MutGuard, RefGuard};
1615

1716
use crate::obj::{Base, GodotClass};
18-
use crate::out;
17+
use crate::storage::borrow_info::DebugBorrowTracker;
1918
use crate::storage::{Lifecycle, Storage, StorageRefCounted};
2019

2120
pub struct InstanceStorage<T: GodotClass> {
@@ -42,7 +41,8 @@ unsafe impl<T: GodotClass> Storage for InstanceStorage<T> {
4241
user_instance: Self::Instance,
4342
base: Base<<Self::Instance as GodotClass>::Base>,
4443
) -> Self {
45-
out!(" Storage::construct <{}>", type_name::<T>());
44+
super::log_construct::<T>();
45+
4646
Self {
4747
user_instance: GdCell::new(user_instance),
4848
base,
@@ -60,49 +60,24 @@ unsafe impl<T: GodotClass> Storage for InstanceStorage<T> {
6060
}
6161

6262
fn get(&self) -> RefGuard<'_, T> {
63-
self.user_instance.borrow().unwrap_or_else(|err| {
64-
panic!(
65-
"\
66-
Gd<T>::bind() failed, already bound; T = {}.\n \
67-
Make sure to use `self.base_mut()` or `self.base()` instead of `self.to_gd()` when possible.\n \
68-
Details: {err}.\
69-
",
70-
type_name::<T>()
71-
)
72-
})
63+
self.user_instance
64+
.borrow()
65+
.unwrap_or_else(|e| super::bind_failed::<T>(e))
7366
}
7467

7568
fn get_mut(&self) -> MutGuard<'_, T> {
76-
self.user_instance.borrow_mut().unwrap_or_else(|err| {
77-
panic!(
78-
"\
79-
Gd<T>::bind_mut() failed, already bound; T = {}.\n \
80-
Make sure to use `self.base_mut()` instead of `self.to_gd()` when possible.\n \
81-
Details: {err}.\
82-
",
83-
type_name::<T>()
84-
)
85-
})
69+
self.user_instance
70+
.borrow_mut()
71+
.unwrap_or_else(|e| super::bind_mut_failed::<T>(e))
8672
}
8773

88-
fn get_inaccessible<'a: 'b, 'b>(
89-
&'a self,
90-
value: &'b mut Self::Instance,
91-
) -> InaccessibleGuard<'b, T> {
74+
fn get_inaccessible<'stor: 'inst, 'inst>(
75+
&'stor self,
76+
value: &'inst mut Self::Instance,
77+
) -> InaccessibleGuard<'inst, T> {
9278
self.user_instance
9379
.make_inaccessible(value)
94-
.unwrap_or_else(|err| {
95-
// We should never hit this, except maybe in extreme cases like having more than
96-
// `usize::MAX` borrows.
97-
panic!(
98-
"\
99-
`base_mut()` failed for type T = {}.\n \
100-
This is most likely a bug, please report it.\n \
101-
Details: {err}.\
102-
",
103-
type_name::<T>()
104-
)
105-
})
80+
.unwrap_or_else(|e| super::bug_inaccessible::<T>(e))
10681
}
10782

10883
fn get_lifecycle(&self) -> Lifecycle {
@@ -123,33 +98,19 @@ impl<T: GodotClass> StorageRefCounted for InstanceStorage<T> {
12398
let refc = self.godot_ref_count.get() + 1;
12499
self.godot_ref_count.set(refc);
125100

126-
out!(
127-
" Storage::on_inc_ref (rc={}) <{}>", // -- {:?}",
128-
refc,
129-
type_name::<T>(),
130-
//self.user_instance
131-
);
101+
super::log_inc_ref(self);
132102
}
133103

134104
fn on_dec_ref(&self) {
135105
let refc = self.godot_ref_count.get() - 1;
136106
self.godot_ref_count.set(refc);
137107

138-
out!(
139-
" | Storage::on_dec_ref (rc={}) <{}>", // -- {:?}",
140-
refc,
141-
type_name::<T>(),
142-
//self.user_instance
143-
);
108+
super::log_dec_ref(self);
144109
}
145110
}
146111

147112
impl<T: GodotClass> Drop for InstanceStorage<T> {
148113
fn drop(&mut self) {
149-
out!(
150-
" Storage::drop (rc={}) <{:?}>",
151-
self.godot_ref_count(),
152-
self.base(),
153-
);
114+
super::log_drop(self);
154115
}
155116
}

0 commit comments

Comments
 (0)