Reworked resources to be assets, and made AssetManager a singleton

This commit is contained in:
Bas de Jong
2025-09-30 21:01:59 +02:00
parent d158668dfd
commit 8328387e86
13 changed files with 182 additions and 112 deletions

View File

@@ -1,10 +1,10 @@
package org.toop.framework.assets; package org.toop.framework.assets;
import org.toop.framework.SnowflakeGenerator; import org.toop.framework.SnowflakeGenerator;
import org.toop.framework.assets.resources.Resource; import org.toop.framework.assets.resources.BaseResource;
public class Asset <T extends Resource> { public class Asset <T extends BaseResource> {
private final Long id; // IS this needed? private final Long id;
private final String name; private final String name;
private final T resource; private final T resource;

View File

@@ -1,9 +1,8 @@
package org.toop.framework.assets; package org.toop.framework.assets;
import org.toop.framework.assets.resources.AudioResource; import org.toop.framework.assets.resources.AudioAsset;
import org.toop.framework.assets.resources.FontResource; import org.toop.framework.assets.resources.BaseResource;
import org.toop.framework.assets.resources.ImageResource; import org.toop.framework.assets.resources.ImageAsset;
import org.toop.framework.assets.resources.Resource;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@@ -12,7 +11,7 @@ import java.util.Objects;
public class AssetLoader { public class AssetLoader {
private final File rootFolder; private final File rootFolder;
private final ArrayList<Asset<Resource>> assets = new ArrayList<>(); private final ArrayList<Asset<? extends BaseResource>> assets = new ArrayList<>();
public AssetLoader(File rootFolder) { public AssetLoader(File rootFolder) {
this.rootFolder = rootFolder; this.rootFolder = rootFolder;
@@ -23,16 +22,21 @@ public class AssetLoader {
return this.rootFolder; return this.rootFolder;
} }
public ArrayList<Asset<Resource>> getAssets() { public ArrayList<Asset<? extends BaseResource>> getAssets() {
return this.assets; return this.assets;
} }
private Resource resourceMapper(File file) throws FileNotFoundException { private <T extends BaseResource> T resourceMapper(Class<T> type, File file) throws FileNotFoundException {
return switch (getExtension(file.getName())) { BaseResource resource = switch (getExtension(file.getName())) {
case "wav" -> new AudioResource(file).load(); case "wav" -> new AudioAsset(file);
case "png" -> new ImageResource(file).load(); case "png" -> new ImageAsset(file);
default -> null; default -> null;
}; };
if (resource == null) return null;
if (!type.isInstance(resource))
throw new IllegalArgumentException("File " + file.getName() + " is not of type " + type);
return type.cast(resource);
} }
public static String getExtension(String name) { public static String getExtension(String name) {
@@ -51,9 +55,10 @@ public class AssetLoader {
fileSearcher(fileEntry); fileSearcher(fileEntry);
} else { } else {
try { try {
this.assets.add( BaseResource resource = resourceMapper(BaseResource.class, fileEntry); // generic token
new Asset<>(fileEntry.getName(), this.resourceMapper(fileEntry)) if (resource != null) {
); this.assets.add(new Asset<>(fileEntry.getName(), resource));
}
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View File

@@ -1,38 +1,38 @@
package org.toop.framework.assets; package org.toop.framework.assets;
import org.apache.maven.surefire.shared.io.function.IOBaseStream; import org.toop.framework.assets.resources.*;
import org.toop.framework.assets.resources.Resource;
import java.io.File; import java.util.*;
import java.nio.file.Path;
import java.util.HashMap;
public class AssetManager { public class AssetManager {
private static final AssetManager INSTANCE = new AssetManager();
private static final Map<String, Asset<? extends BaseResource>> assets = new HashMap<>();
private final HashMap<String, Asset<Resource>> assets = new HashMap<>(); private AssetManager() {}
public AssetManager(File rootFolder) { public static AssetManager getInstance() {
for (Asset<Resource> x : new AssetLoader(rootFolder).getAssets()) { return INSTANCE;
this.assets.put(x.getName(), x);
}
} }
public <T extends Resource> HashMap<String, Asset<T>> getAllResourceOfType(Class<T> resourceClass) { public <T extends BaseResource> ArrayList<Asset<T>> getAllOfType(Class<T> type) {
HashMap<String, Asset<T>> a = new HashMap<>(); ArrayList<Asset<T>> list = new ArrayList<>();
for (Asset<Resource> b : this.assets.values()) { for (Asset<? extends BaseResource> asset : assets.values()) { // <-- use .values()
if (resourceClass.isInstance(b.getResource())) { if (type.isInstance(asset.getResource())) {
a.put(b.getName(), (Asset<T>) b); @SuppressWarnings("unchecked")
Asset<T> typed = (Asset<T>) asset;
list.add(typed);
} }
} }
return a; return list;
}
public HashMap<String, Asset<Resource>> getAssets() {
return this.assets;
} }
public Asset<Resource> getAsset(String assetName) { public static Asset<? extends BaseResource> getById(String guid) {
return assets.get(assetName); return assets.get(guid);
} }
} public static Optional<Asset<? extends BaseResource>> findByName(String name) {
return assets.values().stream()
.filter(a -> a.getName().equals(name))
.findFirst();
}
}

View File

@@ -3,35 +3,53 @@ package org.toop.framework.assets.resources;
import javax.sound.sampled.*; import javax.sound.sampled.*;
import java.io.*; import java.io.*;
public class AudioResource extends Resource implements ResourceType<AudioResource> { public class AudioAsset extends BaseResource implements LoadableResource {
private AudioInputStream audioInputStream = null; private AudioInputStream audioInputStream = null;
private Clip clip = null; private Clip clip = null;
private boolean isLoaded = false;
public AudioResource(File audioFile) { public AudioAsset(final File audioFile) {
super(audioFile); super(audioFile);
} }
public AudioInputStream getAudioStream(){ public AudioInputStream getAudioStream() {
return this.audioInputStream; return this.audioInputStream;
} }
public Clip getClip() { @Override
return this.clip; public void load() {
}
public AudioResource load() {
try { try {
this.audioInputStream = AudioSystem.getAudioInputStream(this.stream); this.audioInputStream = AudioSystem.getAudioInputStream(this.stream);
Clip clip = AudioSystem.getClip(); Clip clip = AudioSystem.getClip();
clip.open(this.audioInputStream); clip.open(this.audioInputStream);
this.clip = clip; this.clip = clip;
this.isLoaded = true;
} catch (UnsupportedAudioFileException | LineUnavailableException e) { } catch (UnsupportedAudioFileException | LineUnavailableException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} catch (IOException e) { // TODO: Error handling } catch (IOException e) { // TODO: Error handling
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return this;
} }
@Override
public void unload() {
this.clip.stop();
this.clip.flush();
this.clip.close();
this.clip = null;
this.isLoaded = false;
}
@Override
public boolean isLoaded() {
return this.isLoaded;
}
public Clip getClip() {
if (!this.isLoaded) this.load();
return this.clip;
}
} }

View File

@@ -2,12 +2,12 @@ package org.toop.framework.assets.resources;
import java.io.*; import java.io.*;
public abstract class Resource { public abstract class BaseResource {
final InputStream stream; final InputStream stream;
final File file; final File file;
Resource(final File file) { BaseResource(final File file) {
this.file = file; this.file = file;
try { try {
this.stream = new BufferedInputStream(new FileInputStream(file)); this.stream = new BufferedInputStream(new FileInputStream(file));

View File

@@ -0,0 +1,28 @@
package org.toop.framework.assets.resources;
import java.io.File;
import java.io.FileNotFoundException;
public class FontAsset extends BaseResource implements LoadableResource {
private boolean isLoaded = false;
public FontAsset(final File fontFile) {
super(fontFile);
}
@Override
public void load() throws FileNotFoundException {
}
@Override
public void unload() {
}
@Override
public boolean isLoaded() {
return false;
}
}

View File

@@ -1,14 +0,0 @@
package org.toop.framework.assets.resources;
import java.io.File;
public class FontResource extends Resource implements ResourceType<FontResource> {
public FontResource(File fontFile) {
super(fontFile);
}
public FontResource load() {
return this;
}
}

View File

@@ -0,0 +1,38 @@
package org.toop.framework.assets.resources;
import javafx.scene.image.Image;
import java.io.File;
import java.io.FileNotFoundException;
public class ImageAsset extends BaseResource implements LoadableResource {
private Image image;
private boolean isLoaded = false;
public ImageAsset(final File file) throws FileNotFoundException {
super(file);
}
@Override
public void load() {
if (!this.isLoaded) {
this.image = new Image(this.stream);
this.isLoaded = true;
}
}
@Override
public void unload() {
this.image = null;
this.isLoaded = false;
}
@Override
public boolean isLoaded() {
return this.isLoaded;
}
public Image getImage() {
if (!this.isLoaded) load();
return image;
}
}

View File

@@ -1,22 +0,0 @@
package org.toop.framework.assets.resources;
import javafx.scene.image.Image;
import java.io.File;
public class ImageResource extends Resource implements ResourceType<ImageResource> {
private Image image = null;
public ImageResource(File imageFile) {
super(imageFile);
}
public Image getImage() {
return this.image;
}
public ImageResource load() {
this.image = new Image(this.stream);
return this;
}
}

View File

@@ -0,0 +1,9 @@
package org.toop.framework.assets.resources;
import java.io.FileNotFoundException;
public interface LoadableResource {
void load() throws FileNotFoundException;
void unload();
boolean isLoaded();
}

View File

@@ -1,5 +0,0 @@
package org.toop.framework.assets.resources;
public interface ResourceType<T extends Resource> {
T load();
}

View File

@@ -0,0 +1,33 @@
package org.toop.framework.assets.resources;
import org.w3c.dom.Text;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TextAsset extends BaseResource implements LoadableResource {
TextAsset(final File file) {
super(file);
}
@Override
public void load() throws FileNotFoundException {
}
@Override
public void unload() {
}
@Override
public boolean isLoaded() {
return false;
}
}

View File

@@ -1,20 +0,0 @@
package org.toop.framework.assets.resources;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import java.io.File;
import java.io.IOException;
public class TextResource extends Resource implements ResourceType<TextResource> {
TextResource(File file) {
super(file);
}
public TextResource load() {
return this;
}
}