mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 10:54:51 +00:00
Moved loads to own class for better memory management. Added ability to add text- and localizationassets.
This commit is contained in:
1
.idea/dictionaries/project.xml
generated
1
.idea/dictionaries/project.xml
generated
@@ -6,6 +6,7 @@
|
|||||||
<w>dcompile</w>
|
<w>dcompile</w>
|
||||||
<w>errorprone</w>
|
<w>errorprone</w>
|
||||||
<w>flushnl</w>
|
<w>flushnl</w>
|
||||||
|
<w>gaaf</w>
|
||||||
<w>gamelist</w>
|
<w>gamelist</w>
|
||||||
<w>playerlist</w>
|
<w>playerlist</w>
|
||||||
<w>tictactoe</w>
|
<w>tictactoe</w>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.toop;
|
|||||||
import org.toop.app.gui.LocalServerSelector;
|
import org.toop.app.gui.LocalServerSelector;
|
||||||
import org.toop.framework.asset.AssetLoader;
|
import org.toop.framework.asset.AssetLoader;
|
||||||
import org.toop.framework.asset.AssetManager;
|
import org.toop.framework.asset.AssetManager;
|
||||||
|
import org.toop.framework.asset.resources.TextAsset;
|
||||||
import org.toop.framework.audio.SoundManager;
|
import org.toop.framework.audio.SoundManager;
|
||||||
import org.toop.framework.audio.events.AudioEvents;
|
import org.toop.framework.audio.events.AudioEvents;
|
||||||
import org.toop.framework.eventbus.EventFlow;
|
import org.toop.framework.eventbus.EventFlow;
|
||||||
@@ -14,22 +15,26 @@ import java.io.IOException;
|
|||||||
import java.nio.file.NotDirectoryException;
|
import java.nio.file.NotDirectoryException;
|
||||||
|
|
||||||
public class Main {
|
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(new AssetLoader("app/src/main/resources/assets"));
|
||||||
AssetManager.loadAssets(AssetLoader.getInstance());
|
var text = AssetManager.getAllOfType(TextAsset.class).getFirst().getResource();
|
||||||
|
|
||||||
|
text.load();
|
||||||
|
|
||||||
|
IO.println(text.getContent());
|
||||||
|
|
||||||
var b = new NetworkingClientManager();
|
var b = new NetworkingClientManager();
|
||||||
var c = new SoundManager();
|
var c = new SoundManager();
|
||||||
|
|
||||||
new EventFlow().addPostEvent(new AudioEvents.PlayAudio("mainmenu.wav", true)).asyncPostEvent();
|
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);
|
// Thread.sleep(200);
|
||||||
new EventFlow().addPostEvent(new AudioEvents.PlayAudio("mainmenu.wav", true)).asyncPostEvent();
|
// new EventFlow().addPostEvent(new AudioEvents.PlayAudio("mainmenu.wav", false)).asyncPostEvent();
|
||||||
new EventFlow().addPostEvent(new AudioEvents.PlayAudio("sadtrombone.wav", true)).asyncPostEvent();
|
// new EventFlow().addPostEvent(new AudioEvents.PlayAudio("sadtrombone.wav", false)).asyncPostEvent();
|
||||||
Thread.sleep(200);
|
// Thread.sleep(200);
|
||||||
new EventFlow().addPostEvent(new AudioEvents.PlayAudio("mainmenu.wav", true)).asyncPostEvent();
|
// new EventFlow().addPostEvent(new AudioEvents.PlayAudio("mainmenu.wav", false)).asyncPostEvent();
|
||||||
new EventFlow().addPostEvent(new AudioEvents.PlayAudio("sadtrombone.wav", true)).asyncPostEvent();
|
// new EventFlow().addPostEvent(new AudioEvents.PlayAudio("sadtrombone.wav", false)).asyncPostEvent();
|
||||||
|
|
||||||
javax.swing.SwingUtilities.invokeLater(LocalServerSelector::new);
|
javax.swing.SwingUtilities.invokeLater(LocalServerSelector::new);
|
||||||
}
|
}
|
||||||
|
|||||||
1
app/src/main/resources/assets/text/test.txt
Normal file
1
app/src/main/resources/assets/text/test.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Super gaaf!
|
||||||
@@ -13,29 +13,16 @@ import org.toop.framework.asset.resources.FileExtension;
|
|||||||
|
|
||||||
public class AssetLoader {
|
public class AssetLoader {
|
||||||
|
|
||||||
private static AssetLoader INSTANCE;
|
|
||||||
|
|
||||||
private final File rootFolder;
|
|
||||||
private final List<Asset<? extends BaseResource>> assets = new CopyOnWriteArrayList<>();
|
private final List<Asset<? extends BaseResource>> assets = new CopyOnWriteArrayList<>();
|
||||||
private final Map<String, Function<File, ? extends BaseResource>> registry = new ConcurrentHashMap<>();
|
private final Map<String, Function<File, ? extends BaseResource>> registry = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private AssetLoader(File rootFolder) {
|
public AssetLoader(File rootFolder) {
|
||||||
this.rootFolder = rootFolder;
|
|
||||||
autoRegisterResources();
|
autoRegisterResources();
|
||||||
fileSearcher(rootFolder);
|
fileSearcher(rootFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized void initialize(String rootFolderPath) {
|
public AssetLoader(String rootFolder) {
|
||||||
if (INSTANCE == null) {
|
this(new File(rootFolder));
|
||||||
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 List<Asset<? extends BaseResource>> getAssets() {
|
public List<Asset<? extends BaseResource>> getAssets() {
|
||||||
|
|||||||
@@ -26,6 +26,26 @@ public class AudioAsset extends BaseResource implements LoadableResource {
|
|||||||
|
|
||||||
// Generates a new audio stream from byte array
|
// Generates a new audio stream from byte array
|
||||||
private AudioInputStream getAudioStream() throws UnsupportedAudioFileException, IOException {
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,18 @@
|
|||||||
package org.toop.framework.asset.resources;
|
package org.toop.framework.asset.resources;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.file.Files;
|
|
||||||
|
|
||||||
public abstract class BaseResource {
|
public abstract class BaseResource {
|
||||||
private byte[] rawData;
|
|
||||||
final File file;
|
final File file;
|
||||||
private boolean isLoaded = false;
|
boolean isLoaded = false;
|
||||||
|
|
||||||
BaseResource(final File file) {
|
protected BaseResource(final File file) {
|
||||||
this.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() {
|
public File getFile() {
|
||||||
return this.file;
|
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,25 @@
|
|||||||
package org.toop.framework.asset.resources;
|
package org.toop.framework.asset.resources;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
|
|
||||||
public class FontAsset extends BaseResource implements LoadableResource {
|
public class FontAsset extends BaseResource implements LoadableResource {
|
||||||
|
|
||||||
private boolean isLoaded = false;
|
|
||||||
|
|
||||||
public FontAsset(final File fontFile) {
|
public FontAsset(final File fontFile) {
|
||||||
super(fontFile);
|
super(fontFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() throws FileNotFoundException {
|
public void load() {
|
||||||
|
this.isLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unload() {
|
public void unload() {
|
||||||
|
this.isLoaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLoaded() {
|
public boolean isLoaded() {
|
||||||
return false;
|
return this.isLoaded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ package org.toop.framework.asset.resources;
|
|||||||
|
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import java.io.File;
|
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 {
|
public class ImageAsset extends BaseResource implements LoadableResource {
|
||||||
private Image image;
|
private Image image;
|
||||||
|
|
||||||
@@ -13,25 +13,33 @@ public class ImageAsset extends BaseResource implements LoadableResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() throws FileNotFoundException {
|
public void load() {
|
||||||
if (!this.isLoaded()) {
|
if (!this.isLoaded) {
|
||||||
super.load(); // Make sure that base class (byte[]) is loaded
|
try (FileInputStream fis = new FileInputStream(this.file)) {
|
||||||
this.image = new Image(this.getInputStream());
|
this.image = new Image(fis);
|
||||||
|
this.isLoaded = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Failed to load image: " + this.file, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unload() {
|
public void unload() {
|
||||||
this.image = null;
|
this.image = null;
|
||||||
super.unload();
|
this.isLoaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLoaded() {
|
||||||
|
return this.isLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Image getImage() {
|
public Image getImage() {
|
||||||
if (!this.isLoaded()) try {
|
if (!this.isLoaded) {
|
||||||
load();
|
this.load();
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ package org.toop.framework.asset.resources;
|
|||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
|
||||||
public interface LoadableResource {
|
public interface LoadableResource {
|
||||||
void load() throws FileNotFoundException;
|
void load();
|
||||||
void unload();
|
void unload();
|
||||||
boolean isLoaded();
|
boolean isLoaded();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<Locale, ResourceBundle> 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<Locale> 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,26 +1,41 @@
|
|||||||
package org.toop.framework.asset.resources;
|
package org.toop.framework.asset.resources;
|
||||||
|
|
||||||
import java.io.File;
|
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 {
|
public class TextAsset extends BaseResource implements LoadableResource {
|
||||||
|
private String content;
|
||||||
|
|
||||||
TextAsset(final File file) {
|
public TextAsset(File file) {
|
||||||
super(file);
|
super(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
@Override
|
||||||
public void unload() {
|
public void unload() {
|
||||||
|
this.content = null;
|
||||||
|
this.isLoaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLoaded() {
|
public boolean isLoaded() {
|
||||||
return false;
|
return this.isLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContent() {
|
||||||
|
return this.content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user