AssetManager init

This commit is contained in:
Bas de Jong
2025-09-30 16:38:13 +02:00
parent 57bd6ded6f
commit 423fd9d68a
22 changed files with 275 additions and 137 deletions

View File

@@ -96,6 +96,12 @@
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>25</version>
</dependency>
</dependencies>
<build>

View File

@@ -1,24 +1,29 @@
package org.toop.framework.assets;
import org.toop.framework.SnowflakeGenerator;
import org.toop.framework.assets.resources.Resource;
import java.nio.file.Path;
public class Asset <T extends Resource> {
private final Long id; // IS this needed?
private final String name;
private final T resource;
public class Asset {
private Long id; // IS this needed?
private String name;
private Path assetPath;
private String asset;
public Asset(String name, Path assetPath) {
public Asset(String name, T resource) {
this.id = new SnowflakeGenerator().nextId();
this.name = name;
this.assetPath = assetPath;
this.resource = resource;
}
private void loadAsset() {
java.nio.file.Path
this.asset = this.assetPath;
public Long getId() {
return this.id;
}
public String getName() {
return this.name;
}
public T getResource() {
return this.resource;
}
}

View File

@@ -0,0 +1,64 @@
package org.toop.framework.assets;
import org.toop.framework.assets.resources.AudioResource;
import org.toop.framework.assets.resources.FontResource;
import org.toop.framework.assets.resources.ImageResource;
import org.toop.framework.assets.resources.Resource;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Objects;
public class AssetLoader {
private final File rootFolder;
private final ArrayList<Asset<Resource>> assets = new ArrayList<>();
public AssetLoader(File rootFolder) {
this.rootFolder = rootFolder;
fileSearcher(rootFolder);
}
public File getRootFolder() {
return this.rootFolder;
}
public ArrayList<Asset<Resource>> getAssets() {
return this.assets;
}
private Resource resourceMapper(File file) throws FileNotFoundException {
return switch (getExtension(file.getName())) {
case "wav" -> new AudioResource(file).load();
case "png" -> new ImageResource(file).load();
default -> null;
};
}
public static String getExtension(String name) {
String extension = "";
int i = name.lastIndexOf('.');
if (i > 0) {
extension = name.substring(i+1);
}
return extension;
}
private void fileSearcher(final File folder) {
for (final File fileEntry : Objects.requireNonNull(folder.listFiles())) {
if (fileEntry.isDirectory()) {
fileSearcher(fileEntry);
} else {
try {
this.assets.add(
new Asset<>(fileEntry.getName(), this.resourceMapper(fileEntry))
);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
}
}
}

View File

@@ -1,12 +1,38 @@
package org.toop.framework.assets;
import org.apache.maven.surefire.shared.io.function.IOBaseStream;
import org.toop.framework.assets.resources.Resource;
import java.io.File;
import java.nio.file.Path;
import java.util.HashMap;
public class AssetManager {
private HashMap<String, Asset> assets = new HashMap<>();
public AssetManager() {
private final HashMap<String, Asset<Resource>> assets = new HashMap<>();
public AssetManager(File rootFolder) {
for (Asset<Resource> x : new AssetLoader(rootFolder).getAssets()) {
this.assets.put(x.getName(), x);
}
}
public <T extends Resource> HashMap<String, Asset<T>> getAllResourceOfType(Class<T> resourceClass) {
HashMap<String, Asset<T>> a = new HashMap<>();
for (Asset<Resource> b : this.assets.values()) {
if (resourceClass.isInstance(b.getResource())) {
a.put(b.getName(), (Asset<T>) b);
}
}
return a;
}
public HashMap<String, Asset<Resource>> getAssets() {
return this.assets;
}
public Asset<Resource> getAsset(String assetName) {
return assets.get(assetName);
}
}

View File

@@ -0,0 +1,35 @@
package org.toop.framework.assets.resources;
import javax.sound.sampled.*;
import java.io.*;
public class AudioResource extends Resource {
private AudioInputStream audioInputStream = null;
private Clip clip = null;
public AudioResource(File audioFile) {
super(audioFile);
}
public AudioInputStream getAudioStream(){
return this.audioInputStream;
}
public Clip getClip() {
return this.clip;
}
@Override
public Resource load() {
try {
this.audioInputStream = AudioSystem.getAudioInputStream(this.stream);
Clip clip = AudioSystem.getClip();
clip.open(this.audioInputStream);
this.clip = clip;
} catch (UnsupportedAudioFileException | LineUnavailableException e) {
throw new RuntimeException(e);
} catch (IOException e) { // TODO: Error handling
throw new RuntimeException(e);
}
return this;
}
}

View File

@@ -0,0 +1,9 @@
package org.toop.framework.assets.resources;
import java.io.File;
public class FontResource extends Resource {
public FontResource(File fontFile) {
super(fontFile);
}
}

View File

@@ -0,0 +1,26 @@
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.stream);
return this;
}
}

View File

@@ -0,0 +1,29 @@
package org.toop.framework.assets.resources;
import java.io.*;
public abstract class Resource {
final InputStream stream;
final File file;
Resource(final File file) {
this.file = file;
try {
this.stream = new BufferedInputStream(new FileInputStream(file));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
public Resource load() {
return this;
}
public InputStream getInputStream() {
return this.stream;
}
public File getFile() {
return this.file;
}
}

View File

@@ -1,75 +0,0 @@
package org.toop.framework.audio;
import java.io.IOException;
import java.nio.file.*;
import java.util.HashSet;
import java.util.Set;
public class AudioFiles {
private Set<String> audioFiles;
private String audioDirectory;
public AudioFiles(String audioDirectory) throws NotDirectoryException {
if (!audioDirectory.endsWith("/") && !audioDirectory.endsWith("\\")) {
throw new NotDirectoryException(audioDirectory);
}
this.audioFiles = AudioFiles.getAudioFiles(audioDirectory);
this.audioDirectory = audioDirectory;
}
public Set<String> getAudioFiles() {
return this.audioFiles;
}
public String getAudioDirectory() {
return this.audioDirectory;
}
public String getAudioFile(String file) {
if (!audioFiles.contains(file)) {
return null;
}
return audioDirectory + file;
}
public static String removeAllKeepOnlyName(String fileDirectoryNameExtension) {
String withoutExtensionAndDirectory = "";
int i = fileDirectoryNameExtension.lastIndexOf('.');
if (i > 0) {
withoutExtensionAndDirectory = fileDirectoryNameExtension.substring(0, i);
}
int y = withoutExtensionAndDirectory.lastIndexOf("/");
int k = withoutExtensionAndDirectory.lastIndexOf("\\");
if (y > 0) {
withoutExtensionAndDirectory = withoutExtensionAndDirectory.substring(y+1);
} else if (k > 0) {
withoutExtensionAndDirectory = withoutExtensionAndDirectory.substring(k+1);
}
return withoutExtensionAndDirectory;
}
private static Set<String> getAudioFiles(String audioDirectory) {
Set<String> fileSet = new HashSet<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(Paths.get(audioDirectory))) {
for (Path path : stream) {
if (!Files.isDirectory(path)) {
String extension = "";
int i = path.getFileName().toString().lastIndexOf('.');
if (i > 0) {
extension = path.getFileName().toString().substring(i+1);
}
if (extension.equalsIgnoreCase("wave") || extension.equalsIgnoreCase("wav")
|| extension.equalsIgnoreCase("mp3"))
fileSet.add(path.getFileName()
.toString());
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return fileSet;
}
}

View File

@@ -1,5 +1,9 @@
package org.toop.framework.audio;
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,22 +16,22 @@ public class SoundManager {
private final Map<String, Clip> activeClips = new HashMap<>();
private HashMap<String, Integer> clips = new HashMap<>();
private AudioFiles audioFiles;
private AssetManager assetManager;
private Vector afs;
private Vector sizes;
private Vector infos;
private Vector audios;
private int num=0;
public SoundManager(AudioFiles audioFiles) {
public SoundManager(AssetManager ass) {
afs=new Vector();
sizes=new Vector();
infos=new Vector();
audios=new Vector();
this.audioFiles = audioFiles;
for (var file : audioFiles.getAudioFiles()) {
this.assetManager = ass;
for (Asset<AudioResource> resource : ass.getAllResourceOfType(AudioResource.class).values()) {
try {
addClip(audioFiles.getAudioDirectory() + file);
addClip(resource);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (UnsupportedAudioFileException e) {
@@ -42,33 +46,27 @@ public class SoundManager {
}
private void handlePlaySound(AudioEvents.PlayAudio event) {
try {
this.playSound(event.fileNameNoExtensionAndNoDirectory(), event.loop());
} catch (UnsupportedAudioFileException e) {
throw new RuntimeException(e);
} catch (LineUnavailableException e) {
throw new RuntimeException(e);
}
this.playSound(event.fileNameNoExtensionAndNoDirectory(), event.loop());
}
private void handleStopSound(AudioEvents.StopAudio event) {
this.stopSound(event.fileNameNoExtensionAndNoDirectory());
}
private void addClip(String s)
private void addClip(Asset<AudioResource> audiol)
throws IOException, UnsupportedAudioFileException, LineUnavailableException {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File(s));
AudioFormat af = audioInputStream.getFormat();
int size = (int) (af.getFrameSize() * audioInputStream.getFrameLength());
AudioResource ad = audiol.getResource();
AudioFormat af = ad.getAudioStream().getFormat();
int size = (int) (af.getFrameSize() * ad.getAudioStream().getFrameLength());
byte[] audio = new byte[size];
DataLine.Info info = new DataLine.Info(Clip.class, af, size);
audioInputStream.read(audio, 0, size);
ad.getInputStream().read(audio, 0, size);
afs.add(af);
sizes.add(new Integer(size));
infos.add(info);
audios.add(audio);
this.clips.put(AudioFiles.removeAllKeepOnlyName(s), this.audios.size()-1);
this.clips.put(audiol.getName(), this.audios.size()-1);
num++;
}
@@ -87,30 +85,39 @@ public class SoundManager {
return new ByteArrayInputStream(data);
}
private void playSound(String audioFileName, boolean loop)
throws UnsupportedAudioFileException, LineUnavailableException {
int x = clips.get(audioFileName);
if (x > num) {
System.out.println("playSound: sample nr[" + x + "] is not available");
} else {
Clip clip = (Clip) AudioSystem.getLine((DataLine.Info) infos.elementAt(x));
clip.open((AudioFormat) afs.elementAt(x), (byte[]) audios.elementAt(x),
0, ((Integer) sizes.elementAt(x)).intValue());
private void playSound(String audioFileName, boolean loop) {
var b = this.assetManager.getAllResourceOfType(AudioResource.class);
b.get(audioFileName).getResource().getClip().start();
}
clip.start();
if (loop) clip.loop(Clip.LOOP_CONTINUOUSLY);
// private void playSound(String audioFileName, boolean loop)
// throws UnsupportedAudioFileException, LineUnavailableException {
// int x = clips.get(audioFileName);
// if (x > num) {
// System.out.println("playSound: sample nr[" + x + "] is not available");
// } else {
// Clip clip = (Clip) AudioSystem.getLine((DataLine.Info) infos.elementAt(x));
//// clip.open((AudioFormat) afs.elementAt(x), (byte[]) audios.elementAt(x),
//// 0, ((Integer) sizes.elementAt(x)).intValue());
//
// clip.start();
// if (loop) clip.loop(Clip.LOOP_CONTINUOUSLY);
//
// // 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();
// }
// });
// }
// }
// 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();
}
});
}
public HashMap<String, Integer> getClips() {
return this.clips;
}
public void stopSound(String audioFileName) {