mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2024-11-25 13:57:59 +01:00
Use a crash callable instead of a mixin for GLWindow
This commit is contained in:
parent
c841abe4dc
commit
09e4d5de79
5 changed files with 40 additions and 92 deletions
|
@ -9,6 +9,8 @@ import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.resources.IReloadableResourceManager;
|
import net.minecraft.client.resources.IReloadableResourceManager;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.fml.client.registry.RenderingRegistry;
|
import net.minecraftforge.fml.client.registry.RenderingRegistry;
|
||||||
|
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||||
|
import net.minecraftforge.fml.common.ICrashCallable;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
@ -53,7 +55,20 @@ public class HDSkins {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GLWindow.current();
|
// Create a bogus crash callable so we can properly close the window in case of a crash.
|
||||||
|
FMLCommonHandler.instance().registerCrashCallable(new ICrashCallable() {
|
||||||
|
@Override
|
||||||
|
public String getLabel() {
|
||||||
|
return "HDSkins";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String call() {
|
||||||
|
GLWindow.dispose();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean fullscreen;
|
private boolean fullscreen;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.voxelmodpack.hdskins.gui;
|
package com.voxelmodpack.hdskins.gui;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.resources.DefaultResourcePack;
|
import net.minecraft.client.resources.DefaultResourcePack;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
@ -24,7 +23,6 @@ import javax.swing.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Experimental window to control file drop. It kind of sucks.
|
* Experimental window to control file drop. It kind of sucks.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class GLWindow extends DropTarget {
|
public class GLWindow extends DropTarget {
|
||||||
|
|
||||||
|
@ -60,7 +58,7 @@ public class GLWindow extends DropTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getScaledPixelUnit(int i) {
|
private static int getScaledPixelUnit(int i) {
|
||||||
return (int)Math.floor(i * Display.getPixelScaleFactor());
|
return (int) Math.floor(i * Display.getPixelScaleFactor());
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Minecraft mc = Minecraft.getMinecraft();
|
private final Minecraft mc = Minecraft.getMinecraft();
|
||||||
|
@ -74,6 +72,8 @@ public class GLWindow extends DropTarget {
|
||||||
|
|
||||||
private boolean isFullscreen;
|
private boolean isFullscreen;
|
||||||
|
|
||||||
|
private boolean open;
|
||||||
|
|
||||||
private GLWindow() {
|
private GLWindow() {
|
||||||
try {
|
try {
|
||||||
open();
|
open();
|
||||||
|
@ -95,12 +95,16 @@ public class GLWindow extends DropTarget {
|
||||||
canvas = new Canvas();
|
canvas = new Canvas();
|
||||||
|
|
||||||
frame = new JFrame(Display.getTitle());
|
frame = new JFrame(Display.getTitle());
|
||||||
frame.add(canvas);
|
frame.getContentPane().add(canvas);
|
||||||
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||||
frame.addWindowListener(new WindowAdapter() {
|
frame.addWindowListener(new WindowAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void windowClosed(WindowEvent windowEvent) {
|
public void windowClosed(WindowEvent windowEvent) {
|
||||||
mc.shutdown();
|
// If we don't check this, exiting the skins menu
|
||||||
|
// will shutdown minecraft.
|
||||||
|
if (open) {
|
||||||
|
mc.shutdown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -116,7 +120,7 @@ public class GLWindow extends DropTarget {
|
||||||
float frameFactorX = frame.getWidth() - frame.getContentPane().getWidth();
|
float frameFactorX = frame.getWidth() - frame.getContentPane().getWidth();
|
||||||
float frameFactorY = frame.getHeight() - frame.getContentPane().getHeight();
|
float frameFactorY = frame.getHeight() - frame.getContentPane().getHeight();
|
||||||
|
|
||||||
frame.setSize((int)Math.floor(w + frameFactorX), (int)Math.floor(h + frameFactorY));
|
frame.setSize((int) Math.floor(w + frameFactorX), (int) Math.floor(h + frameFactorY));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
frame.addComponentListener(new ComponentAdapter() {
|
frame.addComponentListener(new ComponentAdapter() {
|
||||||
|
@ -139,9 +143,13 @@ public class GLWindow extends DropTarget {
|
||||||
|
|
||||||
Display.setParent(canvas);
|
Display.setParent(canvas);
|
||||||
Display.setFullscreen(isFullscreen);
|
Display.setFullscreen(isFullscreen);
|
||||||
|
|
||||||
|
open = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void close() {
|
private void close() {
|
||||||
|
open = false;
|
||||||
|
clearDropTargetListener();
|
||||||
try {
|
try {
|
||||||
Display.setParent(null);
|
Display.setParent(null);
|
||||||
} catch (LWJGLException e) {
|
} catch (LWJGLException e) {
|
||||||
|
@ -197,7 +205,9 @@ public class GLWindow extends DropTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onRefresh(boolean fullscreen) {
|
private void onRefresh(boolean fullscreen) {
|
||||||
if (fullscreen != isFullscreen) {
|
if (fullscreen) {
|
||||||
|
close();
|
||||||
|
} else if (open) {
|
||||||
// Repaint the canvas, not the window.
|
// Repaint the canvas, not the window.
|
||||||
// The former strips the window of its state. The latter fixes a viewport scaling bug.
|
// The former strips the window of its state. The latter fixes a viewport scaling bug.
|
||||||
canvas.setBounds(0, 0, 0, 0);
|
canvas.setBounds(0, 0, 0, 0);
|
||||||
|
@ -206,7 +216,7 @@ public class GLWindow extends DropTarget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearDropTargetListener() {
|
private void clearDropTargetListener() {
|
||||||
if (dropListener != null) {
|
if (dropListener != null) {
|
||||||
removeDropTargetListener(dropListener);
|
removeDropTargetListener(dropListener);
|
||||||
dropListener = null;
|
dropListener = null;
|
||||||
|
|
|
@ -194,9 +194,11 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enableDnd() {
|
private void enableDnd() {
|
||||||
GLWindow.current().setDropTargetListener((FileDropListener) files -> {
|
if (!mc.isFullScreen()) {
|
||||||
files.stream().findFirst().ifPresent(instance::loadLocalFile);
|
GLWindow.current().setDropTargetListener((FileDropListener) files -> {
|
||||||
});
|
files.stream().findFirst().ifPresent(instance::loadLocalFile);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initPanoramaRenderer() {
|
private void initPanoramaRenderer() {
|
||||||
|
@ -210,7 +212,7 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
|
||||||
remotePlayer.releaseTextures();
|
remotePlayer.releaseTextures();
|
||||||
HDSkinManager.clearSkinCache();
|
HDSkinManager.clearSkinCache();
|
||||||
|
|
||||||
GLWindow.current().clearDropTargetListener();
|
GLWindow.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onFileOpenDialogClosed(JFileChooser fileDialog, int dialogResult) {
|
private void onFileOpenDialogClosed(JFileChooser fileDialog, int dialogResult) {
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
package com.voxelmodpack.hdskins.mixin;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import com.voxelmodpack.hdskins.gui.GLWindow;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.crash.CrashReport;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mixin required to close the window after the game detects a crash.
|
|
||||||
*
|
|
||||||
* DO NOT REMOVE
|
|
||||||
*
|
|
||||||
* That means you, Killjoy.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Mixin(Minecraft.class)
|
|
||||||
public abstract class MixinMinecraft {
|
|
||||||
//
|
|
||||||
// Due to how JFrame works the only way to know for sure when the game hash crashed
|
|
||||||
// is to have it call us explicitly.
|
|
||||||
//
|
|
||||||
// ShutdownListener.onShutDown is unlikely to be called as it depends on the
|
|
||||||
// Minecraft.running flag to be unset, which is unlikely to happen if the game crashes.
|
|
||||||
//
|
|
||||||
// Runtime.current().addShutdownHook won't be called it waits for all
|
|
||||||
// non-daemon threads to end, one of which is depending on the JFrame being
|
|
||||||
// disposed to tell it when to end.
|
|
||||||
//
|
|
||||||
// If you're thinking 'hey, what about Minecraft.isCrashed?'
|
|
||||||
// No, that's only set if the internal MinecraftServer crashes.
|
|
||||||
// Otherwise the value is always false and threads spinning to check any such value
|
|
||||||
// will only serve to hang up the VM.
|
|
||||||
//
|
|
||||||
// But senpai, what about a warden thread joined on the main? I'm sure as soon as
|
|
||||||
// the main thread closes that would-
|
|
||||||
//
|
|
||||||
// Nope. It never runs.
|
|
||||||
//
|
|
||||||
// @forge
|
|
||||||
// Because the minecraft forge team are stupid, they call displayCrashReport on startup
|
|
||||||
// regardless of whether the game has crashed or not. Thus the window may flicker an additional
|
|
||||||
// time as the native window is forced back to the front.
|
|
||||||
// This is a minor issue as the window will simply reassert itself when it's next referenced
|
|
||||||
// (i.e. The skins GUI uses it for file drops) so I have no intention of fixing this.
|
|
||||||
//
|
|
||||||
// This is their problem.
|
|
||||||
//
|
|
||||||
// Update 09/06/2018:
|
|
||||||
// After inspecting the forge source this was found to be nothing but pure lies.
|
|
||||||
// The only place they call it is from FMLClientHandler#haltGame.
|
|
||||||
// There is still the possible case where another mod tries to call it,
|
|
||||||
// but that would be the very definition of 'misbehaving'.
|
|
||||||
//
|
|
||||||
// Also note that the method unconditionally calls System.exit, so anyone
|
|
||||||
// who does will be having a hard time.
|
|
||||||
//
|
|
||||||
// @killjoy
|
|
||||||
// Don't be afraid to use a mixin when the situation calls for it.
|
|
||||||
// There is no other way to do this.
|
|
||||||
//
|
|
||||||
// Do not remove.
|
|
||||||
//
|
|
||||||
// [!!!DO NOT REMOVE!!!]
|
|
||||||
//
|
|
||||||
// I'm serious, do not remove.
|
|
||||||
// I don't care how much of a vendeta you have aginst mixins.
|
|
||||||
//
|
|
||||||
//public void displayCrashReport(CrashReport crashReportIn)
|
|
||||||
@Inject(method = "displayCrashReport(Lnet/minecraft/crash/CrashReport;)V", at = @At("HEAD"))
|
|
||||||
private void onGameCrash(CrashReport report, CallbackInfo info) {
|
|
||||||
GLWindow.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,7 +4,6 @@
|
||||||
"package": "com.voxelmodpack.hdskins.mixin",
|
"package": "com.voxelmodpack.hdskins.mixin",
|
||||||
"refmap": "hdskins.mixin.refmap.json",
|
"refmap": "hdskins.mixin.refmap.json",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"MixinMinecraft",
|
|
||||||
"MixinImageBufferDownload",
|
"MixinImageBufferDownload",
|
||||||
"MixinPlayerInfo",
|
"MixinPlayerInfo",
|
||||||
"MixinSkullRenderer"
|
"MixinSkullRenderer"
|
||||||
|
|
Loading…
Reference in a new issue