ResourceLocator

Recently checked into CVS are new utility classes, providing a system that allows you to register special locators to look for specific resource types.  There are two implemented locator types and you can write your own if you need additional functionality.


  1. SimpleResourceLocator - basically, you give it a URI or URL where you want it to look for things, then register it with the ResourceLocatorTool class.
  2. MultiFormatResourceLocator - similar to the simple one, but you can also give it a series of possible extensions.  It will then try to find the file using the different file extensions supplied, in the order supplied.  (It will also look using the original extension in the filename if you give it one, and you can specify whether that should be done first or after you've exhausted the extensions list.)



    So here's an example:


    try {
        MultiFormatResourceLocator loc2 = new MultiFormatResourceLocator(ResourceLocatorTool.class.getResource("/jmetest/data/images/"), ".jpg", ".png", ".tga");
        ResourceLocatorTool.addResourceLocator(ResourceLocatorTool.TYPE_TEXTURE, loc2);
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
   
    URL u = ResourceLocatorTool.locateResource(ResourceLocatorTool.TYPE_TEXTURE, "/model/FieldstoneSpec.gif");
    System.out.println("FOUND URL: "+u);



This prints:

FOUND URL: file:/C:/data/blight/dev/jslack/extern/java/jme/build/jmetest/data/images/FieldstoneSpec.png



It found this file by chopping /model/FieldstoneSpec.gif down, directory by directory and appending it to the baseURL setup in the supplied ResourceLocator.  You'll note that we do not have a FieldstoneSpec.gif in our source tree, but it found the .png version because we supplied that as a possiblity to the locator.  (Note: this extension swapping can save you time in certain circumstances... for example when you are developing and you want to be able to drop in dds versions of your textures without going back and resaving all of your models with the changed texture name.)

You can have as many ResourceLocators registered per resource type as you like.  It will go through them in the order you add them and stop when it finds the first openable file.  If no hits are found, or you do not have locators registered for the given resource type, it will return ResourceLocatorTool.class.getResource(resourceName) as a last resort.

As you might suspect, the RLT can be used in other places in the code besides textures as well.  Using it throughout your code can also allow you to repoint your asset directories very simply without having to recompile or alter your asset files.

Currently the RLT is used by the model loaders and TextureManager methods that accept a String for the texture file name.  It is also used by the AudioSystem in com.jmex.audio if you load a track using a string filename.  Other uses will be added later.

A note about the Simple and MultiFormat locators…  They use URIs to resolve your resources.  Thus, when you register a path, please make sure you have a trailing slash on your directory path so that the resolve will work the way you expect it to.

It works like a charm, glad the old texture location handling is gone!  8)