-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
game_menu example: pull common patterns into methods #12008
base: main
Are you sure you want to change the base?
Conversation
@@ -45,10 +45,62 @@ fn setup(mut commands: Commands) { | |||
commands.spawn(Camera2dBundle::default()); | |||
} | |||
|
|||
// This outermost node encompasses the entire Window (100% width and height) | |||
// and centers all content vertically (align_items) and horizontally (justify_content) | |||
fn outer_node( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a pattern common to every screen of this example, and was previously repeated verbatim in 6 different places
} | ||
|
||
// This node is always a direct child of the `outer` node, and arranges contents in a column, from top to bottom | ||
fn inner_node<T: Into<BackgroundColor>>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pattern was previously used on every single screen except for the Splash screen, and so was repeated in five places
fn main_menu_setup(mut commands: Commands, asset_server: Res<AssetServer>) { | ||
// Common style for all buttons on the screen | ||
let button_style = Style { | ||
fn button_style() -> Style { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pattern was previously repeated verbatim in four different places. The only difference between the Main menu and the Main Settings menu was that the buttons were 50px wider on the Main menu. I've made the Main Settings menu buttons 50px wider in order to not have to repeat this configuration
} | ||
} | ||
|
||
fn button_text_style() -> TextStyle { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pattern was previously repeated verbatim in six places
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you considered extracting it on the root as a function? A similar pattern is used in game_setup
, we could re-use the same code.
fn default_font(font_size: f32) -> TextStyle {
TextStyle {
font_size,
color: TEXT_COLOR,
..default()
}
}
examples/games/game_menu.rs
Outdated
} | ||
|
||
// In the main menu and in the main settings menu, we create a column of buttons | ||
fn column_of_buttons( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pattern was previously repeated in two places
Net |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like this set of changes! It suddenly makes the example much less overwhelming.
I suggest a few changes to even reduce more the number of lines, but also to make the code a bit more in line with rust conventions. (The curly braces surrounding closures are especially problematic)
You don't need to manually change anything! I opened a PR on your bevy fork. See the link: awwsmm#1
} | ||
} | ||
|
||
fn button_text_style() -> TextStyle { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you considered extracting it on the root as a function? A similar pattern is used in game_setup
, we could re-use the same code.
fn default_font(font_size: f32) -> TextStyle {
TextStyle {
font_size,
color: TEXT_COLOR,
..default()
}
}
Regarding the state machine, I think it would work as ASCII art as module doc. Here is a wonderful draft
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the one thing to ask is: does this make the example harder to read? And I think it doesn't. In fact, it introduces some nice hints at good practices for UI dev for the current bevy UI state.
I also considered this. These changes definitely introduce a bit more indirection, but they also eliminate quite a lot of duplication. I think the net effect is improved readability and understandability. |
I made another version of the diagram. There are no edge labels, but they should be easy to infer hopefully.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving because this is an overall improvement. Just left a few nits.
FYI, to rebase, you just need to rename To avoid some headache, I would rebase and ignore the upstream changes. Here is how it would look like:
|
Remade this using labels, and making the diagram tall, rather than wide.
Wide diagrams are sometimes soft-wrapped in IDEs (RustRover, for example). Diagram is available here
|
2b2df07
to
8775459
Compare
Tested the version on this branch locally and it works now as it does before. All button colours and actions are as expected. |
Ready for re-review @nicopap , @benfrankel Thanks in advance! |
…(), renamed column_of_buttons() to button(), 'go to' -> 'to go'
221ef5a
to
4dc25de
Compare
☝🏻 updated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me :)
I'm mostly opposed to those changes. This example is on purpose boilerplate heavy as UI in Bevy is boilerplate heavy, and is a good way to show potential improvements. Solving it in the example rather than in Bevy is not the good way, and will make it harder to showcase those improvements later. It's also a very good candidate for scene driven UI, and that's made harder by having functions around. |
Thanks for your feedback, François. How would you use scene-driven UI here? Is there an example of that in the Bevy repo? Anyway, here are my counterpoints: Going through the Not improving this example because that would make future UI improvements appear less impactful is not, in my opinion, a good reason to leave an example in its current state. If anything, that biases any future comparison, because you started with an example which was purposefully not streamlined when it could have been. Even if you do not wish to accept these changes wholesale, surely there are some sections which you would approve of including in the example, like the diagram (or the functions which return styles, rather than the ones which spawn things). If you let me know which improvements, I'd be happy to extract only those out and trash the other ones. |
Objective
examples/games/game_menu
has a decent amount of boilerplateSolution