-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
[Merged by Bors] - Fix Bevy crashing if no audio device is found #2269
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
If you try to
play_source
when there is no audio device, I don't like the behavior of silentely succeeding.I would expect this to either
error!
panic!
Result<(), ()>
(or some other error type)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.
From the player point of view, an
error
orpanic
are bad. "ok I know I don't have a audio device, don't crash and don't yell at me!". There's already awarn
on the creation, re-logging it every time a sound play doesn't add much...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.
That's fair.
However, I have the counter argument that if you don't have an audio device, and therefore the
stream_handle
isNone
, if you are trying to play anaudio_source
, that's incorrect. Calling these functions if the type itself is not constructed successfully and then "working" seems a little off. 😅It's fine if you try to create the
AudioSource
and that fails, (and it doesn't panic)however, if you actually try to play audio with that audio source, that probably shouldn't work.
Ultimately I'm fine with this PR as is though.
I think it's just important to consider how silently succeeding can be harmful. 😃
Arguable, we should remove the
default
implementation, and instead do something like:However, I don't think this is actually possible, since it needs
Default
to be initialized as a resource.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.
While
init_resource
requiresdefault
(actuallyFromWorld
, but that has a blanket implementation for types that implementdefault
),insert_resource
doesn't have that bound.An alternative is that
AudioOutput
is just never inserted as a Resource, and systems need to query forOption<Res<AudioOutput>>
instead ofRes<AudioOutput>
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.
Something like this would be my preferred solution :)
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 think something also to consider for right now is that the current standing of
bevy_audio
is not the best.It'll mostly likely get replaced in the future via
bevy_kira_audio
so I think right now, it should be our goal to make the built-in functionality as simple and friendly as possible, as the API will likely get scrapped and reworked completely.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.
@NathanSWard That's a completely fair position, and if it eventually gets done Correctly™ then that's fine, and I agree that a proper solution should be more general (for all resources/systems), so it's okay to punt it to a later PR.
But there's a big difference between, "this is hacky and we know it's hacky and we'll do it correctly later" and "this is a good design which we should keep". I'm advocating for the first, not the second.
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.
Just wondering, and very much out of topic, sorry about that... I pretty much always play with no sound because of reasons. Should the volume being off be detected as a failure then?
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's two basic designs:
is_muted
method.Result
which has anenum
that describes the various failures that can happen, withMuted
being one of the reasons.Either design is fine, they just make different tradeoffs. Personally I would go with the first one.
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 agree with the idea that users shouldn't need to care about this (most of the time). I personally don't think the spirit of rust is "whenever you have a chance to require explicit error handling ... do it". I think in rust, just like every other language, you should make a pragmatic call based on the context.
Ex: we could make everyone explicitly handle the case where they try to spawn a sprite, but a render device isn't present by making
spawn().insert(Sprite)
return a RenderDeviceNotAvailable error. But I would argue that doing that would "get in the way" more often than not. A missing render device is a corner case. If every api involving "rendering things" required checking for render device existence, users would have a "very bad time". And when its not there, its generally because the user intended it to be that way (ex; they are running in a headless environment). This is why we have a "headless render backend". We handle this "internally" so when someone tries using sprites, they don't need to think about render devices / account for them being missing.I would hazard a guess that in the 99.X% case, when users play an audio clip, they don't want to care about audio device existence via
if let
/unwrap
. Therefore we should have an api that optimizes for that use case. We should still expose "device existence information" to users that care about it. But we constantly make choices to hide information / assume a certain "happy path" state on behalf of our users in the interest of ergonomics and a "pleasant programming experience". This feels like a case where we should do that.I'm happy to continue this discussion, but I think the current impl is a solid short term solution to a nasty problem. And it has the benefit of not degrading UX for a common use case (and requiring
if let Some(audio_device)
for all audio operation definitely degrades UX for a common use case).