Temporarily shift splash screen control to background thread during registry events
This commit is contained in:
parent
f7097ec394
commit
a19d519b4b
|
|
@ -0,0 +1,20 @@
|
||||||
|
package org.embeddedt.modernfix.forge.mixin.bugfix.loading_screen_freeze;
|
||||||
|
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||||
|
import net.minecraftforge.eventbus.api.Event;
|
||||||
|
import net.minecraftforge.fml.ModLoader;
|
||||||
|
import net.minecraftforge.registries.GameData;
|
||||||
|
import org.embeddedt.modernfix.forge.util.AsyncLoadingScreen;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|
||||||
|
@Mixin(value = GameData.class, remap = false)
|
||||||
|
public class GameDataMixin {
|
||||||
|
@WrapOperation(method = "postRegisterEvents", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/ModLoader;postEventWrapContainerInModOrder(Lnet/minecraftforge/eventbus/api/Event;)V"))
|
||||||
|
private static void swapThreadAndPost(ModLoader loader, Event event, Operation<Void> operation) {
|
||||||
|
try(AsyncLoadingScreen ignored = new AsyncLoadingScreen()) {
|
||||||
|
operation.call(loader, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
package org.embeddedt.modernfix.forge.util;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.loading.ImmediateWindowHandler;
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import org.lwjgl.opengl.GL;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
|
public class AsyncLoadingScreen extends Thread implements AutoCloseable {
|
||||||
|
private final long theWindow;
|
||||||
|
private final AtomicBoolean keepRunning;
|
||||||
|
|
||||||
|
private static int splashThreadNum = 1;
|
||||||
|
|
||||||
|
public AsyncLoadingScreen() {
|
||||||
|
this.setName("ModernFix splash thread " + splashThreadNum++);
|
||||||
|
this.theWindow = GLFW.glfwGetCurrentContext();
|
||||||
|
if(this.theWindow == 0)
|
||||||
|
throw new IllegalStateException("No context found but async loading screen was requested");
|
||||||
|
this.keepRunning = new AtomicBoolean(true);
|
||||||
|
this.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void start() {
|
||||||
|
GLFW.glfwMakeContextCurrent(0);
|
||||||
|
super.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
GLFW.glfwMakeContextCurrent(theWindow);
|
||||||
|
GL.createCapabilities(); // seems to be needed, otherwise we get a "function not valid for context" error
|
||||||
|
while(keepRunning.get()) {
|
||||||
|
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(50));
|
||||||
|
ImmediateWindowHandler.renderTick();
|
||||||
|
}
|
||||||
|
GLFW.glfwMakeContextCurrent(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
keepRunning.set(false);
|
||||||
|
try {
|
||||||
|
this.join();
|
||||||
|
} catch(InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
GLFW.glfwMakeContextCurrent(theWindow);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user