Fixed some serious memory issues with the Replay Manager, which now only loads the required thumbnails.

This commit is contained in:
Marius Metzger
2015-02-02 13:41:39 +01:00
parent 5261536bec
commit 0fc9662449
6 changed files with 84 additions and 56 deletions

View File

@@ -1,22 +1,21 @@
package eu.crushedpixel.replaymod.gui.replaymanager;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import javax.imageio.ImageIO;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiListExtended.IGuiListEntry;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.util.ResourceLocation;
import eu.crushedpixel.replaymod.recording.ReplayMetaData;
@@ -29,9 +28,10 @@ public class GuiReplayListEntry implements IGuiListEntry {
private ReplayMetaData metaData;
private String fileName;
private final ResourceLocation textureResource;
private ResourceLocation textureResource;
private DynamicTexture dynTex = null;
private File imageFile;
private BufferedImage image = null;
public ReplayMetaData getMetaData() {
@@ -52,46 +52,60 @@ public class GuiReplayListEntry implements IGuiListEntry {
private GuiReplayListExtended parent;
public GuiReplayListEntry(GuiReplayListExtended parent, String fileName, ReplayMetaData metaData, BufferedImage image) {
public GuiReplayListEntry(GuiReplayListExtended parent, String fileName, ReplayMetaData metaData, File imageFile) {
this.metaData = metaData;
this.fileName = fileName;
this.parent = parent;
this.textureResource = new ResourceLocation("thumbs/"+fileName);
dynTex = null;
this.image = image;
this.imageFile = imageFile;
}
boolean registered = false;
@Override
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected) {
minecraft.fontRendererObj.drawString(fileName, x + 3, y + 1, 16777215);
try {
minecraft.fontRendererObj.drawString(fileName, x + 3, y + 1, 16777215);
if(y < -slotHeight || y > parent.height) {
if(registered) {
registered = false;
ResourceHelper.freeResource(textureResource);
textureResource = null;
image = null;
dynTex = null;
}
return;
} else {
if(!registered) {
textureResource = new ResourceLocation("thumbs/"+fileName);
image = ImageIO.read(imageFile);
dynTex = new DynamicTexture(image);
minecraft.getTextureManager().loadTexture(textureResource, dynTex);
dynTex.updateDynamicTexture();
ResourceHelper.registerResource(textureResource);
registered = true;
}
//Draw thumbnail
if(image != null) {
if(dynTex == null) {
dynTex = new DynamicTexture(image);
minecraft.getTextureManager().loadTexture(textureResource, dynTex);
dynTex.updateDynamicTexture();
ResourceHelper.registerResource(textureResource);
}
minecraft.getTextureManager().bindTexture(textureResource); //Will be freed by the ResourceHelper
Gui.drawScaledCustomSizeModalRect(x-60, y, 0, 0, 1280, 720, 57, 32, 1280, 720);
minecraft.getTextureManager().bindTexture(textureResource);
Gui.drawScaledCustomSizeModalRect(x-60, y, 0, 0, 1280, 720, 57, 32, 1280, 720);
}
List<String> list = new ArrayList<String>();
list.add(metaData.getServerName()+" ("+dateFormat.format(new Date(metaData.getDate()))+")");
list.add(String.format("%02dm%02ds",
TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration()),
TimeUnit.MILLISECONDS.toSeconds(metaData.getDuration()) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration()))
));
for (int l1 = 0; l1 < Math.min(list.size(), 2); ++l1) {
minecraft.fontRendererObj.drawString((String)list.get(l1), x + 3, y + 12 + minecraft.fontRendererObj.FONT_HEIGHT * l1, 8421504);
}
} catch(Exception e) {
e.printStackTrace();
}
List<String> list = new ArrayList<String>();
list.add(metaData.getServerName()+" ("+dateFormat.format(new Date(metaData.getDate()))+")");
list.add(String.format("%02dm%02ds",
TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration()),
TimeUnit.MILLISECONDS.toSeconds(metaData.getDuration()) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration()))
));
for (int l1 = 0; l1 < Math.min(list.size(), 2); ++l1) {
minecraft.fontRendererObj.drawString((String)list.get(l1), x + 3, y + 12 + minecraft.fontRendererObj.FONT_HEIGHT * l1, 8421504);
}
}
@Override

View File

@@ -1,20 +1,19 @@
package eu.crushedpixel.replaymod.gui.replaymanager;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiListExtended;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.util.MathHelper;
import org.lwjgl.input.Mouse;
import eu.crushedpixel.replaymod.recording.ReplayMetaData;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiListExtended;
import net.minecraft.client.gui.ServerListEntryLanScan;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.resources.ResourcePackListEntry;
import net.minecraft.util.MathHelper;
public class GuiReplayListExtended extends GuiListExtended {
@@ -90,7 +89,7 @@ public class GuiReplayListExtended extends GuiListExtended {
entries = new ArrayList<GuiReplayListEntry>();
}
public void addEntry(String fileName, ReplayMetaData metaData, BufferedImage image) {
public void addEntry(String fileName, ReplayMetaData metaData, File image) {
entries.add(new GuiReplayListEntry(this, fileName, metaData, image));
}

View File

@@ -55,7 +55,7 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback {
private String hoveringText;
private boolean initialized;
private GuiReplayListExtended replayGuiList;
private List<Pair<Pair<File, ReplayMetaData>, BufferedImage>> replayFileList = new ArrayList<Pair<Pair<File, ReplayMetaData>, BufferedImage>>();
private List<Pair<Pair<File, ReplayMetaData>, File>> replayFileList = new ArrayList<Pair<Pair<File, ReplayMetaData>, File>>();
private GuiButton loadButton, uploadButton, folderButton, renameButton, deleteButton, cancelButton, settingsButton;
private static Gson gson = new Gson();
@@ -73,7 +73,7 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback {
private void reloadFiles() {
replayGuiList.clearEntries();
replayFileList = new ArrayList<Pair<Pair<File, ReplayMetaData>, BufferedImage>>();
replayFileList = new ArrayList<Pair<Pair<File, ReplayMetaData>, File>>();
File folder = new File("./replay_recordings/");
folder.mkdirs();
@@ -100,6 +100,11 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback {
if(img == null) {
img = ImageIO.read(MCPNames.class.getClassLoader().getResourceAsStream("default_thumb.jpg"));
}
File tmp = File.createTempFile(FilenameUtils.getBaseName(file.getAbsolutePath()), "jpg");
tmp.deleteOnExit();
ImageIO.write(img, "jpg", tmp);
InputStream is = archive.getInputStream(metadata);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
@@ -108,7 +113,7 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback {
ReplayMetaData metaData = gson.fromJson(json, ReplayMetaData.class);
replayFileList.add(Pair.of(Pair.of(file, metaData), img));
replayFileList.add(Pair.of(Pair.of(file, metaData), tmp));
archive.close();
} catch(Exception e) {
@@ -119,15 +124,15 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback {
Collections.sort(replayFileList, new FileAgeComparator());
for(Pair<Pair<File, ReplayMetaData>, BufferedImage> p : replayFileList) {
for(Pair<Pair<File, ReplayMetaData>, File> p : replayFileList) {
replayGuiList.addEntry(FilenameUtils.getBaseName(p.first().first().getName()), p.first().second(), p.second());
}
}
public class FileAgeComparator implements Comparator<Pair<Pair<File, ReplayMetaData>, BufferedImage>> {
public class FileAgeComparator implements Comparator<Pair<Pair<File, ReplayMetaData>, File>> {
@Override
public int compare(Pair<Pair<File, ReplayMetaData>, BufferedImage> o1, Pair<Pair<File, ReplayMetaData>, BufferedImage> o2) {
public int compare(Pair<Pair<File, ReplayMetaData>, File> o1, Pair<Pair<File, ReplayMetaData>, File> o2) {
try {
return (int)(new Date(o2.first().second().getDate()).compareTo(new Date(o1.first().second().getDate())));
} catch(Exception e) {

View File

@@ -14,7 +14,12 @@ public class ResourceHelper {
openResources.add(loc);
}
public static void freeResources() {
public static void freeResource(ResourceLocation loc) {
Minecraft.getMinecraft().getTextureManager().deleteTexture(loc);
openResources.remove(loc);
}
public static void freeAllResources() {
for(ResourceLocation loc : openResources) {
Minecraft.getMinecraft().getTextureManager().deleteTexture(loc);
}