Closed CaptainLexington closed 4 years ago
I really like this!
I think sets are probably fine, performance wise. The operation is actually faster than it would be on a vector, because sets are based on hash trees IIRC (they're just a specialization of maps).
The pause thing is probably still something that could probably be implemented on top of this as well, because sets also make object lookup easy, since sound objects are you unique. You're right it'd be less declarative to have to have a function for this but I think there's possibly some solution we just haven't thought of, and this is still more powerful than what we have. Same with the metadata.
I think as an improvement on something that was already kind of a crude hack that didn't get nearly as much time in the oven, this passes my approval at least. 👍 I'm happy to approve as is, unless you've got some more ideas you wanna add to this before it's complete. 😄
I updated the demo to introduce a hovering-type sound effect for when the ship is moving. There is, unfortunately, a slight gap when the effect loops, but some digging indicates this is a weakness of the HTMLMediaElement API (or at least implementation on Chrome). It seems like the best bet is to upgrade to using the newer but more complicated Web Audio API, but that sounds like a task for another PR.
This PR is definitely just a suggestion/starting point. It changes the structure and semantics of the
audio-state
atom and theto-play
function, in a way that I hope makes it more expressive but no less simple to use.:music
and:effects
are now sets instead of vecs, and to stop music or a sound effect, you just remove it from the set. When a sound effect finishes, it will automatically be removed from the set. Instead of anis-playing
boolean that describes one piece of music,to-play
receives the entire audio-state for the previous frame. The only difference between:music
and:effects
is that things in:music
loop by default, using the.-loop
property, but it is now easy to "loop" a sound effect too, by just keeping it in:effects
as long as some condition holds.Benefits
Drawbacks
.pause
function on the sound object to do that.While writing this it occurred to me that putting sounds in a set made it impossible to play a sound concurrently with itself, if e.g. two of the same laser guns go off at the same time. But then I realized that that's currently how it works. If you add the same sound effect object to the queue while it is already playing, nothing will happen. Either way, the user would need to create a copy of the sound to play multiple instances at once.
Please give me your thoughts!