Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions Sources/CSFBAudioEngine/Player/AudioPlayer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2136,9 +2136,8 @@ Flags clearFlags(Flags flags, std::memory_order order = std::memory_order_acq_re
auto shouldStop = true;

if (__strong id<SFBAudioPlayerDelegate> delegate = player.delegate;
delegate != nil && [delegate respondsToSelector:@selector(audioPlayerEndOfAudio:)]) {
[delegate audioPlayerEndOfAudio:player];
shouldStop = false;
delegate != nil && [delegate respondsToSelector:@selector(audioPlayerShouldStopAtEndOfAudio:)]) {
shouldStop = [delegate audioPlayerShouldStopAtEndOfAudio:player];
}

Comment on lines 2137 to +2142
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

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

Because the selector audioPlayerEndOfAudio: is unchanged but the return type changed, a delegate built against the previous - (void)audioPlayerEndOfAudio: signature may still respond at runtime and this call will interpret an undefined return value as BOOL (often NO), leaving the engine running unexpectedly. If binary/runtime compatibility is a concern, prefer introducing a new selector for the shouldStop decision (and keep calling the legacy void callback), rather than changing the return type in-place.

Copilot uses AI. Check for mistakes.
if (shouldStop) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,9 +364,11 @@ NS_SWIFT_NAME(AudioPlayer.Delegate)
/// - parameter audioPlayer: The `SFBAudioPlayer` object
/// - parameter playbackState: The current playback state
- (void)audioPlayer:(SFBAudioPlayer *)audioPlayer playbackStateChanged:(SFBAudioPlayerPlaybackState)playbackState;
/// Called to notify the delegate when rendering is complete for all available decoders
/// Called to query the delegate whether playback should stop when rendering is complete for all available decoders
/// - parameter audioPlayer: The `SFBAudioPlayer` object
- (void)audioPlayerEndOfAudio:(SFBAudioPlayer *)audioPlayer NS_SWIFT_NAME(audioPlayerEndOfAudio(_:));
/// - returns: `YES` if the player should stop playback, `NO` to continue rendering silence
- (BOOL)audioPlayerShouldStopAtEndOfAudio:(SFBAudioPlayer *)audioPlayer
NS_SWIFT_NAME(audioPlayerShouldStopAtEndOfAudio(_:));
/// Called to notify the delegate that the decoding and rendering processes for a decoder have been canceled by a
/// user-initiated request
/// - warning: Do not change any properties of `decoder`
Expand Down