Skip to content

Commit 1f7498f

Browse files
committed
Minor cleanup in virtual function special cases
Use Godot class names, make 4.4+ code more robust in case of future special cases.
1 parent adcb58d commit 1f7498f

File tree

2 files changed

+47
-28
lines changed

2 files changed

+47
-28
lines changed

godot-codegen/src/models/domain_mapping.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -487,20 +487,26 @@ impl ClassMethod {
487487

488488
// Since Godot 4.4, GDExtension advertises whether virtual methods have a default implementation or are required to be overridden.
489489
#[cfg(before_api = "4.4")]
490-
let is_virtual_required = special_cases::is_virtual_method_required(
491-
&class_name.rust_ty.to_string(),
492-
rust_method_name,
493-
);
490+
let is_virtual_required =
491+
special_cases::is_virtual_method_required(&class_name, rust_method_name);
494492

495493
#[cfg(since_api = "4.4")]
496-
let is_virtual_required = method.is_virtual
497-
&& method.is_required.unwrap_or_else(|| {
494+
#[allow(clippy::let_and_return)]
495+
let is_virtual_required = method.is_virtual && {
496+
// Evaluate this always first (before potential manual overrides), to detect mistakes in spec.
497+
let is_required_in_json = method.is_required.unwrap_or_else(|| {
498498
panic!(
499499
"virtual method {}::{} lacks field `is_required`",
500500
class_name.rust_ty, rust_method_name
501501
);
502502
});
503503

504+
// Potential special cases come here. The situation "virtual function is required in base class, but not in derived"
505+
// is not handled here, but in virtual_traits.rs. Here, virtual methods appear only once, in their base.
506+
507+
is_required_in_json
508+
};
509+
504510
Some(Self {
505511
common: FunctionCommon {
506512
name: rust_method_name.to_string(),

godot-codegen/src/special_cases/special_cases.rs

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -659,9 +659,11 @@ pub fn get_interface_extra_docs(trait_name: &str) -> Option<&'static str> {
659659
}
660660

661661
#[cfg(before_api = "4.4")]
662-
pub fn is_virtual_method_required(class_name: &str, method: &str) -> bool {
663-
match (class_name, method) {
664-
("ScriptLanguageExtension", _) => method != "get_doc_comment_delimiters",
662+
pub fn is_virtual_method_required(class_name: &TyName, rust_method_name: &str) -> bool {
663+
// Do not call is_derived_virtual_method_required() here; that is handled in virtual_traits.rs.
664+
665+
match (class_name.godot_ty.as_str(), rust_method_name) {
666+
("ScriptLanguageExtension", method) => method != "get_doc_comment_delimiters",
665667

666668
("ScriptExtension", "editor_can_reload_from_file")
667669
| ("ScriptExtension", "can_instantiate")
@@ -699,7 +701,7 @@ pub fn is_virtual_method_required(class_name: &str, method: &str) -> bool {
699701
| ("EditorExportPlugin", "customize_scene")
700702
| ("EditorExportPlugin", "get_customization_configuration_hash")
701703
| ("EditorExportPlugin", "get_name")
702-
| ("EditorVcsInterface", _)
704+
| ("EditorVCSInterface", _)
703705
| ("MovieWriter", _)
704706
| ("TextServerExtension", "has_feature")
705707
| ("TextServerExtension", "get_name")
@@ -805,23 +807,23 @@ pub fn is_virtual_method_required(class_name: &str, method: &str) -> bool {
805807
| ("PacketPeerExtension", "get_available_packet_count")
806808
| ("PacketPeerExtension", "get_max_packet_size")
807809
| ("StreamPeerExtension", "get_available_bytes")
808-
| ("WebRtcDataChannelExtension", "poll")
809-
| ("WebRtcDataChannelExtension", "close")
810-
| ("WebRtcDataChannelExtension", "set_write_mode")
811-
| ("WebRtcDataChannelExtension", "get_write_mode")
812-
| ("WebRtcDataChannelExtension", "was_string_packet")
813-
| ("WebRtcDataChannelExtension", "get_ready_state")
814-
| ("WebRtcDataChannelExtension", "get_label")
815-
| ("WebRtcDataChannelExtension", "is_ordered")
816-
| ("WebRtcDataChannelExtension", "get_id")
817-
| ("WebRtcDataChannelExtension", "get_max_packet_life_time")
818-
| ("WebRtcDataChannelExtension", "get_max_retransmits")
819-
| ("WebRtcDataChannelExtension", "get_protocol")
820-
| ("WebRtcDataChannelExtension", "is_negotiated")
821-
| ("WebRtcDataChannelExtension", "get_buffered_amount")
822-
| ("WebRtcDataChannelExtension", "get_available_packet_count")
823-
| ("WebRtcDataChannelExtension", "get_max_packet_size")
824-
| ("WebRtcPeerConnectionExtension", _)
810+
| ("WebRTCDataChannelExtension", "poll")
811+
| ("WebRTCDataChannelExtension", "close")
812+
| ("WebRTCDataChannelExtension", "set_write_mode")
813+
| ("WebRTCDataChannelExtension", "get_write_mode")
814+
| ("WebRTCDataChannelExtension", "was_string_packet")
815+
| ("WebRTCDataChannelExtension", "get_ready_state")
816+
| ("WebRTCDataChannelExtension", "get_label")
817+
| ("WebRTCDataChannelExtension", "is_ordered")
818+
| ("WebRTCDataChannelExtension", "get_id")
819+
| ("WebRTCDataChannelExtension", "get_max_packet_life_time")
820+
| ("WebRTCDataChannelExtension", "get_max_retransmits")
821+
| ("WebRTCDataChannelExtension", "get_protocol")
822+
| ("WebRTCDataChannelExtension", "is_negotiated")
823+
| ("WebRTCDataChannelExtension", "get_buffered_amount")
824+
| ("WebRTCDataChannelExtension", "get_available_packet_count")
825+
| ("WebRTCDataChannelExtension", "get_max_packet_size")
826+
| ("WebRTCPeerConnectionExtension", _)
825827
| ("MultiplayerPeerExtension", "get_available_packet_count")
826828
| ("MultiplayerPeerExtension", "get_max_packet_size")
827829
| ("MultiplayerPeerExtension", "set_transfer_channel")
@@ -839,7 +841,18 @@ pub fn is_virtual_method_required(class_name: &str, method: &str) -> bool {
839841
| ("MultiplayerPeerExtension", "get_unique_id")
840842
| ("MultiplayerPeerExtension", "get_connection_status") => true,
841843

842-
(_, _) => false,
844+
_ => false,
845+
}
846+
}
847+
848+
// Adjustments for Godot 4.4+, where a virtual method is no longer needed (e.g. in a derived class).
849+
#[rustfmt::skip]
850+
pub fn is_derived_virtual_method_required(class_name: &TyName, rust_method_name: &str) -> Option<bool> {
851+
match (class_name.godot_ty.as_str(), rust_method_name) {
852+
// Required in base class, no longer in derived; https://github.com/godot-rust/gdext/issues/1133.
853+
| ("AudioStreamPlaybackResampled", "mix")
854+
855+
=> Some(false), _ => None
843856
}
844857
}
845858

0 commit comments

Comments
 (0)