Clear the pony cache alongside the skin cache, and fixed windows appearing behind the client

This commit is contained in:
Sollace 2018-06-03 11:57:22 +02:00
parent 5178b8f40d
commit 28274b76fd
8 changed files with 125 additions and 22 deletions

View file

@ -45,6 +45,8 @@ import java.util.UUID;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -62,6 +64,8 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
private boolean enabled = true; private boolean enabled = true;
private List<ISkinCacheClearListener> clearListeners = Lists.newArrayList();
private List<SkinServer> skinServers = Lists.newArrayList(); private List<SkinServer> skinServers = Lists.newArrayList();
private Map<UUID, Map<Type, ResourceLocation>> skinCache = Maps.newHashMap(); private Map<UUID, Map<Type, ResourceLocation>> skinCache = Maps.newHashMap();
@ -223,6 +227,10 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
} }
public void addClearListener(ISkinCacheClearListener listener) {
clearListeners.add(listener);
}
public static void clearSkinCache() { public static void clearSkinCache() {
LiteLoaderLogger.info("Clearing local player skin cache"); LiteLoaderLogger.info("Clearing local player skin cache");
@ -238,6 +246,19 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
var1.printStackTrace(); var1.printStackTrace();
} }
INSTANCE.clearListeners = INSTANCE.clearListeners.stream()
.filter(HDSkinManager::onSkinCacheCleared)
.collect(Collectors.toList());
}
private static boolean onSkinCacheCleared(ISkinCacheClearListener callback) {
try {
return callback.onSkinCacheCleared();
} catch (Exception e) {
LiteLoaderLogger.warning("Exception ancountered calling skin listener '{}'. It will be removed.", callback.getClass().getName());
e.printStackTrace();
return false;
}
} }
public void addSkinModifier(ISkinModifier modifier) { public void addSkinModifier(ISkinModifier modifier) {

View file

@ -0,0 +1,6 @@
package com.voxelmodpack.hdskins;
@FunctionalInterface
public interface ISkinCacheClearListener {
boolean onSkinCacheCleared();
}

View file

@ -0,0 +1,27 @@
package com.voxelmodpack.hdskins;
public final class Later extends Thread {
private final int delay;
protected Later(int delay, Runnable runnable) {
super(runnable);
this.delay = delay;
}
public static void performLater(int delay, Runnable callable) {
new Later(delay, callable).start();
}
public static void performNow(Runnable callable) {
new Later(0, callable).start();
}
@Override
public void run() {
try {
if (delay > 0) sleep(delay);
} catch (InterruptedException e) {}
super.run();
}
}

View file

@ -10,6 +10,7 @@ import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture; import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mumfrey.liteloader.util.log.LiteLoaderLogger; import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.HDSkinManager;
import com.voxelmodpack.hdskins.Later;
import com.voxelmodpack.hdskins.skins.SkinUploadResponse; import com.voxelmodpack.hdskins.skins.SkinUploadResponse;
import com.voxelmodpack.hdskins.upload.awt.ThreadOpenFilePNG; import com.voxelmodpack.hdskins.upload.awt.ThreadOpenFilePNG;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -34,6 +35,7 @@ import net.minecraft.util.text.TextFormatting;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU; import org.lwjgl.util.glu.GLU;
@ -88,7 +90,8 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
private File selectedSkin; private File selectedSkin;
private float uploadOpacity = 0.0F; private float uploadOpacity = 0.0F;
private float lastPartialTick; private float lastPartialTick;
private JFrame fileDrop;
private static JFrame fileDrop;
private MinecraftProfileTexture.Type textureType = SKIN; private MinecraftProfileTexture.Type textureType = SKIN;
@ -170,7 +173,8 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
@Override @Override
public void initGui() { public void initGui() {
enableDnd(); Later.performLater(1, this::enableDnd);
this.initPanoramaRenderer(); this.initPanoramaRenderer();
this.buttonList.clear(); this.buttonList.clear();
this.buttonList.add(this.btnBrowse = new GuiButton(0, 30, this.height - 36, 60, 20, "Browse...")); this.buttonList.add(this.btnBrowse = new GuiButton(0, 30, this.height - 36, 60, 20, "Browse..."));
@ -191,16 +195,21 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
private void enableDnd() { private void enableDnd() {
if (fileDrop != null) { if (fileDrop != null) {
fileDrop.setVisible(true); fileDrop.setVisible(true);
fileDrop.requestFocusInWindow();
fileDrop.setLocation(Display.getX(), Display.getY());
return; return;
} }
fileDrop = new JFrame("Skin Drop"); fileDrop = new JFrame("Skin Drop");
fileDrop.setType(Type.UTILITY); fileDrop.setType(Type.UTILITY);
fileDrop.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); fileDrop.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
fileDrop.setResizable(false); fileDrop.setResizable(false);
fileDrop.setTitle("Skin Drop"); fileDrop.setTitle("Skin Drop");
fileDrop.setSize(256, 256); fileDrop.setSize(256, 256);
// fileDrop.setAlwaysOnTop(true); fileDrop.setAlwaysOnTop(true);
fileDrop.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
fileDrop.setLocation(Display.getX(), Display.getY());
fileDrop.getContentPane().setLayout(null); fileDrop.getContentPane().setLayout(null);
JPanel panel = new JPanel(); JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.GRAY)); panel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.GRAY));
panel.setBounds(10, 11, 230, 205); panel.setBounds(10, 11, 230, 205);
@ -215,6 +224,7 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
try { try {
dt.addDropTargetListener((FileDropListener) files -> files.stream().findFirst().ifPresent(this::loadLocalFile)); dt.addDropTargetListener((FileDropListener) files -> files.stream().findFirst().ifPresent(this::loadLocalFile));
fileDrop.setVisible(true); fileDrop.setVisible(true);
fileDrop.requestFocusInWindow();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -227,10 +237,16 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
@Override @Override
public void onGuiClosed() { public void onGuiClosed() {
super.onGuiClosed(); super.onGuiClosed();
if (this.fileDrop != null) Later.performLater(1, () -> {
this.fileDrop.dispose(); if (!(Minecraft.getMinecraft().currentScreen instanceof GuiSkins)) {
this.localPlayer.releaseTextures(); if (fileDrop != null) {
this.remotePlayer.releaseTextures(); fileDrop.setVisible(false);
}
GuiSkins.this.localPlayer.releaseTextures();
GuiSkins.this.remotePlayer.releaseTextures();
HDSkinManager.clearSkinCache();
}
});
} }
private void onFileOpenDialogClosed(JFileChooser fileDialog, int dialogResult) { private void onFileOpenDialogClosed(JFileChooser fileDialog, int dialogResult) {
@ -283,7 +299,7 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
this.selectedSkin = null; this.selectedSkin = null;
this.localPlayer.releaseTextures(); this.localPlayer.releaseTextures();
this.openFileThread = new ThreadOpenFilePNG(this.mc, I18n.format("hdskins.open.title"), this::onFileOpenDialogClosed); this.openFileThread = new ThreadOpenFilePNG(this.mc, I18n.format("hdskins.open.title"), this::onFileOpenDialogClosed);
this.openFileThread.start(); this.openFileThread.setParent(fileDrop).start();
guiButton.enabled = false; guiButton.enabled = false;
} }

View file

@ -2,9 +2,17 @@ package com.voxelmodpack.hdskins.upload.awt;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import java.awt.AWTEvent;
import java.awt.event.MouseEvent;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileFilter;
import org.lwjgl.opengl.Display;
import com.voxelmodpack.hdskins.Later;
/** /**
* Base class for "open file" dialog threads * Base class for "open file" dialog threads
* *
@ -19,6 +27,10 @@ public abstract class ThreadOpenFile extends Thread {
*/ */
protected final IOpenFileCallback parentScreen; protected final IOpenFileCallback parentScreen;
private JFileChooser fileDialog;
private JFrame parent = null;
protected ThreadOpenFile(Minecraft minecraft, String dialogTitle, IOpenFileCallback callback) protected ThreadOpenFile(Minecraft minecraft, String dialogTitle, IOpenFileCallback callback)
throws IllegalStateException { throws IllegalStateException {
if (minecraft.isFullScreen()) { if (minecraft.isFullScreen()) {
@ -29,14 +41,35 @@ public abstract class ThreadOpenFile extends Thread {
this.dialogTitle = dialogTitle; this.dialogTitle = dialogTitle;
} }
@Override
public void start() {
Later.performLater(0, this);
}
public ThreadOpenFile setParent(JFrame parent) {
this.parent = parent;
this.parent.setAlwaysOnTop(true);
return this;
}
@Override @Override
public void run() { public void run() {
JFileChooser fileDialog = new JFileChooser(); if (parent == null) {
parent = new JFrame("InternalDialog");
parent.setAlwaysOnTop(true);
}
parent.requestFocusInWindow();
parent.setVisible(false);
fileDialog = new JFileChooser();
fileDialog.setDialogTitle(this.dialogTitle); fileDialog.setDialogTitle(this.dialogTitle);
fileDialog.setFileFilter(this.getFileFilter()); fileDialog.setFileFilter(this.getFileFilter());
int dialogResult = fileDialog.showOpenDialog(null); int dialogResult = fileDialog.showOpenDialog(parent);
parent.setVisible(true);
this.parentScreen.onFileOpenDialogClosed(fileDialog, dialogResult); this.parentScreen.onFileOpenDialogClosed(fileDialog, dialogResult);
} }

View file

@ -46,6 +46,7 @@ public class MineLittlePony {
config = new PonyConfig(); config = new PonyConfig();
ponyManager = new PonyManager(config); ponyManager = new PonyManager(config);
renderManager = new PonyRenderManager(); renderManager = new PonyRenderManager();
LiteLoader.getInstance().registerExposable(config, null); LiteLoader.getInstance().registerExposable(config, null);
@ -70,6 +71,7 @@ public class MineLittlePony {
// manager.setGatewayURL(GATEWAY_URL); // manager.setGatewayURL(GATEWAY_URL);
manager.addSkinModifier(new PonySkinModifier()); manager.addSkinModifier(new PonySkinModifier());
// logger.info("Set MineLP skin server URL."); // logger.info("Set MineLP skin server URL.");
manager.addClearListener(ponyManager);
RenderManager rm = minecraft.getRenderManager(); RenderManager rm = minecraft.getRenderManager();
renderManager.initialisePlayerRenderers(rm); renderManager.initialisePlayerRenderers(rm);

View file

@ -7,6 +7,7 @@ import com.google.gson.JsonParseException;
import com.minelittlepony.model.PMAPI; import com.minelittlepony.model.PMAPI;
import com.minelittlepony.pony.data.Pony; import com.minelittlepony.pony.data.Pony;
import com.minelittlepony.pony.data.PonyLevel; import com.minelittlepony.pony.data.PonyLevel;
import com.voxelmodpack.hdskins.ISkinCacheClearListener;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.client.entity.AbstractClientPlayer;
@ -29,7 +30,7 @@ import java.util.stream.Collectors;
* The PonyManager is responsible for reading and recoding all the pony data associated with an entity of skin. * The PonyManager is responsible for reading and recoding all the pony data associated with an entity of skin.
* *
*/ */
public class PonyManager implements IResourceManagerReloadListener { public class PonyManager implements IResourceManagerReloadListener, ISkinCacheClearListener {
public static final ResourceLocation STEVE = new ResourceLocation("minelittlepony", "textures/entity/steve_pony.png"); public static final ResourceLocation STEVE = new ResourceLocation("minelittlepony", "textures/entity/steve_pony.png");
public static final ResourceLocation ALEX = new ResourceLocation("minelittlepony", "textures/entity/alex_pony.png"); public static final ResourceLocation ALEX = new ResourceLocation("minelittlepony", "textures/entity/alex_pony.png");
@ -45,7 +46,6 @@ public class PonyManager implements IResourceManagerReloadListener {
private PonyConfig config; private PonyConfig config;
private Map<ResourceLocation, Pony> poniesCache = Maps.newHashMap(); private Map<ResourceLocation, Pony> poniesCache = Maps.newHashMap();
private Map<ResourceLocation, Pony> backgroudPoniesCache = Maps.newHashMap();
public PonyManager(PonyConfig config) { public PonyManager(PonyConfig config) {
this.config = config; this.config = config;
@ -149,7 +149,6 @@ public class PonyManager implements IResourceManagerReloadListener {
@Override @Override
public void onResourceManagerReload(IResourceManager resourceManager) { public void onResourceManagerReload(IResourceManager resourceManager) {
poniesCache.clear(); poniesCache.clear();
backgroudPoniesCache.clear();
backgroundPonyList.clear(); backgroundPonyList.clear();
try { try {
for (IResource res : resourceManager.getAllResources(BGPONIES_JSON)) { for (IResource res : resourceManager.getAllResources(BGPONIES_JSON)) {
@ -202,4 +201,11 @@ public class PonyManager implements IResourceManagerReloadListener {
return ponies.stream().map(this::apply).collect(Collectors.toList()); return ponies.stream().map(this::apply).collect(Collectors.toList());
} }
} }
@Override
public boolean onSkinCacheCleared() {
MineLittlePony.logger.info("Flushed {} cached ponies.", poniesCache.size());
poniesCache.clear();
return true;
}
} }

View file

@ -40,12 +40,4 @@ public class GuiSkinsMineLP extends GuiSkins {
ponyManager.removePony(resource); ponyManager.removePony(resource);
} }
} }
@Override
public void onGuiClosed() {
super.onGuiClosed();
ponyManager.removePony(localPlayer.getSkinTexture());
ponyManager.removePony(remotePlayer.getSkinTexture());
}
} }