A Preloading Resource Idea, is it a good or bad one?

so, i had the idea that i would need to propper manage my resources if i want a eficient code. And i tought of this:



Create a Package called ResourcePath, it will contain only Enums such as this one:


package ResourcePath;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

public enum TextureResourcePath {
   
    TextureTechWall("Textures\","TechWall.jpg", 0),
    TextureRoughMetal("Textures\","rough_metal_texture.png", 1),
    TextureLava("Textures\","Lava.jpg", 2),
    TextureFlare("Textures\","Flaresmall.jpg", 3)
    ;
   
    private String path;
    private String name;
    private int id;
    public static final String rooturl = "file:" + System.getProperty("user.dir")+ "/Resources/";
    public static final String rootpath = System.getProperty("user.dir")+ "\Resources\";
    private TextureResourcePath(String path, String name, int id){
        this.path = path;
        this.name = name;
        this.id = id;
    }
   
    public String getPath(){
        return path;
    }
    public String getName(){
        return name;
    }

    public int getId() {
        return id;
    }
    @Override
    public String toString() {
        return rootpath + path + name;
    }

    public URL toURL(){
        try {
            return new URL(rooturl + path + name);
        } catch (MalformedURLException ex) {
            Logger.getLogger(ResourcePath.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

}



it will store all possible texture paths inside the Resources directory right on your Dist directory, they would be somethign like: "distResourcesTexturesFlaresmall.jpg", this can become either a String for a File or a URL for a.. URL!

using this i can create the GraphicsManager: (what is not yet ready, but using the same idea here comes the SoundManager that is ready ;D)

package MainPack;

import ResourcePath.SoundResourcePath;
import com.jme.renderer.Camera;
import com.jmex.audio.AudioSystem;
import com.jmex.audio.AudioTrack;
import com.jmex.audio.AudioTrack.TrackType;
public class SoundManager {
    private static AudioSystem audio;
    private static final AudioTrack[] SFX = new AudioTrack[SoundResourcePath.values().length];
    private static void preloadSFX() {
        for(SoundResourcePath r : SoundResourcePath.values())
        SFX[r.getId()] = getSFX(r);
    }
    public static void preload(Camera cam){
        audio = AudioSystem.getSystem();
        audio.getEar().trackOrientation(cam);
        audio.getEar().trackPosition(cam);
        preloadSFX();
    }
    public static void playSFX(SoundResourcePath resource){
        SFX[resource.getId()].play();
    }
    private static AudioTrack getSFX(SoundResourcePath resource) {
        // Create a non-streaming, looping, positional sound clip.
        AudioTrack sound = audio.createAudioTrack(resource.toURL(), false);
        System.out.println(sound);
        sound.setType(TrackType.HEADSPACE);
        sound.setRelative(false);
        sound.setLooping(false);
        return sound;
    }
}



so it will not only preload ALL sounds on your game at startup, but also it will let you play ANY of then with simply one line:

SoundManager.playSFX(SoundResourcePath.Whateversoundyouwish);

is it a good idea or i waste memory/cpu or whatever?

Its always a good idea to cache resources. Its very likely that the same resource will be requested more than once during the life-time of an application, and going to the hard-drive on every request is much more costly than reading from memory.

Looking at your code, I think that some parts can be improved. First of all, you really don't need to have an enum for every resource path that your application is going to use… You can just use a Map<String, Object> to map resource names into their data. With the jME class ResourceLocatorTool, you can locate resources in predefined paths, by providing a resource name, which will give you the URL (the path to the resource) which you use to load it. This way of doing it keeps all resources in memory. A more efficent way of doing this is to dynamically load/release resources, it's more complex… You have to load a resource on demand, track it's usage by the application, and if it has not been used for a long time, you unload it from memory.

seens complicated and confuse, gonna try one day!



well, now that you say that, if my game have X levels, and each uses Y resources that may repeat, loading then all is not nessesssary, but garantees that they will be there. i wish i knew how to use Maps, gonna check on google one day too.