Skip to content

Commit 5b65c25

Browse files
committed
Virtual methods are no longer required if a derived Godot class implements them
1 parent 531f122 commit 5b65c25

File tree

1 file changed

+14
-4
lines changed

1 file changed

+14
-4
lines changed

godot-codegen/src/generator/virtual_traits.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::generator::{docs, functions_common};
1010
use crate::models::domain::{
1111
ApiView, Class, ClassLike, ClassMethod, FnQualifier, Function, TyName,
1212
};
13+
use crate::special_cases;
1314
use crate::util::ident;
1415
use proc_macro2::{Ident, TokenStream};
1516
use quote::quote;
@@ -150,7 +151,10 @@ fn make_special_virtual_methods(notification_enum_name: &Ident) -> TokenStream {
150151
}
151152
}
152153

153-
fn make_virtual_method(method: &ClassMethod) -> Option<TokenStream> {
154+
fn make_virtual_method(
155+
method: &ClassMethod,
156+
override_is_required: Option<bool>,
157+
) -> Option<TokenStream> {
154158
if !method.is_virtual() {
155159
return None;
156160
}
@@ -166,7 +170,8 @@ fn make_virtual_method(method: &ClassMethod) -> Option<TokenStream> {
166170
// make_return() requests following args, but they are not used for virtual methods. We can provide empty streams.
167171
varcall_invocation: TokenStream::new(),
168172
ptrcall_invocation: TokenStream::new(),
169-
is_virtual_required: method.is_virtual_required(),
173+
is_virtual_required: override_is_required
174+
.unwrap_or_else(|| method.is_virtual_required()),
170175
is_varcall_fallible: true,
171176
},
172177
None,
@@ -186,15 +191,20 @@ fn make_all_virtual_methods(
186191

187192
for method in class.methods.iter() {
188193
// Assumes that inner function filters on is_virtual.
189-
if let Some(tokens) = make_virtual_method(method) {
194+
if let Some(tokens) = make_virtual_method(method, None) {
190195
all_tokens.push(tokens);
191196
}
192197
}
193198

194199
for base_name in all_base_names {
195200
let base_class = view.get_engine_class(base_name);
196201
for method in base_class.methods.iter() {
197-
if let Some(tokens) = make_virtual_method(method) {
202+
// Certain derived classes in Godot implement a virtual method declared in a base class, thus no longer
203+
// making it required. This isn't advertised in the extension_api, but instead manually tracked via special cases.
204+
let is_required =
205+
special_cases::is_derived_virtual_method_required(class.name(), method.name());
206+
207+
if let Some(tokens) = make_virtual_method(method, is_required) {
198208
all_tokens.push(tokens);
199209
}
200210
}

0 commit comments

Comments
 (0)