Deferred Resource Loading
Slick is implicitly single threaded. The game loop is written around the concept that there is only a single thread and hence no need to worry about synchronization. One of the areas that this falls down is when loading a large amount of resources. This can cause a blank screen to be displayed at start up while the single thread loads all the resource before feeding back that the game is starting to the user. One option would be to allow another thread to be running in the background to load resources - however, this is technically annoying to do while maintaining a simple API and code base.
Slick provides a way to get this loading bar style initialization - called deferred loading. When deferred loading is enabled all the calls to load resources (images, sounds, music, fonts etc) are wrapped in the library to load only the explicit data required for the resource immediately. Each resource handle that is returned is then placed in the global LoadingList. As each part of your game requests resources, this list builds up to be a global set of resource handles for everything in the game.
Once initialization is complete, we can then simply cycle through the loading list loading each resource. However, we can do this in a controller manner - load one resource, update the screen, load the next resource, update the screen. No one resource should take so long to load that it keeps the screen from refreshing for a significant amount of time (if it does, then the resource should probably be streamed anyway :)).
The DeferredLoadingTest should give you a clear view of how this intended to be used. Essentially it works like so:
public void render(GameContainer container, Graphics g) { g.drawString("Loaded: "+lastLoaded, 100, 100); } public void update(GameContainer container, int delta) throws SlickException { if (LoadingList.get().getRemainingResources() > 0) { DeferredResource nextResource = LoadingList.get().getNext(); nextResource.load(); lastLoaded = nextResource.getDescription(); } else { // loading is complete, do normal update here } }
While this solution isn't perfect in practice it works for most situations, while keeping the implementation and API simple.