Skip to content

Commit

Permalink
Fix potential threading crashes
Browse files Browse the repository at this point in the history
  • Loading branch information
Pixaurora committed Nov 12, 2024
1 parent 983c854 commit 016743e
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

import net.pixaurora.kit_tunes.api.music.Album;
import net.pixaurora.kit_tunes.api.music.Artist;
Expand All @@ -15,14 +15,14 @@
import net.pixaurora.kitten_heart.impl.service.MusicMetadataService;

public class MusicMetadataImpl implements MusicMetadataService, MutableMusicMetadata {
private final Map<ResourcePath, Album> albums = new HashMap<>();
private final Map<ResourcePath, Artist> artists = new HashMap<>();
private final Map<ResourcePath, Track> tracks = new HashMap<>();
private final Map<ResourcePath, Album> albums = new ConcurrentHashMap<>();
private final Map<ResourcePath, Artist> artists = new ConcurrentHashMap<>();
private final Map<ResourcePath, Track> tracks = new ConcurrentHashMap<>();

private final HashMap<String, Track> trackMatches = new HashMap<>();
private final HashMap<ResourcePath, List<Album>> trackToAlbums = new HashMap<>();
private final Map<String, Track> trackMatches = new ConcurrentHashMap<>();
private final Map<ResourcePath, List<Album>> trackToAlbums = new ConcurrentHashMap<>();

private final HashMap<ResourcePath, Duration> trackDurations = new HashMap<>();
private final Map<ResourcePath, Duration> trackDurations = new ConcurrentHashMap<>();

@Override
public void add(Album album) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class PlayingSong implements ProgressProvider {
private final ListeningProgress progress;
private final MusicControls controls;

private boolean hasSentMiddleEvent;
private volatile boolean hasSentMiddleEvent;
private final long middleEventMillis;

public PlayingSong(ResourcePath path, Optional<Track> track, ListeningProgress progress, MusicControls controls) {
Expand All @@ -31,6 +31,7 @@ public PlayingSong(ResourcePath path, Optional<Track> track, ListeningProgress p
this.controls = controls;
this.middleEventMillis = track.map(Track::duration).map(duration -> duration.toMillis() * 6 / 10)
.orElse(Constants.MINIMUM_TIME_TO_SCROBBLE.toMillis());
this.hasSentMiddleEvent = false;

if (this.track.isPresent()) {
Track track0 = track.get();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package net.pixaurora.kitten_sounds.impl;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

import com.mojang.blaze3d.audio.Channel;

Expand All @@ -13,11 +11,13 @@

public class MusicControlsImpl implements MusicControls {
private Optional<ChannelHandle> channel = Optional.empty();
private final AtomicReference<PlaybackState> playbackState = new AtomicReference<>(PlaybackState.STOPPED);

public void channel(ChannelHandle channel) {
this.channel = Optional.of(channel);
}

@Override
public void pause() {
if (this.channel.isPresent()) {
this.channel.get().execute(Channel::pause);
Expand All @@ -33,26 +33,18 @@ public void unpause() {

@Override
public PlaybackState playbackState() {
if (this.channel.isEmpty() || this.channel.get().isStopped()) {
return PlaybackState.STOPPED;
}
return this.playbackState.get();
}

CompletableFuture<PlaybackState> playbackState = new CompletableFuture<PlaybackState>().orTimeout(1,
TimeUnit.MINUTES);

this.channel.get().execute(channel -> {
if (channel.playing()) {
playbackState.complete(PlaybackState.PLAYING);
} else {
playbackState.complete(PlaybackState.PAUSED);
}
});

try {
return playbackState.get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("Couldn't get playback state!", e);
}
public void updatePlaybackState(Channel channel) {
this.playbackState.set(computePlaybackState(channel));
}

public PlaybackState computePlaybackState(Channel channel) {
if (channel.playing()) {
return PlaybackState.PLAYING;
} else {
return PlaybackState.PAUSED;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ public static void pollTrackProgress(Map<SoundInstance, ChannelAccess.ChannelHan
return true;
} else {
polledSong.polled().execute(
channel -> polledSong.progress().measureProgress((SongProgressTracker) (Object) channel));
channel -> {
polledSong.progress().measureProgress((SongProgressTracker) (Object) channel);
polledSong.controls().updatePlaybackState(channel);
});

return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package net.pixaurora.kitten_sounds.impl;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

import com.mojang.blaze3d.audio.Channel;

Expand All @@ -13,6 +11,7 @@

public class MusicControlsImpl implements MusicControls {
private Optional<ChannelHandle> channel = Optional.empty();
private final AtomicReference<PlaybackState> playbackState = new AtomicReference<>(PlaybackState.STOPPED);

public void channel(ChannelHandle channel) {
this.channel = Optional.of(channel);
Expand All @@ -34,26 +33,18 @@ public void unpause() {

@Override
public PlaybackState playbackState() {
if (this.channel.isEmpty() || this.channel.get().isStopped()) {
return PlaybackState.STOPPED;
}
return this.playbackState.get();
}

CompletableFuture<PlaybackState> playbackState = new CompletableFuture<PlaybackState>().orTimeout(1,
TimeUnit.MINUTES);

this.channel.get().execute(channel -> {
if (channel.playing()) {
playbackState.complete(PlaybackState.PLAYING);
} else {
playbackState.complete(PlaybackState.PAUSED);
}
});

try {
return playbackState.get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("Couldn't get playback state!", e);
}
public void updatePlaybackState(Channel channel) {
this.playbackState.set(computePlaybackState(channel));
}

public PlaybackState computePlaybackState(Channel channel) {
if (channel.playing()) {
return PlaybackState.PLAYING;
} else {
return PlaybackState.PAUSED;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ public static void pollTrackProgress(Map<SoundInstance, ChannelAccess.ChannelHan
return true;
} else {
polledSong.polled().execute(
channel -> polledSong.progress().measureProgress((SongProgressTracker) (Object) channel));
channel -> {
polledSong.progress().measureProgress((SongProgressTracker) (Object) channel);
polledSong.controls().updatePlaybackState(channel);
});

return false;
}
Expand Down

0 comments on commit 016743e

Please sign in to comment.