Renamed assetmanager to resourcemanager

This commit is contained in:
lieght
2025-10-02 21:47:18 +02:00
parent 3c699cde01
commit ccc8ba3b79
25 changed files with 300 additions and 292 deletions

View File

@@ -4,6 +4,9 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.toop.framework.asset.events.AssetLoaderEvents;
import org.toop.framework.asset.resources.*;
import org.toop.framework.asset.types.BundledResource;
import org.toop.framework.asset.types.FileExtension;
import org.toop.framework.asset.types.PreloadResource;
import org.toop.framework.eventbus.EventFlow;
import org.reflections.Reflections;
@@ -17,7 +20,7 @@ import java.util.function.Function;
/**
* Responsible for loading assets from a file system directory into memory.
* <p>
* The {@code AssetLoader} scans a root folder recursively, identifies files,
* The {@code ResourceLoader} scans a root folder recursively, identifies files,
* and maps them to registered resource types based on file extensions and
* {@link FileExtension} annotations.
* It supports multiple resource types including {@link PreloadResource} (automatically loaded)
@@ -25,7 +28,7 @@ import java.util.function.Function;
* </p>
*
* <p>Assets are stored in a static, thread-safe list and can be retrieved
* through {@link AssetManager}.</p>
* through {@link ResourceManager}.</p>
*
* <p>Features:</p>
* <ul>
@@ -38,24 +41,24 @@ import java.util.function.Function;
*
* <p>Usage example:</p>
* <pre>{@code
* AssetLoader loader = new AssetLoader("assets");
* ResourceLoader loader = new ResourceLoader("assets");
* double progress = loader.getProgress();
* List<Asset<? extends BaseResource>> loadedAssets = loader.getAssets();
* }</pre>
*/
public class AssetLoader {
private static final Logger logger = LogManager.getLogger(AssetLoader.class);
private static final List<Asset<? extends BaseResource>> assets = new CopyOnWriteArrayList<>();
public class ResourceLoader {
private static final Logger logger = LogManager.getLogger(ResourceLoader.class);
private static final List<ResourceMeta<? extends BaseResource>> assets = new CopyOnWriteArrayList<>();
private final Map<String, Function<File, ? extends BaseResource>> registry = new ConcurrentHashMap<>();
private final AtomicInteger loadedCount = new AtomicInteger(0);
private int totalCount = 0;
/**
* Constructs an AssetLoader and loads assets from the given root folder.
* Constructs an ResourceLoader and loads assets from the given root folder.
* @param rootFolder the folder containing asset files
*/
public AssetLoader(File rootFolder) {
public ResourceLoader(File rootFolder) {
autoRegisterResources();
List<File> foundFiles = new ArrayList<>();
fileSearcher(rootFolder, foundFiles);
@@ -80,10 +83,10 @@ public class AssetLoader {
}
/**
* Constructs an AssetLoader from a folder path.
* Constructs an ResourceLoader from a folder path.
* @param rootFolder the folder path containing assets
*/
public AssetLoader(String rootFolder) {
public ResourceLoader(String rootFolder) {
this(new File(rootFolder));
}
@@ -115,7 +118,7 @@ public class AssetLoader {
* Returns a snapshot list of all assets loaded by this loader.
* @return list of loaded assets
*/
public List<Asset<? extends BaseResource>> getAssets() {
public List<ResourceMeta<? extends BaseResource>> getAssets() {
return new ArrayList<>(assets);
}
@@ -179,7 +182,7 @@ public class AssetLoader {
boolean alreadyAdded = assets.stream()
.anyMatch(a -> a.getResource() == finalResource);
if (!alreadyAdded) {
assets.add(new Asset<>(file.getName(), resource));
assets.add(new ResourceMeta<>(file.getName(), resource));
}
logger.info("Loaded {} from {}", resource.getClass().getSimpleName(), file.getAbsolutePath());

View File

@@ -8,9 +8,9 @@ import java.util.concurrent.ConcurrentHashMap;
/**
* Centralized manager for all loaded assets in the application.
* <p>
* {@code AssetManager} maintains a thread-safe registry of {@link Asset} objects
* {@code ResourceManager} maintains a thread-safe registry of {@link Asset} objects
* and provides utility methods to retrieve assets by name, ID, or type.
* It works together with {@link AssetLoader} to register assets automatically
* It works together with {@link ResourceLoader} to register assets automatically
* when they are loaded from the file system.
* </p>
*
@@ -25,47 +25,47 @@ import java.util.concurrent.ConcurrentHashMap;
* <p>Example usage:</p>
* <pre>{@code
* // Load assets from a loader
* AssetLoader loader = new AssetLoader(new File("RootFolder"));
* AssetManager.loadAssets(loader);
* ResourceLoader loader = new ResourceLoader(new File("RootFolder"));
* ResourceManager.loadAssets(loader);
*
* // Retrieve a single resource
* ImageAsset background = AssetManager.get("background.jpg");
* ImageAsset background = ResourceManager.get("background.jpg");
*
* // Retrieve all fonts
* List<Asset<FontAsset>> fonts = AssetManager.getAllOfType(FontAsset.class);
* List<Asset<FontAsset>> fonts = ResourceManager.getAllOfType(FontAsset.class);
*
* // Retrieve by asset name or optional lookup
* Optional<Asset<? extends BaseResource>> maybeAsset = AssetManager.findByName("menu.css");
* Optional<Asset<? extends BaseResource>> maybeAsset = ResourceManager.findByName("menu.css");
* }</pre>
*
* <p>Notes:</p>
* <ul>
* <li>All retrieval methods are static and thread-safe.</li>
* <li>The {@link #get(String)} method may require casting if the asset type is not known at compile time.</li>
* <li>Assets should be loaded via {@link AssetLoader} before retrieval.</li>
* <li>Assets should be loaded via {@link ResourceLoader} before retrieval.</li>
* </ul>
*/
public class AssetManager {
private static final AssetManager INSTANCE = new AssetManager();
private static final Map<String, Asset<? extends BaseResource>> assets = new ConcurrentHashMap<>();
public class ResourceManager {
private static final ResourceManager INSTANCE = new ResourceManager();
private static final Map<String, ResourceMeta<? extends BaseResource>> assets = new ConcurrentHashMap<>();
private AssetManager() {}
private ResourceManager() {}
/**
* Returns the singleton instance of {@code AssetManager}.
* Returns the singleton instance of {@code ResourceManager}.
*
* @return the shared instance
*/
public static AssetManager getInstance() {
public static ResourceManager getInstance() {
return INSTANCE;
}
/**
* Loads all assets from a given {@link AssetLoader} into the manager.
* Loads all assets from a given {@link ResourceLoader} into the manager.
*
* @param loader the loader that has already loaded assets
*/
public synchronized static void loadAssets(AssetLoader loader) {
public synchronized static void loadAssets(ResourceLoader loader) {
for (var asset : loader.getAssets()) {
assets.put(asset.getName(), asset);
}
@@ -80,11 +80,23 @@ public class AssetManager {
*/
@SuppressWarnings("unchecked")
public static <T extends BaseResource> T get(String name) {
Asset<T> asset = (Asset<T>) assets.get(name);
ResourceMeta<T> asset = (ResourceMeta<T>) assets.get(name);
if (asset == null) return null;
return asset.getResource();
}
/**
* Retrieve the resource of a given name, cast to the expected type.
*
* @param name the asset name
* @param <T> the expected resource type
* @return the resource, or null if not found
*/
@SuppressWarnings("unchecked")
public static <T extends BaseResource> T get(Class<T> type, String name) {
return type.cast(assets.get(name).getResource());
}
/**
* Retrieve all assets of a specific resource type.
*
@@ -92,12 +104,12 @@ public class AssetManager {
* @param <T> the resource type
* @return a list of assets matching the type
*/
public static <T extends BaseResource> ArrayList<Asset<T>> getAllOfType(Class<T> type) {
ArrayList<Asset<T>> list = new ArrayList<>();
for (Asset<? extends BaseResource> asset : assets.values()) {
public static <T extends BaseResource> ArrayList<ResourceMeta<T>> getAllOfType(Class<T> type) {
ArrayList<ResourceMeta<T>> list = new ArrayList<>();
for (ResourceMeta<? extends BaseResource> asset : assets.values()) {
if (type.isInstance(asset.getResource())) {
@SuppressWarnings("unchecked")
Asset<T> typed = (Asset<T>) asset;
ResourceMeta<T> typed = (ResourceMeta<T>) asset;
list.add(typed);
}
}
@@ -110,8 +122,8 @@ public class AssetManager {
* @param id the asset ID
* @return the asset, or null if not found
*/
public static Asset<? extends BaseResource> getById(String id) {
for (Asset<? extends BaseResource> asset : assets.values()) {
public static ResourceMeta<? extends BaseResource> getById(String id) {
for (ResourceMeta<? extends BaseResource> asset : assets.values()) {
if (asset.getId().toString().equals(id)) {
return asset;
}
@@ -125,7 +137,7 @@ public class AssetManager {
* @param name the asset name
* @return the asset, or null if not found
*/
public static Asset<? extends BaseResource> getByName(String name) {
public static ResourceMeta<? extends BaseResource> getByName(String name) {
return assets.get(name);
}
@@ -135,7 +147,7 @@ public class AssetManager {
* @param name the asset name
* @return an Optional containing the asset if found
*/
public static Optional<Asset<? extends BaseResource>> findByName(String name) {
public static Optional<ResourceMeta<? extends BaseResource>> findByName(String name) {
return Optional.ofNullable(assets.get(name));
}
@@ -144,7 +156,7 @@ public class AssetManager {
*
* @param asset the asset to add
*/
public static void addAsset(Asset<? extends BaseResource> asset) {
public static void addAsset(ResourceMeta<? extends BaseResource> asset) {
assets.put(asset.getName(), asset);
}
}

View File

@@ -3,12 +3,12 @@ package org.toop.framework.asset;
import org.toop.framework.SnowflakeGenerator;
import org.toop.framework.asset.resources.BaseResource;
public class Asset <T extends BaseResource> {
public class ResourceMeta<T extends BaseResource> {
private final Long id;
private final String name;
private final T resource;
public Asset(String name, T resource) {
public ResourceMeta(String name, T resource) {
this.id = new SnowflakeGenerator().nextId();
this.name = name;
this.resource = resource;

View File

@@ -1,5 +1,7 @@
package org.toop.framework.asset.resources;
import org.toop.framework.asset.types.FileExtension;
import java.io.File;
@FileExtension({"css"})

View File

@@ -1,6 +1,9 @@
package org.toop.framework.asset.resources;
import javafx.scene.text.Font;
import org.toop.framework.asset.types.FileExtension;
import org.toop.framework.asset.types.PreloadResource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

View File

@@ -1,6 +1,9 @@
package org.toop.framework.asset.resources;
import javafx.scene.image.Image;
import org.toop.framework.asset.types.FileExtension;
import org.toop.framework.asset.types.LoadableResource;
import java.io.File;
import java.io.FileInputStream;

View File

@@ -1,5 +1,9 @@
package org.toop.framework.asset.resources;
import org.toop.framework.asset.types.BundledResource;
import org.toop.framework.asset.types.FileExtension;
import org.toop.framework.asset.types.LoadableResource;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;

View File

@@ -1,6 +1,8 @@
package org.toop.framework.asset.resources;
import javafx.scene.media.Media;
import org.toop.framework.asset.types.FileExtension;
import org.toop.framework.asset.types.LoadableResource;
import java.io.*;

View File

@@ -1,10 +1,10 @@
package org.toop.framework.asset.resources;
import javafx.scene.media.Media;
import org.toop.framework.asset.types.FileExtension;
import org.toop.framework.asset.types.LoadableResource;
import javax.sound.sampled.*;
import java.io.*;
import java.net.URI;
@FileExtension({"wav"})
public class SoundEffectAsset extends BaseResource implements LoadableResource {

View File

@@ -1,5 +1,8 @@
package org.toop.framework.asset.resources;
import org.toop.framework.asset.types.FileExtension;
import org.toop.framework.asset.types.LoadableResource;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

View File

@@ -1,4 +1,6 @@
package org.toop.framework.asset.resources;
package org.toop.framework.asset.types;
import org.toop.framework.asset.ResourceLoader;
import java.io.File;
@@ -6,7 +8,7 @@ import java.io.File;
* Represents a resource that can be composed of multiple files, or "bundled" together
* under a common base name.
*
* <p>Implementing classes allow an {@link org.toop.framework.asset.AssetLoader}
* <p>Implementing classes allow an {@link ResourceLoader}
* to automatically merge multiple related files into a single resource instance.</p>
*
* <p>Typical use cases include:</p>

View File

@@ -1,4 +1,7 @@
package org.toop.framework.asset.resources;
package org.toop.framework.asset.types;
import org.toop.framework.asset.ResourceLoader;
import org.toop.framework.asset.resources.BaseResource;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -9,7 +12,7 @@ import java.lang.annotation.ElementType;
* Annotation to declare which file extensions a {@link BaseResource} subclass
* can handle.
*
* <p>This annotation is processed by the {@link org.toop.framework.asset.AssetLoader}
* <p>This annotation is processed by the {@link ResourceLoader}
* to automatically register resource types for specific file extensions.
* Each extension listed will be mapped to the annotated resource class,
* allowing the loader to instantiate the correct type when scanning files.</p>

View File

@@ -1,4 +1,6 @@
package org.toop.framework.asset.resources;
package org.toop.framework.asset.types;
import org.toop.framework.asset.ResourceLoader;
/**
* Represents a resource that can be explicitly loaded and unloaded.
@@ -40,7 +42,7 @@ package org.toop.framework.asset.resources;
* }</pre>
*
* <p>This interface is commonly used with {@link PreloadResource} to allow automatic
* loading by an {@link org.toop.framework.asset.AssetLoader} if desired.</p>
* loading by an {@link ResourceLoader} if desired.</p>
*/
public interface LoadableResource {
/**

View File

@@ -1,13 +1,15 @@
package org.toop.framework.asset.resources;
package org.toop.framework.asset.types;
import org.toop.framework.asset.ResourceLoader;
/**
* Marker interface for resources that should be **automatically loaded** by the {@link org.toop.framework.asset.AssetLoader}.
* Marker interface for resources that should be **automatically loaded** by the {@link ResourceLoader}.
*
* <p>Extends {@link LoadableResource}, so any implementing class must provide the standard
* {@link LoadableResource#load()} and {@link LoadableResource#unload()} methods, as well as the
* {@link LoadableResource#isLoaded()} check.</p>
*
* <p>When a resource implements {@code PreloadResource}, the {@code AssetLoader} will invoke
* <p>When a resource implements {@code PreloadResource}, the {@code ResourceLoader} will invoke
* {@link LoadableResource#load()} automatically after the resource is discovered and instantiated,
* without requiring manual loading by the user.</p>
*

View File

@@ -1,15 +1,15 @@
package org.toop.framework.audio;
import javafx.application.Platform;
import javafx.scene.media.MediaPlayer;
import org.toop.framework.SnowflakeGenerator;
import org.toop.framework.asset.Asset;
import org.toop.framework.asset.AssetManager;
import org.toop.framework.asset.ResourceManager;
import org.toop.framework.asset.ResourceMeta;
import org.toop.framework.asset.resources.MusicAsset;
import org.toop.framework.asset.resources.SoundEffectAsset;
import org.toop.framework.audio.events.AudioEvents;
import org.toop.framework.eventbus.EventFlow;
import javafx.scene.media.MediaPlayer;
import java.io.*;
import java.util.*;
import javax.sound.sampled.*;
@@ -25,7 +25,7 @@ public class SoundManager {
public SoundManager() {
// Get all Audio Resources and add them to a list.
for (Asset<SoundEffectAsset> asset : AssetManager.getAllOfType(SoundEffectAsset.class)) {
for (ResourceMeta<SoundEffectAsset> asset : ResourceManager.getAllOfType(SoundEffectAsset.class)) {
try {
this.addAudioResource(asset);
} catch (IOException | LineUnavailableException | UnsupportedAudioFileException e) {
@@ -58,7 +58,7 @@ public class SoundManager {
this.stopSound(event.clipId());
}
private void addAudioResource(Asset<SoundEffectAsset> audioAsset)
private void addAudioResource(ResourceMeta<SoundEffectAsset> audioAsset)
throws IOException, UnsupportedAudioFileException, LineUnavailableException {
this.audioResources.put(audioAsset.getName(), audioAsset.getResource());
@@ -74,15 +74,15 @@ public class SoundManager {
private void handleMusicStart(AudioEvents.StartBackgroundMusic e) {
backgroundMusicQueue.clear();
Platform.runLater(() -> {
backgroundMusicQueue.addAll(
AssetManager.getAllOfType(MusicAsset.class).stream()
.map(Asset::getResource)
.toList()
);
backgroundMusicPlayer();
});
List<MusicAsset> shuffledArray = new ArrayList<>(ResourceManager.getAllOfType(MusicAsset.class)
.stream()
.map(ResourceMeta::getResource)
.toList());
Collections.shuffle(shuffledArray);
backgroundMusicQueue.addAll(
shuffledArray
);
backgroundMusicPlayer();
}
private void addBackgroundMusic(MusicAsset musicAsset) {