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

Allow RenderTarget comparison #8300

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

aevyrie
Copy link
Member

@aevyrie aevyrie commented Apr 4, 2023

Objective

  • The changes in Windows as Entities removed the ability to compare RenderTargets without bringing in additional query data. This should not be needed, as these types are directly comparable.

Solution

  • Reinstate derive macros.

@james7132 james7132 added A-Rendering Drawing game state to the screen C-Usability A targeted quality-of-life change that makes Bevy easier to use labels Apr 4, 2023
@@ -370,7 +370,7 @@ impl CameraRenderGraph {

/// The "target" that a [`Camera`] will render to. For example, this could be a [`Window`](bevy_window::Window)
/// swapchain or an [`Image`].
#[derive(Debug, Clone, Reflect)]
#[derive(Debug, Clone, Reflect, PartialEq, Eq, Hash, PartialOrd, Ord)]
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure if Ord can be implemented here properly. Are we potentially arbitrarily stating that all Window variants are less than Image variants? Does that even make sense?

Copy link
Member Author

Choose a reason for hiding this comment

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

I mirrored the derives from NormalizedRenderTarget to stay consistent. I assume these are derived for use cases where you want an ordered list or hashmap keys or similar.

Copy link
Member

Choose a reason for hiding this comment

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

Upon checking the docs for the stdlib, it occurred to me the exact ordering behavior of the derive macros are not well documented/defined. Filed rust-lang/rust#109946 as a follow-up.

If enum variants matter, and we want a first-to-last ordering for render targets, I'm tempted to say we should put Image variants before Window, since that tends to be how you'd expect it to be sorted in a rendering order, and we should probably document that too. This can be done in this PR or as a follow-up.

@jakobhellermann
Copy link
Contributor

This will return false for RenderTarget::Window(WindowRef::Primary) == RenderTarget::Window(WindowRef::Entity(primary_window)), right? Is that a problem?

@aevyrie
Copy link
Member Author

aevyrie commented Apr 5, 2023

I kinda think that's a problem with the new RenderTarget changes. I've found the recent changes to the type difficult to work with, and the special casing for primary windows makes it awkward to use. The fact that you can represent identical states with different values is a code smell to me, and not something I think we should patch over with more code.

Anywho, the larger point here is that I should be able to take two RenderTargets and check if they are equal (without needing to do additional ECS queries!). I'm fine with axing Ord and friends, the only reason I included those was to mirror the sister Normalized type.

Copy link
Member

@cart cart left a comment

Choose a reason for hiding this comment

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

I'm on board for these changes, although removing Ord makes sense if we don't have a reasonable use case for it, especially given the conversation above.

I think I'm even on board for WindowRef::Primary != WindowRef::Entity(PRIMARY_WINDOW_ENTITY), provided we document that.

I kinda think that's a problem with the new RenderTarget changes. I've found the recent changes to the type difficult to work with, and the special casing for primary windows makes it awkward to use. The fact that you can represent identical states with different values is a code smell to me, and not something I think we should patch over with more code.

The core issue is that you can't have a statically defined "default entity id" (like we could for WindowId::primary because we owned the entire id space for WindowId). If we remove WindowRef::Primary, that would mean that RenderTarget could no longer have a default window value, which means Cameras could no longer have a default value.

There are a variety of alternatives, I just think they're all worse than the current approach:

  1. Re-add WindowId and make it a component. For RenderTargets and other window references, use that instead of Entities. This feels weird to me (each window has two canonical ids) and makes a number of assignment scenarios harder than entities (ex: spawn a window with a command, grab the newly created WindowId, assign to camera render target).
  2. Use RenderTarget::Window(Option<Entity>) and "fix up" the None value on the first frame with the primary window. I've been pushing against the "fix up" pattern in Bevy for awhile. As much as possible I don't want to be touching people's entities. If a user sets a value on a component, it should stay that way to avoid surprises. This pattern also produces change events that users don't expect. And imo as much as possible entities should be in a "correct" state on insert. They shouldn't be "made correct' at some arbitrary point in the schedule. This also doesn't really solve the comparison problem because None != Some(PRIMARY_WINDOW_ENTITY) is essentially the same thing.

@cart
Copy link
Member

cart commented Apr 5, 2023

I suppose theres also option (3): don't impl Default for Camera and require people to assign RenderTarget values (and everything else) themselves. But thats not actually an option for so many different reasons that I'm not going to list them unless someone really wants to advocate for this.

@aevyrie
Copy link
Member Author

aevyrie commented Apr 5, 2023

I'm in favor of removing Ord for for RenderTarget and NormalizedRenderTarget. I'm not sure that order makes much sense for these types, and users may have different ordering needs and expectations. Would it be acceptable to include that change in this PR?

@cart
Copy link
Member

cart commented Apr 6, 2023

Yeah I'm on board for that

@BD103 BD103 added S-Adopt-Me The original PR author has no intent to complete this work. Pick me up! D-Trivial Nice and easy! A great choice to get started with Bevy labels Aug 24, 2024
@bas-ie
Copy link
Contributor

bas-ie commented Sep 22, 2024

Adopted in #15353 .

@alice-i-cecile alice-i-cecile added S-Needs-Design This issue requires design work to think about how it would best be accomplished X-Contentious There are nontrivial implications that should be thought through D-Straightforward Simple bug fixes and API improvements, docs, test and examples and removed D-Trivial Nice and easy! A great choice to get started with Bevy labels Sep 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Usability A targeted quality-of-life change that makes Bevy easier to use D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Adopt-Me The original PR author has no intent to complete this work. Pick me up! S-Needs-Design This issue requires design work to think about how it would best be accomplished X-Contentious There are nontrivial implications that should be thought through
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

7 participants