Skip to content

Commit 416f477

Browse files
Merge branch 'master' into plb/gstring-concatenation
2 parents 2e08d6e + 4a6f803 commit 416f477

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+2810
-1177
lines changed

.github/composite/godot-install/action.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,17 @@ runs:
4141
env:
4242
ARTIFACT_NAME: ${{ inputs.artifact-name }}
4343
# if: steps.cache-godot.outputs.cache-hit != 'true'
44-
# If a specific Godot revision should be used, rather than latest, use this:
45-
# curl https://nightly.link/Bromeon/godot4-nightly/actions/runs/4910907653/${{ inputs.artifact-name }}.zip \
4644
run: |
4745
if [[ $ARTIFACT_NAME == *"nightly"* ]]; then
4846
url="https://nightly.link/Bromeon/godot4-nightly/workflows/compile-godot-nightly/master/$ARTIFACT_NAME.zip"
47+
# If a specific Godot revision should be used, rather than latest, use this:
48+
# url="https://nightly.link/Bromeon/godot4-nightly/actions/runs/<WORKFLOW_RUN_ID>/$ARTIFACT_NAME.zip"
4949
else
5050
url="https://nightly.link/Bromeon/godot4-nightly/workflows/compile-godot-stable/master/$ARTIFACT_NAME.zip"
5151
fi
5252
5353
curl "$url" -Lo artifact.zip --retry 3
54-
unzip artifact.zip -d $RUNNER_DIR/godot_bin
54+
unzip -q artifact.zip -d $RUNNER_DIR/godot_bin
5555
shell: bash
5656

5757
- name: "Prepare Godot executable"

.github/workflows/full-ci.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ jobs:
104104

105105
# Note: could use `-- --no-deps` to not lint dependencies, however it doesn't really speed up and also skips deps in workspace.
106106
- name: "Check clippy"
107-
# TODO(Rust 1.86): remove -A clippy::precedence; see https://github.com/godot-rust/gdext/pull/1055.
108107
run: |
109108
cargo clippy --all-targets $CLIPPY_FEATURES -- \
110109
-D clippy::suspicious \
@@ -114,8 +113,7 @@ jobs:
114113
-D clippy::dbg_macro \
115114
-D clippy::todo \
116115
-D clippy::unimplemented \
117-
-D warnings \
118-
-A clippy::precedence
116+
-D warnings
119117
120118
unit-test:
121119
name: unit-test (${{ matrix.name }}${{ matrix.rust-special }})

.github/workflows/minimal-ci.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ jobs:
9696
components: clippy
9797

9898
- name: "Check clippy"
99-
# TODO(Rust 1.86): remove -A clippy::precedence; see https://github.com/godot-rust/gdext/pull/1055.
10099
run: |
101100
cargo clippy --all-targets $CLIPPY_FEATURES -- \
102101
-D clippy::suspicious \
@@ -106,8 +105,7 @@ jobs:
106105
-D clippy::dbg_macro \
107106
-D clippy::todo \
108107
-D clippy::unimplemented \
109-
-D warnings \
110-
-A clippy::precedence
108+
-D warnings
111109
112110
113111
unit-test:
@@ -169,6 +167,15 @@ jobs:
169167
godot-binary: godot.linuxbsd.editor.dev.x86_64
170168
rust-extra-args: --features itest/experimental-threads,itest/codegen-full-experimental,godot/api-custom,godot/serde,itest/register-docs
171169

170+
- name: linux-release
171+
os: ubuntu-22.04
172+
artifact-name: linux-release-nightly
173+
godot-binary: godot.linuxbsd.template_release.x86_64
174+
# Use `codegen-full-experimental` to make sure that all function tables can be loaded in Godot release builds.
175+
# If the experimental part causes problems, downgrade to `codegen-full`.
176+
rust-extra-args: --release --features itest/codegen-full-experimental
177+
rust-cache-key: release
178+
172179
# Linux compat
173180

174181
- name: linux-4.4

.github/workflows/release-version.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,7 @@ jobs:
133133
-D clippy::dbg_macro \
134134
-D clippy::todo \
135135
-D clippy::unimplemented \
136-
-D warnings \
137-
-A clippy::precedence
136+
-D warnings
138137
139138
rustfmt:
140139
runs-on: ubuntu-latest

Cargo.toml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,41 @@ members = [
1515
"itest/hot-reload/rust",
1616
]
1717

18+
# All dependencies except own crates of this project should be specified here, independently of whether they're dev, build or
19+
# regular dependencies. Sort alphabetically within each section; comments about a dependency come on the section header.
20+
[workspace.dependencies]
21+
# Related to godot-rust.
22+
gdextension-api = { version = "0.2.2", git = "https://github.com/godot-rust/godot4-prebuilt", branch = "releases" }
23+
24+
# Main library features.
25+
glam = { version = "0.30", features = ["debug-glam-assert"] }
26+
serde = { version = "1", features = ["derive"] }
27+
serde_json = "1"
28+
29+
# Related to tooling/build setup.
30+
# * regex: not used for unicode parsing -> features unicode-bool + unicode-gencat are enabled instead of unicode-perl.
31+
# 'unicode-gencat' needed for \d, see https://docs.rs/regex/latest/regex/#unicode-features.
32+
bindgen = { version = "0.71", default-features = false, features = ["runtime"] }
33+
libc = "0.2.172"
34+
regex = { version = "1.11", default-features = false, features = ["std", "unicode-bool", "unicode-gencat"] }
35+
which = "7"
36+
37+
# Macros and codegen. Minimal versions compatible with -Zminimal-versions.
38+
# * proc_macro2: Literal::c_string() added in 1.0.80.
39+
# * quote: 1.0.37 allows tokenizing CStr.
40+
# * venial: 0.6.1 contains some bugfixes.
41+
heck = "0.5"
42+
litrs = "0.4"
43+
markdown = "=1.0.0-alpha.23"
44+
nanoserde = "0.2"
45+
proc-macro2 = "1.0.80"
46+
quote = "1.0.37"
47+
venial = "0.6.1"
48+
49+
# Testing (godot-cell, itest).
50+
proptest = "1.6.0"
51+
pin-project-lite = { version = "0.2" }
52+
1853
# Note about Jetbrains IDEs: "IDE Sync" (Refresh Cargo projects) may cause static analysis errors such as
1954
# "at most one `api-*` feature can be enabled". This is because by default, all Cargo features are enabled,
2055
# which isn't a setup we support. To address this, individual features can be enabled in the various

check.sh

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,6 @@ function cmd_fmt() {
146146
}
147147

148148
function cmd_clippy() {
149-
# TODO(Rust 1.86): remove `-A clippy::precedence`.
150-
# In Rust 1.85, `clippy::precedence` includes bitmasking and shift operations. Rigid adherence to this rule results in more noisy code, with
151-
# little benefits (being aware of bit operator precedence is something we can expect + bit manipulations are common in Godot).
152-
# This behavior will be reverted in 1.86 and moved into new lint `precedence_bits` included in `restriction` category.
153-
# See https://github.com/godot-rust/gdext/pull/1055 and https://github.com/rust-lang/rust-clippy/pull/14115.
154-
155149
run cargo clippy --all-targets "${extraCargoArgs[@]}" -- \
156150
-D clippy::suspicious \
157151
-D clippy::style \
@@ -160,13 +154,10 @@ function cmd_clippy() {
160154
-D clippy::dbg_macro \
161155
-D clippy::todo \
162156
-D clippy::unimplemented \
163-
-D warnings \
164-
-A clippy::precedence
157+
-D warnings
165158
}
166159

167160
function cmd_klippy() {
168-
# TODO(Rust 1.86): remove `-A clippy::precedence`.
169-
170161
run cargo clippy --fix --all-targets "${extraCargoArgs[@]}" -- \
171162
-D clippy::suspicious \
172163
-D clippy::style \
@@ -175,8 +166,7 @@ function cmd_klippy() {
175166
-D clippy::dbg_macro \
176167
-D clippy::todo \
177168
-D clippy::unimplemented \
178-
-D warnings \
179-
-A clippy::precedence
169+
-D warnings
180170
}
181171

182172
function cmd_test() {

godot-bindings/Cargo.toml

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,15 @@ api-custom = ["dep:bindgen", "dep:regex", "dep:which"]
3737
api-custom-extheader = []
3838

3939
[dependencies]
40-
gdextension-api = { version = "0.2.2", git = "https://github.com/godot-rust/godot4-prebuilt", branch = "releases" }
40+
gdextension-api = { workspace = true }
4141

42-
# Do not use bindgen 0.69, it contains regression that forces recompilation of code.
43-
bindgen = { optional = true, version = "0.68", default-features = false, features = ["runtime"] }
44-
# regex >= 1.5.5 for security: https://blog.rust-lang.org/2022/03/08/cve-2022-24713.html
45-
# 'unicode-gencat' needed for \d, see: https://docs.rs/regex/1.5.5/regex/#unicode-features
46-
regex = { optional = true, version = "1.5.5", default-features = false, features = ["std", "unicode-gencat"] }
47-
which = { optional = true, version = "6" }
42+
bindgen = { workspace = true, optional = true }
43+
regex = { workspace = true, optional = true }
44+
which = { workspace = true, optional = true }
4845

4946
[dev-dependencies]
50-
# For tests, we need regex unconditionally. Keep this in sync with above dependency.
51-
regex = { version = "1.5.5", default-features = false, features = ["std", "unicode-gencat"] }
47+
# For tests, we need regex unconditionally.
48+
regex = { workspace = true }
5249

5350
# https://docs.rs/about/metadata
5451
[package.metadata.docs.rs]

godot-bindings/src/header_gen.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,21 @@ use std::path::Path;
1111
pub(crate) fn generate_rust_binding(in_h_path: &Path, out_rs_path: &Path) {
1212
let c_header_path = in_h_path.display().to_string();
1313

14-
// Listening to changes on files that are generated by this build step cause an infinite loop with cargo watch of
15-
// build -> detect change -> rebuild -> detect change -> ...
14+
// Default behavior of bindgen is to invalidate the built crate whenever any of the included header files changed. This is sensible,
15+
// but in our case, listening to changes on files that are generated by this build step cause an infinite loop with cargo watch of:
16+
// build -> detect change -> rebuild -> detect change -> ...
1617
// println!("cargo:rerun-if-changed={}", c_header_path);
18+
//
19+
// Without `rerun_on_header_files(false)`, the following command causes repeated recompilation of godot-ffi onward:
20+
// cargo build -p itest --features godot/api-custom
21+
//
22+
// This is non-trivial to fix and isn't planned at the moment, see https://github.com/godot-rust/gdext/issues/281.
23+
// If you have an idea to address this without too invasive changes, please comment on that issue.
24+
let cargo_cfg = bindgen::CargoCallbacks::new().rerun_on_header_files(false);
1725

1826
let builder = bindgen::Builder::default()
1927
.header(c_header_path)
20-
// Tell cargo to invalidate the built crate whenever any of the
21-
// included header files changed.
22-
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
28+
.parse_callbacks(Box::new(cargo_cfg))
2329
.prepend_enum_name(false);
2430

2531
std::fs::create_dir_all(

godot-bindings/src/import.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ pub use gdextension_api::version_4_4 as prebuilt;
8383
feature = "api-custom",
8484
)))]
8585
// ]]
86-
8786
// [version-sync] [[
8887
// [include] current.minor
8988
// [line] pub use gdextension_api::version_$snakeVersion as prebuilt;

godot-cell/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ homepage = "https://godot-rust.github.io"
1414
proptest = ["dep:proptest"]
1515

1616
[dependencies]
17-
proptest = { version = "1.4.0", optional = true }
17+
proptest = { workspace = true, optional = true }
1818

1919
# https://docs.rs/about/metadata
2020
[package.metadata.docs.rs]

godot-codegen/Cargo.toml

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,11 @@ experimental-threads = []
2323
[dependencies]
2424
godot-bindings = { path = "../godot-bindings", version = "=0.2.4" }
2525

26-
heck = "0.5"
27-
nanoserde = "0.1.35"
28-
29-
# Minimum versions compatible with -Zminimal-versions
30-
proc-macro2 = "1.0.80" # Literal::c_string() added in 1.0.80.
31-
quote = "1.0.29"
32-
33-
# Since we don't use Regex for unicode parsing, the features unicode-bool/unicode-gencat are used instead of unicode-perl.
34-
# See also https://docs.rs/regex/latest/regex/#unicode-features.
35-
regex = { version = "1.5.5", default-features = false, features = ["std", "unicode-bool", "unicode-gencat"] }
26+
heck = { workspace = true }
27+
nanoserde = { workspace = true }
28+
proc-macro2 = { workspace = true }
29+
quote = { workspace = true }
30+
regex = { workspace = true }
3631

3732
[build-dependencies]
3833
godot-bindings = { path = "../godot-bindings", version = "=0.2.4" } # emit_godot_version_cfg

godot-codegen/src/context.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub struct Context<'a> {
2525
inheritance_tree: InheritanceTree,
2626
cached_rust_types: HashMap<GodotTy, RustTy>,
2727
notifications_by_class: HashMap<TyName, Vec<(Ident, i32)>>,
28+
classes_with_signals: HashSet<TyName>,
2829
notification_enum_names_by_class: HashMap<TyName, NotificationEnum>,
2930
method_table_indices: HashMap<MethodTableKey, usize>,
3031
method_table_next_index: HashMap<String, usize>,
@@ -66,6 +67,10 @@ impl<'a> Context<'a> {
6667
// Populate class lookup by name
6768
engine_classes.insert(class_name.clone(), class);
6869

70+
if !option_as_slice(&class.signals).is_empty() {
71+
ctx.classes_with_signals.insert(class_name.clone());
72+
}
73+
6974
// Populate derived-to-base relations
7075
if let Some(base) = class.inherits.as_ref() {
7176
let base_name = TyName::from_godot(base);
@@ -278,6 +283,24 @@ impl<'a> Context<'a> {
278283
self.cached_rust_types.get(ty)
279284
}
280285

286+
/// Walks up in the hierarchy, and returns the first (nearest) base class which declares at least 1 signal.
287+
///
288+
/// Always returns a result, as `Object` (the root) itself declares signals.
289+
pub fn find_nearest_base_with_signals(&self, class_name: &TyName) -> TyName {
290+
let tree = self.inheritance_tree();
291+
292+
let mut class = class_name.clone();
293+
while let Some(base) = tree.direct_base(&class) {
294+
if self.classes_with_signals.contains(&base) {
295+
return base;
296+
} else {
297+
class = base;
298+
}
299+
}
300+
301+
panic!("Object (root) should always have signals")
302+
}
303+
281304
pub fn notification_constants(&'a self, class_name: &TyName) -> Option<&'a Vec<(Ident, i32)>> {
282305
self.notifications_by_class.get(class_name)
283306
}

godot-codegen/src/generator/builtins.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,8 @@ fn make_builtin_method_definition(
253253
let ptrcall_invocation = quote! {
254254
let method_bind = sys::builtin_method_table().#fptr_access;
255255

256-
<CallSig as PtrcallSignatureTuple>::out_builtin_ptrcall(
256+
257+
Signature::<CallParams, CallRet>::out_builtin_ptrcall(
257258
method_bind,
258259
#builtin_name_str,
259260
#method_name_str,
@@ -265,7 +266,7 @@ fn make_builtin_method_definition(
265266
let varcall_invocation = quote! {
266267
let method_bind = sys::builtin_method_table().#fptr_access;
267268

268-
<CallSig as VarcallSignatureTuple>::out_builtin_ptrcall_varargs(
269+
Signature::<CallParams, CallRet>::out_builtin_ptrcall_varargs(
269270
method_bind,
270271
#builtin_name_str,
271272
#method_name_str,

godot-codegen/src/generator/classes.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,10 @@ fn make_class(class: &Class, ctx: &mut Context, view: &ApiView) -> GeneratedClas
123123
builders,
124124
} = make_class_methods(class, &class.methods, &cfg_attributes, ctx);
125125

126-
let signal_types = signals::make_class_signals(class, &class.signals, ctx);
126+
let signals::SignalCodegen {
127+
signal_code,
128+
has_own_signals,
129+
} = signals::make_class_signals(class, &class.signals, ctx);
127130

128131
let enums = enums::make_enums(&class.enums, &cfg_attributes);
129132
let constants = constants::make_constants(&class.constants);
@@ -137,14 +140,14 @@ fn make_class(class: &Class, ctx: &mut Context, view: &ApiView) -> GeneratedClas
137140
// Associated "sidecar" module is made public if there are other symbols related to the class, which are not
138141
// in top-level godot::classes module (notification enums are not in the sidecar, but in godot::classes::notify).
139142
// This checks if token streams (i.e. code) is empty.
140-
let has_sidecar_module = !enums.is_empty() || !builders.is_empty() || signal_types.is_some();
143+
let has_sidecar_module = !enums.is_empty() || !builders.is_empty() || has_own_signals;
141144

142145
let class_doc = docs::make_class_doc(
143146
class_name,
144147
base_ident_opt,
145148
notification_enum.is_some(),
146149
has_sidecar_module,
147-
signal_types.is_some(),
150+
has_own_signals,
148151
);
149152

150153
let module_doc = docs::make_module_doc(class_name);
@@ -262,7 +265,7 @@ fn make_class(class: &Class, ctx: &mut Context, view: &ApiView) -> GeneratedClas
262265

263266
#builders
264267
#enums
265-
#signal_types
268+
#signal_code
266269
};
267270
// note: TypePtr -> ObjectPtr conversion OK?
268271

@@ -512,7 +515,7 @@ fn make_class_method_definition(
512515
let ptrcall_invocation = quote! {
513516
let method_bind = sys::#get_method_table().#fptr_access;
514517

515-
<CallSig as PtrcallSignatureTuple>::out_class_ptrcall(
518+
Signature::<CallParams, CallRet>::out_class_ptrcall(
516519
method_bind,
517520
#rust_class_name,
518521
#rust_method_name,
@@ -525,7 +528,7 @@ fn make_class_method_definition(
525528
let varcall_invocation = quote! {
526529
let method_bind = sys::#get_method_table().#fptr_access;
527530

528-
<CallSig as VarcallSignatureTuple>::out_class_varcall(
531+
Signature::<CallParams, CallRet>::out_class_varcall(
529532
method_bind,
530533
#rust_class_name,
531534
#rust_method_name,

godot-codegen/src/generator/functions_common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,9 @@ pub fn make_function_definition(
177177
let call_sig_decl = {
178178
let return_ty = &sig.return_value().type_tokens();
179179

180-
// Build <'a0, 'a1, ...> for lifetimes.
181180
quote! {
182-
type CallSig #callsig_lifetime_args = ( #return_ty, #(#param_types),* );
181+
type CallRet = #return_ty;
182+
type CallParams #callsig_lifetime_args = (#(#param_types,)*);
183183
}
184184
};
185185

0 commit comments

Comments
 (0)