Skip to content

Commit cd652b7

Browse files
authored
Merge pull request #593 from godot-rust/feature/no-init
`#[class(no_init)]` to explicitly disable constructor
2 parents b4a91a6 + d0e99a4 commit cd652b7

File tree

16 files changed

+285
-160
lines changed

16 files changed

+285
-160
lines changed

godot-core/src/lib.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -186,21 +186,20 @@ pub mod private {
186186
// https://github.com/rust-lang/rust/pull/58994. Fortunately, an extra layer of indirection solves most problems: we generate a declarative
187187
// macro that itself isn't deprecated, but _its_ expansion is. Since the expansion happens in a later step, the warning is emitted.
188188

189-
#[doc(hidden)]
190189
#[inline(always)]
191190
#[deprecated = "#[base] is no longer needed; Base<T> is recognized directly. \n\
192191
More information on https://github.com/godot-rust/gdext/pull/577."]
193-
pub const fn base_attribute_warning() {}
192+
pub const fn base_attribute() {}
194193

195194
#[doc(hidden)]
196195
#[macro_export]
197-
macro_rules! __base_attribute_warning_expand {
198-
() => {
199-
const _: () = $crate::private::base_attribute_warning();
196+
macro_rules! __emit_deprecated_warning {
197+
($warning_fn:ident) => {
198+
const _: () = $crate::private::$warning_fn();
200199
};
201200
}
202201

203-
pub use crate::__base_attribute_warning_expand;
202+
pub use crate::__emit_deprecated_warning;
204203
}
205204

206205
macro_rules! generate_gdextension_api_version {

godot-core/src/registry.rs

+14
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ pub enum PluginItem {
102102

103103
/// Whether `#[class(hidden)]` was used.
104104
is_hidden: bool,
105+
106+
/// Whether the class has a default constructor.
107+
is_instantiable: bool,
105108
},
106109

107110
/// Collected from `#[godot_api] impl MyClass`.
@@ -377,9 +380,20 @@ fn fill_class_info(item: PluginItem, c: &mut ClassRegistrationInfo) {
377380
default_get_virtual_fn,
378381
is_editor_plugin,
379382
is_hidden,
383+
is_instantiable,
380384
} => {
381385
c.parent_class_name = Some(base_class_name);
382386

387+
// Classes marked #[class(no_init)] are translated to "abstract" in Godot. This disables their default constructor.
388+
// "Abstract" is a misnomer -- it's not an abstract base class, but rather a "utility/static class" (although it can have instance
389+
// methods). Examples are Input, IP, FileAccess, DisplayServer.
390+
//
391+
// Abstract base classes on the other hand are called "virtual" in Godot. Examples are Mesh, Material, Texture.
392+
// For some reason, certain ABCs like PhysicsBody2D are not marked "virtual" but "abstract".
393+
//
394+
// See also: https://github.com/godotengine/godot/pull/58972
395+
c.godot_params.is_abstract = (!is_instantiable) as sys::GDExtensionBool;
396+
383397
fill_into(
384398
&mut c.godot_params.create_instance_func,
385399
generated_create_fn,

0 commit comments

Comments
 (0)