Thread not finishing - Sound Event Dispatcher Java

39 Views Asked by At

I am creating a game in Java and I am trying to implement music playing but I am running into issues ending the program.

The primary hierarchy of my program is 3 classes I have written; InputHandler, GameState, and Map. The InputHandler contains a GameState object, and a GameState object contains a Map (the player's current location) as well as a Graph structure of Maps which is the world map.

Every Map object also contains a File which is their music track, and also an AudioInputStream and a Clip to play this track. I have not implemented multiple locations as of yet, so only one Map is created at startup, and for testing I am just manually calling the .play() method I have written on the Map object, although obviously I plan to change this so it is called whenever the location is changed.

Here is some of my code (irrelevant parts cut out) so you might be able to understand the structure better.

public class Map {

private File track;
private AudioInputStream as;
private Clip clip;

public Map(...) throws UnsupportedAudioFileException, IOException, LineUnavailableException {

                --construction stuff here--

        as = AudioSystem.getAudioInputStream(track);
        clip = AudioSystem.getClip();
        clip.open(as);
    }

    public void playTrack() {
        clip.start();
    }

    public void stopTrack() {
        clip.stop();
    }
    
    public void closeMusicLine() {
        try {
            clip.close();
            as.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public class GameState { 

    private Map location;

    public GameState(Map startingLocation) {
        location = startingLocation;
    }

    public void stopMusic() {
        location.stopTrack();
    }
    
    public void closeMusicLine() {
        location.closeMusicLine();
    }

public class InputHandler { 

    private GameState state;

    public InputHandler(GameState state) { 
        this.state = state;
    }

    public String handle(String input) {

        if (...) { 
            --stuff for handling inputs etc--
        } else if (leadingCommand.equals("exit")) {
            state.stopMusic();
            state.closeMusicLine();
            output = "Bye!\n";
        }

        return output;
    }

}

public class Main {
    public static void main(String[] args) {
        Map m = null;
        try {
            m =  new Map(...);
            //m.playTrack();
        } catch (Exception e) {
            e.printStackTrace();
        }
        GameState g = new GameState(m);
        InputHandler ioHandler = new InputHandler(g);
        Scanner in = new Scanner(System.in);

        while (ioHandler.acceptingInput()) {
            System.out.println(ioHandler.handle(in.nextLine()));
        }

    }

}

I tried running my program to start, and I was very happy to hear my music playing without any trouble on the first time. The issue came when I issued the 'exit' command ingame. I was met with the usual "Bye!" that I should expect, but the program simple hanged. This lasted 15 seconds before out popped an error saying 2 threads refused to finish even after interrupt.

It was at this point that I added the closeMusicLine() method, as I have learned in school you should close InputStreams and other things after you're done to prevent data corruption. Unfortunately, this didn't work, although it did reduce the number of threads from 2 to 1. Even after I commented out the call to playTrack() in Main, I still had this issue, despite the fact that the music wasn't even playing anymore.

This is about as far as I know. I usually only like to work with code that I fully understand, to avoid stuff like this, but I really don't know much about audio playback in Java and I'm mostly copying code I found online.

1

There are 1 best solutions below

0
On

Gonna leave this up in case someone else has a similar issue OR if someone responds with a better solution, but I found that putting System.exit(0); at the end of main() (after the While loop exits) fixes it. I don't know how good this is because I don't know how safe it is to exit here, but unless someone responds otherwise I'll use this.