-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Remove incorrect equality comparisons for asset load error types #14428
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
Conversation
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 seems more correct to me. I also like the methods. It feels cleaner than having users use matches!
directly.
// NOTE: an `is_not_loaded` method is intentionally not included, as it may mislead some users | ||
// into thinking it is complementary to `is_loaded`. | ||
// `NotLoaded` is a very specific failure mode and in most cases it is not necessary to directly check for it. | ||
// If this is necessary the `matches!` macro can be used instead of a helper method. |
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.
Unrelated to this PR but it might be worth renaming the NotLoaded
variant to Idle
or something to help clarify the distinction on the enum itself.
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.
There might be a better name, but I like how NotLoaded
avoids making any statements about the asset. If an asset handle is NotLoaded
, it could mean that it hasn't started loading yet, or it could mean that there is no asset associated with the handle and never will be, or that the handle is invalid. A name like Idle
implies that the asset does exist in some form which isn't necessarily true
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.
Oh good point, I hadn't considered that 🤔
/// Returns `true` if the asset is loaded or in the process of being loaded. If true true, | ||
/// then the asset can be considered to be in a "normal" state: the asset either exists | ||
/// or will exist, and no errors have been encountered yet. | ||
pub fn is_loaded_or_loading(&self) -> bool { | ||
self.is_loaded() || self.is_loading() | ||
} |
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.
Is this a common thing yo check for? I imagine you'd generally want to handle these two cases separately, right?
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'm not tied to this method, I'd be okay with removing it. I just imagined that some users would want a quick way of checking if an asset is in a valid state or not, and allowing you to call is_loaded
and is_loading
in a single call allows you to avoid binding a LoadState
to a local
@JoJoJet if you resolve merge conflicts I'll get this in. |
Adopted in #15890 |
Objective
The type
AssetLoadError
hasPartialEq
andEq
impls, which is problematic due to the fact that theAssetLoaderError
andAddAsyncError
variants lie in their impls: they will returntrue
for anyBox<dyn Error>
with the sameTypeId
, even if the actual value is different. This can lead to subtle bugs if a user relies on the equality comparison to ensure that two values are equal.More generally, it is an anti-pattern for large error types involving dynamic dispatch, such as
AssetLoadError
, to have equality comparisons. Directly comparing two errors for equality is usually not desired -- if some logic needs to branch based on the value of an error, it is usually more correct to check for specific variants and inspect their fields.As far as I can tell, the only reason these errors have equality comparisons is because the
LoadState
enum wrapsAssetLoadError
for itsFailed
variant. This equality comparison is only used to check for== LoadState::Loaded
, which we can easily replace with anis_loaded
method.Solution
Remove the
{Partial}Eq
impls fromLoadState
, which also allows us to remove it from the error types.Migration Guide
The types
bevy_asset::AssetLoadError
andbevy_asset::LoadState
no longer support equality comparisons. If you need to check for an asset's load state, consider checking for a specific variant usingLoadState::is_loaded
or thematches!
macro. Similarly, consider using thematches!
macro to check for specific variants of theAssetLoadError
type if you need to inspect the value of an asset load error in your code.