Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace euclid with glam (proof-of-concept) #713

Merged
merged 2 commits into from Mar 30, 2021
Merged

Conversation

Demindiro
Copy link
Contributor

@Demindiro Demindiro commented Mar 18, 2021

I had some time to take a look at #594. I decided to go with glam since it compiles the fastest.

I went with the "front-end" approach as I believe that is the most flexible approach.

I did rename a few things (like zero() to ZERO, quaternion() to new(), ...) but that is easy to revert if required.

It doesn't seem like many changes are required. Wrapping all the methods in glam is easy to do with extensive use of glam() and into(). The crate does seem to miss implementations for a few types and methods like Rect2 and rotated, so we'll have to implement those from scratch.

the impl Mul/Div/Add/...s for Vector2 and Vector3 are pretty much identical, maybe there is some way to reduce duplication?

Closes #594
Closes #670 (Vector3 is fully implemented)

Copy link
Member

@Bromeon Bromeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the PR!

I haven't had a chance to look at everything yet, but I already left some remarks. Also some files are indented with Tab instead of Spaces (which is The Right Way ™️ but unfortunately not what godot-rust uses 😬). You might want to use cargo fmt.

Regarding glam vs. other vector libraries: since they become an implementation detail, I'm fine with starting with glam without very deep API comparison. If necessary, we can always change the back-end later without breaking the API.

examples/scene_create/Cargo.toml Outdated Show resolved Hide resolved
gdnative-core/src/core_types/quat.rs Outdated Show resolved Hide resolved
gdnative-core/src/core_types/mod.rs Outdated Show resolved Hide resolved
@@ -22,6 +25,9 @@ pub mod vector2;
pub mod vector2_array;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is more a comment towards @toasteater and the dev team, not specific to this PR:

Do we export both the inner module and core_types? In my opinion, it could make sense to keep these mod declarations private, and just the pub mod re-export public.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see also #713 (comment)

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some additional comments about the API.

gdnative-core/src/core_types/geom/transform.rs Outdated Show resolved Hide resolved
gdnative-core/src/core_types/mod.rs Outdated Show resolved Hide resolved
Comment on lines 17 to 22
pub mod quat;
pub mod rect2;
pub mod rid;
pub mod string;
pub mod string_array;
pub mod transform2d;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think they need to be public modules since they only contain single types that are re-exported.

gdnative-core/src/core_types/vector3.rs Outdated Show resolved Hide resolved
gdnative-core/src/core_types/quat.rs Outdated Show resolved Hide resolved
Copy link
Member

@Bromeon Bromeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the changes, looks really good meanwhile! 🙂

One thing we should still discuss: before we had a dedicated Angle type, now the functions just expose f32. Would it make sense to keep that for type safety (at a cost of verbosity) or not?

If we decide to have our own Angle, let's move it to a separate PR, so we can also discuss the API and so on.

pub mod variant;
pub mod variant_array;
pub mod vector2;
pub mod vector2_array;
pub mod vector3;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mentioned the bindings depend on this one to be public?
Could you tell us the error you got, then we can make a note to fix it later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exact error is:

error[E0433]: failed to resolve: use of undeclared crate or module `vector3`
   --> /home/david/Documents/godot/rust/target/debug/build/gdnative-bindings-bf0499e791931b11/out/generated.rs:460:3858
    |
460 | ...= ""] # [inline] pub fn axis (& self) -> vector3 :: Axis { unsafe { let method_bind : * mut sys :: godot_method_bind = SpriteBase3DMet...
    |                                             ^^^^^^^ use of undeclared crate or module `vector3`

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently the tests depend on them being technically public too: https://github.com/godot-rust/godot-rust/runs/2172242242

Maybe we want to keep them public for now and look for a solution later?

gdnative-core/src/core_types/vector2.rs Outdated Show resolved Hide resolved
gdnative-core/src/core_types/vector2.rs Outdated Show resolved Hide resolved
gdnative-core/src/core_types/vector2.rs Outdated Show resolved Hide resolved
gdnative-core/src/core_types/vector2.rs Outdated Show resolved Hide resolved
gdnative-core/src/core_types/vector3.rs Show resolved Hide resolved
}
}

macro_rules! derive_op_impl {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@toasteater would it make sense to extract these macros to their own private file vector_ops.rs and parametrize them over the vector type Vector2/Vector3?

Could avoid some code duplication and would keep the vector files cleaner.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense, but I think it's ok to merge this as is for now and do on that later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK for me 👍🏼

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is looking nice now! Please let us know when it's ready for a final review.

bors try

bors bot added a commit that referenced this pull request Mar 23, 2021
@bors
Copy link
Contributor

bors bot commented Mar 23, 2021

try

Build failed:

@Demindiro
Copy link
Contributor Author

I'll try to fix the tests this evening and then it should be ready.

@Bromeon
Copy link
Member

Bromeon commented Mar 23, 2021

by @Bromeon:
One thing we should still discuss: before we had a dedicated Angle type, now the functions just expose f32. Would it make sense to keep that for type safety (at a cost of verbosity) or not?

If we decide to have our own Angle, let's move it to a separate PR, so we can also discuss the API and so on.

@toasteater Let's discuss that in a separate issue then, to keep the scope of this PR limited?

@ghost ghost mentioned this pull request Mar 23, 2021
@ghost
Copy link

ghost commented Mar 23, 2021

@Bromeon I agree. Issue created: #716

@Demindiro Demindiro marked this pull request as ready for review March 23, 2021 20:50
@Demindiro
Copy link
Contributor Author

The tests will still fail due to mentioned ICE and is_equal_approx seemingly being stricter (or perhaps it has something to do with glam implementing things differently? Switching to Vec3 doesn't seem to change anything though).

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remember to run cargo fmt, cargo clippy, and the test suite before pushing.

Regarding approx strictness, you can pass custom epsilons to the macros: relative_eq!(a, b, epsilon = 0.0001). We may or may not want that to be a parameter on is_equal_approx, but I suppose probably yes?

/// Returns the axis of the vector's largest value. See `Axis` enum.
/// If all components are equal, this method returns `Axis::X`.
#[inline]
#[allow(clippy::collapsible-if)]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

collapsible_if. Also this is a tab: run cargo fmt before pushing. May I ask why did you ignore instead of use the lint suggestion?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ignore it because I believe the current version is more readable than the collapsed version.

if self.z > self.y {
    if self.z > self.x {
        Axis::Z
    } else {
        Axis::X
    }
} else {
    if self.y > self.x {
        Axis::Y
    } else {
        Axis::X
    }
}

vs

if self.z > self.y {
    if self.z > self.x {
        Axis::Z
    } else {
        Axis::X
    }
} else if self.y > self.x {
    Axis::Y
} else {
    Axis::X
}

/// Returns the axis of the vector's smallest value. See `Axis` enum.
/// If all components are equal, this method returns `Axis::Z`.
#[inline]
#[allow(clippy::collapsible-if)]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as before.

gdnative-core/src/core_types/vector3.rs Show resolved Hide resolved
gdnative-core/src/core_types/vector3.rs Outdated Show resolved Hide resolved
@ghost
Copy link

ghost commented Mar 24, 2021

As far as I can tell everything is functional (the examples work). The derive tests do fail though due to hardcoded output for one test and an ICE for a couple others.

I did not see any ICEs. Which version of rustc are you using?

@Demindiro
Copy link
Contributor Author

Demindiro commented Mar 24, 2021

I did not see any ICEs. Which version of rustc are you using?

I was using rustc 1.51.0-nightly (04caa632d 2021-01-30), but rustc 1.53.0-nightly (673d0db5e 2021-03-23) seems to have fixed the issue.

I also reran the tests and they fail again due to very slightly differing output. Should I update the tests or keep it as it is? (the tests do pass when running cargo test +stable)

EXPECTED:
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error: unknown argument, expected one of:
    to_variant_with, from_variant_with, with, skip_to_variant, skip_from_variant, skip
 --> $DIR/from_variant_fail_07.rs:5:15
  |
5 |     #[variant(aoeu = "aoeu")]
  |               ^^^^
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

ACTUAL OUTPUT:
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error: unknown argument, expected one of:
to_variant_with, from_variant_with, with, skip_to_variant, skip_from_variant, skip
 --> $DIR/from_variant_fail_07.rs:5:15
  |
5 |     #[variant(aoeu = "aoeu")]
  |               ^^^^
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

@ghost
Copy link

ghost commented Mar 24, 2021

@Demindiro Keep them as-is. UI tests should always use stable as a reference, never nightly.

@ghost
Copy link

ghost commented Mar 28, 2021

While there are certainly things that are still debatable, like the placement of the internal trait, I feel that this PR has gone through enough, and further detailed things can be taken care of in additional follow-up PRs instead.

@Demindiro When you think that this PR is ready, please remove any dbg! macros and commented code, and ping one of us for merging! Please remember to run cargo fmt, cargo clippy, and the test suite before pushing to avoid problems with CI. We use bors to ensure that CI always passes on the master branch. We're unable to merge a PR that doesn't pass CI.

bors try

bors bot added a commit that referenced this pull request Mar 28, 2021
@bors
Copy link
Contributor

bors bot commented Mar 28, 2021

try

Build failed:

@Bromeon
Copy link
Member

Bromeon commented Mar 28, 2021

bors try

bors bot added a commit that referenced this pull request Mar 28, 2021
@bors
Copy link
Contributor

bors bot commented Mar 28, 2021

try

Build failed:

@Demindiro
Copy link
Contributor Author

clippy on stable passes but nightly fails (even though I use nightly and it doesn't fail for me). Do I need to change anything?

Also, apparently clamp is unstable even though the linked issue has been closed since November 2020. Do I need to change that too?

It also seems the stable output of the tests matches that of my nightly output. However, if I run the tests as stable it passes. I've also never touched those tests.

@ghost
Copy link

ghost commented Mar 29, 2021

According to the build log you can apparently update the UI tests with TRYBUILD=overwrite. I've looked at the current test outputs and I think they're acceptable.

clippy on stable passes but nightly fails (even though I use nightly and it doesn't fail for me). Do I need to change anything?

No, it's allowed for nightly clippy to fail.

Also, apparently clamp is unstable even though the linked issue has been closed since November 2020. Do I need to change that too?

That's from rustc 1.46 which was a lot older than that I think? We haven't decided on a MSRV policy yet, but if you can work around it, please do for the moment being.

@Bromeon
Copy link
Member

Bromeon commented Mar 30, 2021

bors try

bors bot added a commit that referenced this pull request Mar 30, 2021
@bors
Copy link
Contributor

bors bot commented Mar 30, 2021

try

Build failed:

@ghost
Copy link

ghost commented Mar 30, 2021

error: Invalid syntax
expecting #[variant(...)]. See documentation:
https://docs.rs/gdnative/0.9.0/gdnative/core_types/trait.ToVariant.html#field-attributes
 --> $DIR/from_variant_fail_02.rs:6:15
  |
6 |     #[variant(baz::quux)]
  |               ^^^^^^^^^
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

ACTUAL OUTPUT:
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error: Invalid syntax
expecting #[variant(...)]. See documentation:
https://docs.rs/gdnative/0.9.0/gdnative/core_types/trait.ToVariant.html#field-attributes
 --> $DIR/from_variant_fail_02.rs:6:15
  |
6 |     #[variant(baz::quux)]
  |               ^^^
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
EXPECTED:
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error: Found baz::quux, expected one of:
to_variant_with, from_variant_with, with, skip_to_variant, skip_from_variant, skip
 --> $DIR/from_variant_fail_03.rs:6:15
  |
6 |     #[variant(baz::quux = "path::to::function")]
  |               ^^^^^^^^^
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

ACTUAL OUTPUT:
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error: Found baz::quux, expected one of:
to_variant_with, from_variant_with, with, skip_to_variant, skip_from_variant, skip
 --> $DIR/from_variant_fail_03.rs:6:15
  |
6 |     #[variant(baz::quux = "path::to::function")]
  |               ^^^
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

I think the expected outputs are preferrable here, but I'm not sure why the output for those errors changed. Shouldn't the error spans be provided by the derive macros? I don't think this PR touched those. Perhaps a rustc regression?

EDIT: It turns out that the current expected outputs are from a nightly compiler. Presumably the difference is caused by the availability of Span::join there. Maybe we'll want to disable those tests for stable compilers instead of changing the expected output back.

@ghost
Copy link

ghost commented Mar 30, 2021

@Demindiro It appears that you're having difficulty with the test suite. Since you have enabled the option to allow maintainers to push to your PR branch, would you mind if I fixed things and squashed the commits directly on your branch?

@Demindiro
Copy link
Contributor Author

Please do, this is getting ridiculous.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is definitely a big improvement over what we had. Thanks for the PR! I'm sorry that you've hit a few speedbumps with your first PR. I hope you'll take our enforcement of CI and bikeshedding of seemingly trivial points as evidence that we really care about the code here :)

Dealt with tests and squashed.

bors r+

bors bot added a commit that referenced this pull request Mar 30, 2021
713: Replace euclid with glam (proof-of-concept) r=toasteater a=Demindiro

I had some time to take a look at #594. I decided to go with `glam` since it compiles the fastest.

I went with the "front-end" approach as I believe that is the most flexible approach.

I did rename a few things (like `zero()` to `ZERO`, `quaternion()` to `new()`, ...) but that is easy to revert if required.

It doesn't seem like many changes are required. Wrapping all the methods in `glam` is easy to do with extensive use of `glam()` and `into()`. The crate does seem to miss implementations for a few types and methods like `Rect2` and `rotated`, so we'll have to implement those from scratch.

the `impl Mul/Div/Add/...`s for `Vector2` and `Vector3` are pretty much identical, maybe there is some way to reduce duplication?

Closes #594
Closes #670 (`Vector3` is fully implemented)

Co-authored-by: David Hoppenbrouwers <david@salt-inc.org>
Co-authored-by: toasteater <48371905+toasteater@users.noreply.github.com>
@bors
Copy link
Contributor

bors bot commented Mar 30, 2021

Build failed:

Update tests with the added `glam` dependency. Run tests that depend on
Span::join only on nightly.
@ghost
Copy link

ghost commented Mar 30, 2021

Well this is embarrasing

bors retry

@bors
Copy link
Contributor

bors bot commented Mar 30, 2021

Build succeeded:

@bors bors bot merged commit 3ad9b65 into godot-rust:master Mar 30, 2021
@Bromeon
Copy link
Member

Bromeon commented Mar 30, 2021

Cool to see this merged! 🍾

Thanks a lot to @Demindiro for your contribution and the patience, and @toasteater for the finishing touches! 🙂

@Bromeon Bromeon mentioned this pull request May 1, 2021
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Vector3 feature parity with Godot [discussion] Moving away from euclid in favor of local types
2 participants