Only load image resources when needed.

- Stop loading all images on startup.
- Game images are preloaded before the song starts.
- Destroy skin images immediately after finishing a beatmap, potentially saving lots of memory.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2015-01-14 23:10:19 -05:00
parent 05a671e627
commit 64d961a8f9
4 changed files with 56 additions and 15 deletions

View File

@ -313,6 +313,11 @@ public enum GameImage {
*/
private static int containerWidth, containerHeight;
/**
* Whether a skin image has been loaded.
*/
private static boolean skinImageLoaded = false;
/**
* Initializes the GameImage class with container dimensions.
* @param width the container width
@ -323,6 +328,19 @@ public enum GameImage {
containerHeight = height;
}
/**
* Destroys all skin images, if any have been loaded.
*/
public static void destroySkinImages() {
if (skinImageLoaded) {
for (GameImage img : GameImage.values()) {
if (img.isGameImage())
img.destroySkinImage();
}
skinImageLoaded = false;
}
}
/**
* Constructor.
* @param filename the image file name
@ -353,6 +371,8 @@ public enum GameImage {
* The skin image takes priority over the default image.
*/
public Image getImage() {
if (defaultImage == null)
setDefaultImage();
return (skinImage != null) ? skinImage : defaultImage;
}
@ -369,13 +389,14 @@ public enum GameImage {
/**
* Sets the default image for this resource.
* If the default image has already been loaded, this will do nothing.
*/
public void setDefaultImage() {
if (defaultImage != null)
return;
try {
if (defaultImage != null && !defaultImage.isDestroyed())
defaultImage.destroy();
defaultImage = new Image(filename);
process();
} catch (SlickException e) {
Log.error(String.format("Failed to set default image '%s'.", filename), e);
}
@ -387,15 +408,19 @@ public enum GameImage {
* @return true if a new skin image is loaded, false otherwise
*/
public boolean setSkinImage(File dir) {
try {
// destroy the existing image, if any
if (skinImage != null && !skinImage.isDestroyed())
skinImage.destroy();
if (dir == null)
return false;
// destroy the existing image, if any
destroySkinImage();
try {
// set a new image
File file = new File(dir, filename);
if (file.isFile() && !Options.isBeatmapSkinIgnored()) {
skinImage = new Image(file.getAbsolutePath());
process();
skinImageLoaded = true;
return true;
} else {
skinImage = null;
@ -407,6 +432,21 @@ public enum GameImage {
}
}
/**
* Destroys the associated skin image, if any.
*/
private void destroySkinImage() {
if (skinImage == null)
return;
try {
if (!skinImage.isDestroyed())
skinImage.destroy();
skinImage = null;
} catch (SlickException e) {
Log.error(String.format("Failed to destroy skin image for '%s'.", this.name()), e);
}
}
/**
* Sub-method for image processing actions (via an override).
* @param img the image to process
@ -421,7 +461,7 @@ public enum GameImage {
/**
* Performs individual post-loading actions on the image.
*/
public void process() {
private void process() {
setImage(process_sub(getImage(), containerWidth, containerHeight));
}
}

View File

@ -184,12 +184,8 @@ public class Utils {
Log.error("Failed to load fonts.", e);
}
// set default game images
// initialize game images
GameImage.init(width, height);
for (GameImage img : GameImage.values()) {
img.setDefaultImage();
img.process();
}
// initialize game mods
for (GameMod mod : GameMod.values())

View File

@ -859,8 +859,10 @@ public class Game extends BasicGameState {
// set images
File parent = osu.getFile().getParentFile();
for (GameImage img : GameImage.values()) {
if (img.isGameImage() && img.setSkinImage(parent))
img.process();
if (img.isGameImage()) {
img.setDefaultImage(); // ensure that default image has been loaded
img.setSkinImage(parent);
}
}
// skip button

View File

@ -581,6 +581,9 @@ public class SongMenu extends BasicGameState {
// stop playing the theme song
if (MusicController.isThemePlaying() && focusNode != null)
MusicController.play(focusNode.osuFiles.get(focusNode.osuFileIndex), true);
// destroy skin images, if any
GameImage.destroySkinImages();
}
@Override