diff --git a/app/src/main/java/org/toop/Main.java b/app/src/main/java/org/toop/Main.java index 1f91081..858ab1a 100644 --- a/app/src/main/java/org/toop/Main.java +++ b/app/src/main/java/org/toop/Main.java @@ -14,14 +14,17 @@ import java.io.IOException; import java.nio.file.NotDirectoryException; public class Main { - static void main(String[] args) throws IOException, UnsupportedAudioFileException, LineUnavailableException { + static void main(String[] args) throws IOException, UnsupportedAudioFileException, LineUnavailableException, InterruptedException { var a = new AssetManager(new File("app/src/main/resources/assets")); var b = new NetworkingClientManager(); var c = new SoundManager(a); -// IO.println(a.getAssets()); - IO.println(c.getClips()); - + new EventFlow().addPostEvent(new AudioEvents.PlayAudio("mainmenu.wav", true)).asyncPostEvent(); + new EventFlow().addPostEvent(new AudioEvents.PlayAudio("sadtrombone.wav", true)).asyncPostEvent(); + Thread.sleep(200); + new EventFlow().addPostEvent(new AudioEvents.PlayAudio("mainmenu.wav", true)).asyncPostEvent(); + new EventFlow().addPostEvent(new AudioEvents.PlayAudio("sadtrombone.wav", true)).asyncPostEvent(); + Thread.sleep(200); new EventFlow().addPostEvent(new AudioEvents.PlayAudio("mainmenu.wav", true)).asyncPostEvent(); new EventFlow().addPostEvent(new AudioEvents.PlayAudio("sadtrombone.wav", true)).asyncPostEvent(); diff --git a/framework/src/main/java/org/toop/framework/assets/resources/BaseResource.java b/framework/src/main/java/org/toop/framework/assets/resources/BaseResource.java index c4c8568..07469f8 100644 --- a/framework/src/main/java/org/toop/framework/assets/resources/BaseResource.java +++ b/framework/src/main/java/org/toop/framework/assets/resources/BaseResource.java @@ -1,23 +1,34 @@ package org.toop.framework.assets.resources; import java.io.*; +import java.nio.file.Files; public abstract class BaseResource { final InputStream stream; final File file; +public abstract class Resource { + final private byte[] rawData; + final private File file; BaseResource(final File file) { + Resource(final File file) throws RuntimeException { this.file = file; try { - this.stream = new BufferedInputStream(new FileInputStream(file)); - } catch (FileNotFoundException e) { + this.rawData = Files.readAllBytes(file.toPath()); + } catch (IOException e) { throw new RuntimeException(e); } } public InputStream getInputStream() { return this.stream; + public Resource load() { + return this; + } + + public InputStream getStream() { + return new BufferedInputStream(new ByteArrayInputStream(this.rawData)); } public File getFile() { diff --git a/framework/src/main/java/org/toop/framework/assets/resources/ImageResource.java b/framework/src/main/java/org/toop/framework/assets/resources/ImageResource.java new file mode 100644 index 0000000..bab44bf --- /dev/null +++ b/framework/src/main/java/org/toop/framework/assets/resources/ImageResource.java @@ -0,0 +1,27 @@ + +package org.toop.framework.assets.resources; + +import javafx.scene.image.Image; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + +public class ImageResource extends Resource { + + private Image image = null; + + public ImageResource(File imageFile) { + super(imageFile); + } + + public Image getImage() { + return this.image; + } + + @Override + public Resource load() { + this.image = new Image(this.getStream()); + return this; + } +} \ No newline at end of file diff --git a/framework/src/main/java/org/toop/framework/audio/SoundManager.java b/framework/src/main/java/org/toop/framework/audio/SoundManager.java index 59d0656..faa8770 100644 --- a/framework/src/main/java/org/toop/framework/audio/SoundManager.java +++ b/framework/src/main/java/org/toop/framework/audio/SoundManager.java @@ -1,9 +1,9 @@ package org.toop.framework.audio; +import org.toop.framework.SnowflakeGenerator; import org.toop.framework.assets.Asset; import org.toop.framework.assets.AssetManager; import org.toop.framework.assets.resources.AudioResource; -import org.toop.framework.assets.resources.Resource; import org.toop.framework.audio.events.AudioEvents; import org.toop.framework.eventbus.EventFlow; @@ -12,16 +12,15 @@ import java.util.*; import javax.sound.sampled.*; public class SoundManager { - private final Map activeClips = new HashMap<>(); - private final HashMap clips = new HashMap<>(); - private final AssetManager assetManager; + private final Map activeClips = new HashMap<>(); + private final HashMap audioResources = new HashMap<>(); + private final SnowflakeGenerator idGenerator = new SnowflakeGenerator(); // TODO: Don't create a new generator public SoundManager(AssetManager asm) { - this.assetManager = asm; // Get all Audio Resources and add them to a list. for (Asset resource : asm.getAllResourceOfType(AudioResource.class).values()) { try { - addClip(resource); + this.addAudioResource(resource); } catch (IOException | LineUnavailableException | UnsupportedAudioFileException e) { throw new RuntimeException(e); } @@ -36,53 +35,59 @@ public class SoundManager { } private void handleStopSound(AudioEvents.StopAudio event) { - this.stopSound(event.fileNameNoExtensionAndNoDirectory()); + this.stopSound(event.clipId()); } - private void addClip(Asset audioAsset) + private void addAudioResource(Asset audioAsset) throws IOException, UnsupportedAudioFileException, LineUnavailableException { AudioResource audioResource = audioAsset.getResource(); - this.clips.put(audioAsset.getName(), audioResource.getClip()); + this.audioResources.put(audioAsset.getName(), audioResource); } - private void playSound(String audioFileName, boolean loop) { - // Get clip - Clip clip = clips.get(audioFileName); + private long playSound(String audioFileName, boolean loop) { + try { + AudioResource resource = audioResources.get(audioFileName); - if (clip == null) { - return; - } - - // Reset clip - clip.setFramePosition(0); - - // If loop make it loop, else just start it once - if (loop){ - clip.loop(Clip.LOOP_CONTINUOUSLY); - } - else { - clip.start(); - } - - // store it so we can stop it later - activeClips.put(audioFileName, clip); // TODO: Do on snowflake for specific sound to stop - - // remove when finished (only for non-looping sounds) - clip.addLineListener(event -> { - if (event.getType() == LineEvent.Type.STOP && !clip.isRunning()) { - activeClips.remove(audioFileName); - clip.close(); + // Return -1 which indicates resource wasn't available + if (resource == null){ + return -1; } - }); + + // Get a new clip from resource + Clip clip = resource.getNewClip(); + + // If supposed to loop make it loop, else just start it once + if (loop){ + clip.loop(Clip.LOOP_CONTINUOUSLY); + } + else { + clip.start(); + } + + // Generate id for clip + long clipId = idGenerator.nextId(); + + // store it so we can stop it later + activeClips.put(clipId, clip); // TODO: Do on snowflake for specific sound to stop + + // remove when finished (only for non-looping sounds) + clip.addLineListener(event -> { + if (event.getType() == LineEvent.Type.STOP && !clip.isRunning()) { + activeClips.remove(clipId); + clip.close(); + } + }); + + // Return id so it can be stopped + return clipId; + } catch (LineUnavailableException | IOException | UnsupportedAudioFileException e) { + throw new RuntimeException(e); + } } - public HashMap getClips() { - return this.clips; - } - - public void stopSound(String audioFileName) { - Clip clip = activeClips.get(audioFileName); + public void stopSound(long clipId) { + Clip clip = activeClips.get(clipId); if (clip == null) { return; @@ -90,7 +95,7 @@ public class SoundManager { clip.stop(); clip.close(); - activeClips.remove(audioFileName); + activeClips.remove(clipId); } public void stopAllSounds() { diff --git a/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java b/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java index 56aaf64..74bc41a 100644 --- a/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java +++ b/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java @@ -8,5 +8,5 @@ public class AudioEvents extends EventsBase { public record PlayAudio(String fileNameNoExtensionAndNoDirectory, boolean loop) implements EventWithoutSnowflake {} - public record StopAudio(String fileNameNoExtensionAndNoDirectory) implements EventWithoutSnowflake {} + public record StopAudio(long clipId) implements EventWithoutSnowflake {} }