From 5e4db91750ed7b39dcd705e3a7efca2a4a315844 Mon Sep 17 00:00:00 2001
From: lieght <49651652+BAFGdeJong@users.noreply.github.com>
Date: Wed, 1 Oct 2025 04:19:28 +0200
Subject: [PATCH] Moved loads to own class for better memory management. Added
ability to add text- and localizationassets.
---
.idea/dictionaries/project.xml | 1 +
app/src/main/java/org/toop/Main.java | 25 +++---
app/src/main/resources/assets/text/test.txt | 1 +
.../org/toop/framework/asset/AssetLoader.java | 19 +----
.../framework/asset/resources/AudioAsset.java | 22 ++++-
.../asset/resources/BaseResource.java | 41 +--------
.../framework/asset/resources/FontAsset.java | 11 +--
.../framework/asset/resources/ImageAsset.java | 34 +++++---
.../asset/resources/LoadableResource.java | 2 +-
.../asset/resources/LocalizationAsset.java | 85 +++++++++++++++++++
.../framework/asset/resources/TextAsset.java | 29 +++++--
11 files changed, 177 insertions(+), 93 deletions(-)
create mode 100644 app/src/main/resources/assets/text/test.txt
create mode 100644 framework/src/main/java/org/toop/framework/asset/resources/LocalizationAsset.java
diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml
index 5f1391a..46f4d3b 100644
--- a/.idea/dictionaries/project.xml
+++ b/.idea/dictionaries/project.xml
@@ -6,6 +6,7 @@
dcompile
errorprone
flushnl
+ gaaf
gamelist
playerlist
tictactoe
diff --git a/app/src/main/java/org/toop/Main.java b/app/src/main/java/org/toop/Main.java
index 8fb2f17..a3dbd73 100644
--- a/app/src/main/java/org/toop/Main.java
+++ b/app/src/main/java/org/toop/Main.java
@@ -3,6 +3,7 @@ package org.toop;
import org.toop.app.gui.LocalServerSelector;
import org.toop.framework.asset.AssetLoader;
import org.toop.framework.asset.AssetManager;
+import org.toop.framework.asset.resources.TextAsset;
import org.toop.framework.audio.SoundManager;
import org.toop.framework.audio.events.AudioEvents;
import org.toop.framework.eventbus.EventFlow;
@@ -14,22 +15,26 @@ import java.io.IOException;
import java.nio.file.NotDirectoryException;
public class Main {
- static void main(String[] args) throws IOException, UnsupportedAudioFileException, LineUnavailableException, InterruptedException {
+ static void main(String[] args) {
- AssetLoader.initialize("app/src/main/resources/assets");
- AssetManager.loadAssets(AssetLoader.getInstance());
+ AssetManager.loadAssets(new AssetLoader("app/src/main/resources/assets"));
+ var text = AssetManager.getAllOfType(TextAsset.class).getFirst().getResource();
+
+ text.load();
+
+ IO.println(text.getContent());
var b = new NetworkingClientManager();
var c = new SoundManager();
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();
+// new EventFlow().addPostEvent(new AudioEvents.PlayAudio("sadtrombone.wav", false)).asyncPostEvent();
+// Thread.sleep(200);
+// new EventFlow().addPostEvent(new AudioEvents.PlayAudio("mainmenu.wav", false)).asyncPostEvent();
+// new EventFlow().addPostEvent(new AudioEvents.PlayAudio("sadtrombone.wav", false)).asyncPostEvent();
+// Thread.sleep(200);
+// new EventFlow().addPostEvent(new AudioEvents.PlayAudio("mainmenu.wav", false)).asyncPostEvent();
+// new EventFlow().addPostEvent(new AudioEvents.PlayAudio("sadtrombone.wav", false)).asyncPostEvent();
javax.swing.SwingUtilities.invokeLater(LocalServerSelector::new);
}
diff --git a/app/src/main/resources/assets/text/test.txt b/app/src/main/resources/assets/text/test.txt
new file mode 100644
index 0000000..9e44f93
--- /dev/null
+++ b/app/src/main/resources/assets/text/test.txt
@@ -0,0 +1 @@
+Super gaaf!
\ No newline at end of file
diff --git a/framework/src/main/java/org/toop/framework/asset/AssetLoader.java b/framework/src/main/java/org/toop/framework/asset/AssetLoader.java
index 1c77c72..397a81a 100644
--- a/framework/src/main/java/org/toop/framework/asset/AssetLoader.java
+++ b/framework/src/main/java/org/toop/framework/asset/AssetLoader.java
@@ -13,29 +13,16 @@ import org.toop.framework.asset.resources.FileExtension;
public class AssetLoader {
- private static AssetLoader INSTANCE;
-
- private final File rootFolder;
private final List> assets = new CopyOnWriteArrayList<>();
private final Map> registry = new ConcurrentHashMap<>();
- private AssetLoader(File rootFolder) {
- this.rootFolder = rootFolder;
+ public AssetLoader(File rootFolder) {
autoRegisterResources();
fileSearcher(rootFolder);
}
- public static synchronized void initialize(String rootFolderPath) {
- if (INSTANCE == null) {
- INSTANCE = new AssetLoader(new File(rootFolderPath));
- }
- }
-
- public static AssetLoader getInstance() {
- if (INSTANCE == null) {
- throw new IllegalStateException("AssetLoader not initialized. Call initialize() first.");
- }
- return INSTANCE;
+ public AssetLoader(String rootFolder) {
+ this(new File(rootFolder));
}
public List> getAssets() {
diff --git a/framework/src/main/java/org/toop/framework/asset/resources/AudioAsset.java b/framework/src/main/java/org/toop/framework/asset/resources/AudioAsset.java
index 9a4a679..4b00212 100644
--- a/framework/src/main/java/org/toop/framework/asset/resources/AudioAsset.java
+++ b/framework/src/main/java/org/toop/framework/asset/resources/AudioAsset.java
@@ -26,6 +26,26 @@ public class AudioAsset extends BaseResource implements LoadableResource {
// Generates a new audio stream from byte array
private AudioInputStream getAudioStream() throws UnsupportedAudioFileException, IOException {
- return AudioSystem.getAudioInputStream(this.getInputStream());
+ return AudioSystem.getAudioInputStream(this.file);
+ }
+
+ @Override
+ public void load() {
+ try {
+ this.getAudioStream();
+ this.isLoaded = true;
+ } catch (UnsupportedAudioFileException | IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void unload() {
+ this.isLoaded = false; // TODO?
+ }
+
+ @Override
+ public boolean isLoaded() {
+ return this.isLoaded;
}
}
diff --git a/framework/src/main/java/org/toop/framework/asset/resources/BaseResource.java b/framework/src/main/java/org/toop/framework/asset/resources/BaseResource.java
index 95ce7aa..c1aa040 100644
--- a/framework/src/main/java/org/toop/framework/asset/resources/BaseResource.java
+++ b/framework/src/main/java/org/toop/framework/asset/resources/BaseResource.java
@@ -1,53 +1,18 @@
package org.toop.framework.asset.resources;
import java.io.*;
-import java.nio.file.Files;
public abstract class BaseResource {
- private byte[] rawData;
+
final File file;
- private boolean isLoaded = false;
+ boolean isLoaded = false;
- BaseResource(final File file) {
+ protected BaseResource(final File file) {
this.file = file;
}
- public boolean isLoaded() {
- return this.isLoaded;
- }
-
- public void load() throws FileNotFoundException {
- this.loadRawData();
- isLoaded = true;
- }
-
- private void loadRawData() throws FileNotFoundException{
- try {
- this.rawData = Files.readAllBytes(file.toPath());
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- public void unload(){
- this.unloadRawData();
- isLoaded = false;
- }
-
- private void unloadRawData() {
- this.rawData = null;
- }
-
public File getFile() {
return this.file;
}
- public InputStream getInputStream() throws FileNotFoundException {
- if (!isLoaded){
- // Manually load the data, makes sure it doesn't call subclass load()
- loadRawData();
- isLoaded = true;
- }
- return new BufferedInputStream(new ByteArrayInputStream(this.rawData));
- }
}
diff --git a/framework/src/main/java/org/toop/framework/asset/resources/FontAsset.java b/framework/src/main/java/org/toop/framework/asset/resources/FontAsset.java
index b4f3d06..db4ad84 100644
--- a/framework/src/main/java/org/toop/framework/asset/resources/FontAsset.java
+++ b/framework/src/main/java/org/toop/framework/asset/resources/FontAsset.java
@@ -1,28 +1,25 @@
package org.toop.framework.asset.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 {
+ public void load() {
+ this.isLoaded = true;
}
@Override
public void unload() {
-
+ this.isLoaded = false;
}
@Override
public boolean isLoaded() {
- return false;
+ return this.isLoaded;
}
}
diff --git a/framework/src/main/java/org/toop/framework/asset/resources/ImageAsset.java b/framework/src/main/java/org/toop/framework/asset/resources/ImageAsset.java
index 5f12d58..3cc0a3b 100644
--- a/framework/src/main/java/org/toop/framework/asset/resources/ImageAsset.java
+++ b/framework/src/main/java/org/toop/framework/asset/resources/ImageAsset.java
@@ -2,9 +2,9 @@ package org.toop.framework.asset.resources;
import javafx.scene.image.Image;
import java.io.File;
-import java.io.FileNotFoundException;
+import java.io.FileInputStream;
-@FileExtension({"png"})
+@FileExtension({"png", "jpg", "jpeg"})
public class ImageAsset extends BaseResource implements LoadableResource {
private Image image;
@@ -13,25 +13,33 @@ public class ImageAsset extends BaseResource implements LoadableResource {
}
@Override
- public void load() throws FileNotFoundException {
- if (!this.isLoaded()) {
- super.load(); // Make sure that base class (byte[]) is loaded
- this.image = new Image(this.getInputStream());
+ public void load() {
+ if (!this.isLoaded) {
+ try (FileInputStream fis = new FileInputStream(this.file)) {
+ this.image = new Image(fis);
+ this.isLoaded = true;
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to load image: " + this.file, e);
+ }
}
}
@Override
public void unload() {
this.image = null;
- super.unload();
+ this.isLoaded = false;
+ }
+
+ @Override
+ public boolean isLoaded() {
+ return this.isLoaded;
}
public Image getImage() {
- if (!this.isLoaded()) try {
- load();
- } catch (FileNotFoundException e) {
- throw new RuntimeException(e);
+ if (!this.isLoaded) {
+ this.load();
+ return image;
}
- return image;
+ return null;
}
-}
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/toop/framework/asset/resources/LoadableResource.java b/framework/src/main/java/org/toop/framework/asset/resources/LoadableResource.java
index fe14ab6..4b94092 100644
--- a/framework/src/main/java/org/toop/framework/asset/resources/LoadableResource.java
+++ b/framework/src/main/java/org/toop/framework/asset/resources/LoadableResource.java
@@ -3,7 +3,7 @@ package org.toop.framework.asset.resources;
import java.io.FileNotFoundException;
public interface LoadableResource {
- void load() throws FileNotFoundException;
+ void load();
void unload();
boolean isLoaded();
}
diff --git a/framework/src/main/java/org/toop/framework/asset/resources/LocalizationAsset.java b/framework/src/main/java/org/toop/framework/asset/resources/LocalizationAsset.java
new file mode 100644
index 0000000..27d9b83
--- /dev/null
+++ b/framework/src/main/java/org/toop/framework/asset/resources/LocalizationAsset.java
@@ -0,0 +1,85 @@
+package org.toop.framework.asset.resources;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+@FileExtension({"properties"})
+public class LocalizationAsset extends BaseResource implements LoadableResource {
+ private final Map bundles = new HashMap<>();
+ private boolean isLoaded = false;
+
+ public LocalizationAsset(File file) {
+ super(file);
+ }
+
+ @Override
+ public void load() {
+ // Convention: file names like messages_en.properties, ui_de.properties, etc.
+ String baseName = getBaseName(getFile().getName());
+
+ // Scan the parent folder for all matching *.properties with same basename
+ File folder = getFile().getParentFile();
+ File[] files = folder.listFiles((dir, name) ->
+ name.startsWith(baseName) && name.endsWith(".properties"));
+
+ if (files != null) {
+ for (File f : files) {
+ Locale locale = extractLocale(f.getName(), baseName);
+ try (InputStreamReader reader =
+ new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8)) {
+ this.bundles.put(locale, new PropertyResourceBundle(reader));
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to load localization file: " + f, e);
+ }
+ }
+ }
+
+ this.isLoaded = true;
+ }
+
+ @Override
+ public void unload() {
+ this.bundles.clear();
+ this.isLoaded = false;
+ }
+
+ @Override
+ public boolean isLoaded() {
+ return this.isLoaded;
+ }
+
+ public String getString(String key, Locale locale) {
+ ResourceBundle bundle = this.bundles.get(locale);
+ if (bundle == null) throw new MissingResourceException(
+ "No bundle for locale: " + locale, getClass().getName(), key);
+ return bundle.getString(key);
+ }
+
+ public boolean hasLocale(Locale locale) {
+ return this.bundles.containsKey(locale);
+ }
+
+ public Set getAvailableLocales() {
+ return Collections.unmodifiableSet(this.bundles.keySet());
+ }
+
+ private String getBaseName(String fileName) {
+ int underscoreIndex = fileName.indexOf('_');
+ int dotIndex = fileName.lastIndexOf('.');
+ if (underscoreIndex > 0) {
+ return fileName.substring(0, underscoreIndex);
+ }
+ return fileName.substring(0, dotIndex);
+ }
+
+ private Locale extractLocale(String fileName, String baseName) {
+ int underscoreIndex = fileName.indexOf('_');
+ int dotIndex = fileName.lastIndexOf('.');
+ if (underscoreIndex > 0 && dotIndex > underscoreIndex) {
+ String localePart = fileName.substring(underscoreIndex + 1, dotIndex);
+ return Locale.forLanguageTag(localePart.replace('_', '-'));
+ }
+ return Locale.getDefault(); // fallback
+ }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/toop/framework/asset/resources/TextAsset.java b/framework/src/main/java/org/toop/framework/asset/resources/TextAsset.java
index 5231513..8fc51bc 100644
--- a/framework/src/main/java/org/toop/framework/asset/resources/TextAsset.java
+++ b/framework/src/main/java/org/toop/framework/asset/resources/TextAsset.java
@@ -1,26 +1,41 @@
package org.toop.framework.asset.resources;
import java.io.File;
-import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+@FileExtension({"txt", "json", "xml"})
public class TextAsset extends BaseResource implements LoadableResource {
+ private String content;
- TextAsset(final File file) {
+ public TextAsset(File file) {
super(file);
}
@Override
- public void load() throws FileNotFoundException {
-
+ public void load() {
+ try {
+ byte[] bytes = Files.readAllBytes(getFile().toPath());
+ this.content = new String(bytes, StandardCharsets.UTF_8);
+ this.isLoaded = true;
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to load text asset: " + getFile(), e);
+ }
}
@Override
public void unload() {
-
+ this.content = null;
+ this.isLoaded = false;
}
@Override
public boolean isLoaded() {
- return false;
+ return this.isLoaded;
}
-}
+
+ public String getContent() {
+ return this.content;
+ }
+}
\ No newline at end of file