Skip to content

Commit 4229ad5

Browse files
bors[bot]Bromeon
andauthored
Merge #223
223: Object notification API, `engine` intra-doc links r=Bromeon a=Bromeon So far, there was no way to intercept the Godot `_notification` API, and also issuing notifications was very cumbersome, as the constants were spread across several classes. This PR introduces multiple new APIs: 1. `{Class}Notification` enum, which contains all notifications relevant for a given class. * For example, `Node3DNotification` accumulates all `NOTIFICATION_*` constants across `Node3D`, `Node` and `Object` classes. * In GDScript, this is less of an issue because there is true inheritance, so one can type `Node3D.NOTIF...` and auto-complete will list all candidates. In Rust, constants are not inherited. * There is currently a workaround for bug [godot#75839](godotengine/godot#75839): in two cases, two enumerators cannot be distinguished as they share the same integer value. We address this by using a single enumerator to represent both (not ideal, but there's nothing else we can do). 2. Virtual method `{Class}Virtual::on_notification(what: {NearestClass}Notification)`. * This is the equivalent to GDScript's `_notification` (with underscore), but more meaningfully named. It can be used to intercept low-level notifications for the given class. * The parameter type is either the notification enum for that class; or if the class itself does not have any notification constants, the nearest base class that _does_. This avoids proliferation of enum types with the exact same interface. It's possibly breaking when Godot adds such constants in new classes, but it helps reduce the API surface if not _every single class_ needs its own enum (since there are relatively few classes working with notifications). 3. The method `{Class}::issue_notification(what: {NearestClass}Notification)`. * This is the counterpart of `on_notification` to _send_ notifications. * In GDScript, this is named `notification` (no underscore). --- Apart from that, there are smaller changes: * `Display` is now implemented on all `Gd<T>` types, by using the Godot string representation. `T`'s `Display` impl is ignored. * Several generated symbols in `godot::engine` are now slighly documented and contain intra-doc links to navigate easily: * Class <-> virtual trait * Class <-> notification enum * Class <-> sidecar module * Class -> Godot online docs * Modules `global`, `utilities` and `notify` Co-authored-by: Jan Haller <[email protected]>
2 parents 885bb91 + 04ffc0a commit 4229ad5

15 files changed

+608
-74
lines changed

godot-codegen/src/central_generator.rs

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ fn make_sys_code(central_items: &CentralItems) -> String {
136136
#(#opaque_types)*
137137
}
138138

139+
// ----------------------------------------------------------------------------------------------------------------------------------------------
140+
139141
pub struct GlobalMethodTable {
140142
#(#variant_fn_decls)*
141143
}
@@ -148,6 +150,8 @@ fn make_sys_code(central_items: &CentralItems) -> String {
148150
}
149151
}
150152

153+
// ----------------------------------------------------------------------------------------------------------------------------------------------
154+
151155
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
152156
#[repr(i32)]
153157
pub enum VariantType {
@@ -182,6 +186,8 @@ fn make_sys_code(central_items: &CentralItems) -> String {
182186
ffi_methods! { type GDExtensionTypePtr = *mut Self; .. }
183187
}
184188

189+
// ----------------------------------------------------------------------------------------------------------------------------------------------
190+
185191
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
186192
#[repr(i32)]
187193
pub enum VariantOperator {
@@ -256,6 +262,12 @@ fn make_core_code(central_items: &CentralItems) -> String {
256262
}
257263
}
258264

265+
/// Global enums and constants.
266+
///
267+
/// A list of global-scope enumerated constants.
268+
/// For global built-in functions, check out the [`utilities` module][crate::engine::utilities].
269+
///
270+
/// See also [Godot docs for `@GlobalScope`](https://docs.godotengine.org/en/stable/classes/[email protected]#enumerations).
259271
pub mod global {
260272
use crate::sys;
261273
#( #global_enum_defs )*
@@ -266,7 +278,7 @@ fn make_core_code(central_items: &CentralItems) -> String {
266278
}
267279

268280
fn make_central_items(api: &ExtensionApi, build_config: &str, ctx: &mut Context) -> CentralItems {
269-
let mut opaque_types = vec![];
281+
let mut opaque_types = Vec::new();
270282
for class in &api.builtin_class_sizes {
271283
if class.build_configuration == build_config {
272284
for ClassSize { name, size } in &class.sizes {
@@ -331,7 +343,7 @@ fn make_central_items(api: &ExtensionApi, build_config: &str, ctx: &mut Context)
331343

332344
result
333345
.variant_op_enumerators_pascal
334-
.push(ident(&shout_to_pascal(name)));
346+
.push(ident(&util::shout_to_pascal(name)));
335347
result
336348
.variant_op_enumerators_ord
337349
.push(Literal::i32_unsuffixed(op.value));
@@ -707,22 +719,3 @@ fn is_trivial(type_names: &TypeNames) -> bool {
707719

708720
list.contains(&type_names.json_builtin_name.as_str())
709721
}
710-
711-
fn shout_to_pascal(shout_case: &str) -> String {
712-
let mut result = String::with_capacity(shout_case.len());
713-
let mut next_upper = true;
714-
715-
for ch in shout_case.chars() {
716-
if next_upper {
717-
assert_ne!(ch, '_'); // no double underscore
718-
result.push(ch); // unchanged
719-
next_upper = false;
720-
} else if ch == '_' {
721-
next_upper = true;
722-
} else {
723-
result.push(ch.to_ascii_lowercase());
724-
}
725-
}
726-
727-
result
728-
}

0 commit comments

Comments
 (0)