Integrated thread implementation / Crash fix
This commit is contained in:
@@ -23,7 +23,6 @@ import io.anuke.kryonet.DefaultThreadImpl;
|
||||
import io.anuke.kryonet.KryoClient;
|
||||
import io.anuke.kryonet.KryoServer;
|
||||
import io.anuke.mindustry.core.Platform;
|
||||
import io.anuke.mindustry.core.ThreadHandler.ThreadProvider;
|
||||
import io.anuke.mindustry.game.Saves.SaveSlot;
|
||||
import io.anuke.mindustry.io.SaveIO;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
@@ -85,11 +84,6 @@ public class AndroidLauncher extends PatchedAndroidApplication{
|
||||
showDonations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThreadProvider getThreadProvider(){
|
||||
return new DefaultThreadImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUUID(){
|
||||
try{
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ allprojects {
|
||||
appName = 'Mindustry'
|
||||
gdxVersion = '1.9.8'
|
||||
roboVMVersion = '2.3.0'
|
||||
uCoreVersion = '53571305f7e5b31dd07377756bb46c0f2ae2ef34'
|
||||
uCoreVersion = 'dec41336067c013f04f0e17db3b06e24d3c11f6a'
|
||||
|
||||
getVersionString = {
|
||||
String buildVersion = getBuildVersion()
|
||||
|
||||
@@ -166,7 +166,7 @@ public class Vars{
|
||||
});
|
||||
}
|
||||
|
||||
threads = new ThreadHandler(Platform.instance.getThreadProvider());
|
||||
threads = new ThreadHandler();
|
||||
|
||||
mobile = Gdx.app.getType() == ApplicationType.Android || Gdx.app.getType() == ApplicationType.iOS || testMobile;
|
||||
ios = Gdx.app.getType() == ApplicationType.iOS;
|
||||
|
||||
@@ -210,7 +210,7 @@ public class ContentLoader{
|
||||
if(id < 0) id += 256;
|
||||
|
||||
if(temporaryMapper != null && temporaryMapper[type.ordinal()] != null && temporaryMapper[type.ordinal()].length != 0){
|
||||
if(temporaryMapper[type.ordinal()][id] == null){
|
||||
if(temporaryMapper[type.ordinal()].length <= id || temporaryMapper[type.ordinal()][id] == null){
|
||||
return getByID(type, 0); //default value is always ID 0
|
||||
}
|
||||
return (T)temporaryMapper[type.ordinal()][id];
|
||||
|
||||
@@ -2,7 +2,6 @@ package io.anuke.mindustry.core;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.Base64Coder;
|
||||
import io.anuke.mindustry.core.ThreadHandler.ThreadProvider;
|
||||
import io.anuke.ucore.core.Settings;
|
||||
import io.anuke.ucore.function.Consumer;
|
||||
import io.anuke.ucore.scene.ui.TextField;
|
||||
@@ -67,17 +66,6 @@ public abstract class Platform {
|
||||
* @param filetype File extension to filter
|
||||
*/
|
||||
public void showFileChooser(String text, String content, Consumer<FileHandle> cons, boolean open, String filetype){}
|
||||
/**Use the default thread provider from the kryonet module for this.*/
|
||||
public ThreadProvider getThreadProvider(){
|
||||
return new ThreadProvider() {
|
||||
@Override public boolean isOnThread() {return true;}
|
||||
@Override public void sleep(long ms) {}
|
||||
@Override public void start(Runnable run) {}
|
||||
@Override public void stop() {}
|
||||
@Override public void notify(Object object) {}
|
||||
@Override public void wait(Object object) {}
|
||||
};
|
||||
}
|
||||
|
||||
/**Forces the app into landscape mode. Currently Android only.*/
|
||||
public void beginForceLandscape(){}
|
||||
|
||||
@@ -6,13 +6,15 @@ import com.badlogic.gdx.utils.TimeUtils;
|
||||
import io.anuke.ucore.core.Settings;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.util.Log;
|
||||
import io.anuke.ucore.util.Threads;
|
||||
import io.anuke.ucore.util.Threads.ThreadInfoProvider;
|
||||
|
||||
import static io.anuke.mindustry.Vars.control;
|
||||
import static io.anuke.mindustry.Vars.logic;
|
||||
|
||||
public class ThreadHandler{
|
||||
public class ThreadHandler implements ThreadInfoProvider{
|
||||
private final Queue<Runnable> toRun = new Queue<>();
|
||||
private final ThreadProvider impl;
|
||||
private Thread thread, graphicsThread;
|
||||
private final Object updateLock = new Object();
|
||||
private float delta = 1f;
|
||||
private float smoothDelta = 1f;
|
||||
@@ -22,11 +24,12 @@ public class ThreadHandler{
|
||||
private boolean rendered = true;
|
||||
private long lastFrameTime;
|
||||
|
||||
public ThreadHandler(ThreadProvider impl){
|
||||
this.impl = impl;
|
||||
public ThreadHandler(){
|
||||
Threads.setThreadInfoProvider(this);
|
||||
graphicsThread = Thread.currentThread();
|
||||
|
||||
Timers.setDeltaProvider(() -> {
|
||||
float result = impl.isOnThread() ? delta : Gdx.graphics.getDeltaTime() * 60f;
|
||||
float result = isOnThread() ? delta : Gdx.graphics.getDeltaTime() * 60f;
|
||||
return Math.min(Float.isNaN(result) ? 1f : result, 15f);
|
||||
});
|
||||
}
|
||||
@@ -86,7 +89,7 @@ public class ThreadHandler{
|
||||
long elapsed = TimeUtils.timeSinceMillis(lastFrameTime);
|
||||
if(elapsed < target){
|
||||
try{
|
||||
impl.sleep(target - elapsed);
|
||||
Thread.sleep(target - elapsed);
|
||||
}catch(InterruptedException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -99,7 +102,7 @@ public class ThreadHandler{
|
||||
|
||||
synchronized(updateLock){
|
||||
rendered = true;
|
||||
impl.notify(updateLock);
|
||||
Threads.notify(updateLock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,12 +114,25 @@ public class ThreadHandler{
|
||||
if(enabled){
|
||||
logic.doUpdate = false;
|
||||
Timers.runTask(2f, () -> {
|
||||
impl.start(this::runLogic);
|
||||
if(thread != null){
|
||||
thread.interrupt();
|
||||
thread = null;
|
||||
}
|
||||
|
||||
thread = new Thread(this::runLogic);
|
||||
thread.setDaemon(true);
|
||||
thread.setName("Update Thread");
|
||||
thread.start();
|
||||
Log.info("Starting logic thread.");
|
||||
|
||||
this.enabled = true;
|
||||
});
|
||||
}else{
|
||||
this.enabled = false;
|
||||
impl.stop();
|
||||
if(thread != null){
|
||||
thread.interrupt();
|
||||
thread = null;
|
||||
}
|
||||
Timers.runTask(2f, () -> {
|
||||
logic.doUpdate = true;
|
||||
});
|
||||
@@ -128,7 +144,17 @@ public class ThreadHandler{
|
||||
}
|
||||
|
||||
public boolean isOnThread(){
|
||||
return impl.isOnThread();
|
||||
return Thread.currentThread() == thread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnLogicThread() {
|
||||
return !enabled || Thread.currentThread() == thread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnGraphicsThread() {
|
||||
return !enabled || Thread.currentThread() == graphicsThread;
|
||||
}
|
||||
|
||||
private void runLogic(){
|
||||
@@ -157,12 +183,12 @@ public class ThreadHandler{
|
||||
long target = (long) ((1000) / 60f);
|
||||
|
||||
if(elapsed < target){
|
||||
impl.sleep(target - elapsed);
|
||||
Thread.sleep(target - elapsed);
|
||||
}
|
||||
|
||||
synchronized(updateLock){
|
||||
while(!rendered){
|
||||
impl.wait(updateLock);
|
||||
Threads.wait(updateLock);
|
||||
}
|
||||
rendered = false;
|
||||
}
|
||||
@@ -184,18 +210,4 @@ public class ThreadHandler{
|
||||
control.setError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public interface ThreadProvider{
|
||||
boolean isOnThread();
|
||||
|
||||
void sleep(long ms) throws InterruptedException;
|
||||
|
||||
void start(Runnable run);
|
||||
|
||||
void stop();
|
||||
|
||||
void wait(Object object) throws InterruptedException;
|
||||
|
||||
void notify(Object object);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,6 +165,7 @@ public class SaveIO{
|
||||
|
||||
stream.close();
|
||||
}catch(Exception e){
|
||||
content.setTemporaryMapper(null);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,9 @@ import club.minnced.discord.rpc.DiscordRichPresence;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Base64Coder;
|
||||
import io.anuke.kryonet.DefaultThreadImpl;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.core.Platform;
|
||||
import io.anuke.mindustry.core.ThreadHandler.ThreadProvider;
|
||||
import io.anuke.mindustry.game.GameMode;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.ui.dialogs.FileChooser;
|
||||
@@ -112,11 +110,6 @@ public class DesktopPlatform extends Platform{
|
||||
if(useDiscord) DiscordRPC.INSTANCE.Discord_Shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThreadProvider getThreadProvider(){
|
||||
return new DefaultThreadImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUUID(){
|
||||
try{
|
||||
|
||||
@@ -4,13 +4,11 @@ import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.backends.iosrobovm.IOSApplication;
|
||||
import com.badlogic.gdx.backends.iosrobovm.IOSApplicationConfiguration;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import io.anuke.kryonet.DefaultThreadImpl;
|
||||
import io.anuke.kryonet.KryoClient;
|
||||
import io.anuke.kryonet.KryoServer;
|
||||
import io.anuke.mindustry.core.Platform;
|
||||
import io.anuke.mindustry.core.ThreadHandler;
|
||||
import io.anuke.mindustry.io.SaveIO;
|
||||
import io.anuke.mindustry.game.Saves.SaveSlot;
|
||||
import io.anuke.mindustry.io.SaveIO;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.ucore.scene.ui.TextField;
|
||||
import io.anuke.ucore.scene.ui.layout.Unit;
|
||||
@@ -73,11 +71,6 @@ public class IOSLauncher extends IOSApplication.Delegate {
|
||||
return locale.getDisplayName(locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThreadHandler.ThreadProvider getThreadProvider() {
|
||||
return new DefaultThreadImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shareFile(FileHandle file){
|
||||
FileHandle to = Gdx.files.absolute(getDocumentsDirectory()).child(file.name());
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
package io.anuke.kryonet;
|
||||
|
||||
import io.anuke.mindustry.core.ThreadHandler.ThreadProvider;
|
||||
import io.anuke.ucore.util.Threads;
|
||||
import io.anuke.ucore.util.Threads.ThreadInfoProvider;
|
||||
import io.anuke.ucore.util.Log;
|
||||
|
||||
public class DefaultThreadImpl implements ThreadProvider, ThreadInfoProvider{
|
||||
private Thread thread;
|
||||
|
||||
public DefaultThreadImpl(){
|
||||
Threads.setThreadInfoProvider(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnLogicThread(){
|
||||
return thread == null || isOnThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnGraphicsThread(){
|
||||
return thread == null || !isOnThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnThread() {
|
||||
return Thread.currentThread() == thread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sleep(long ms) throws InterruptedException{
|
||||
Thread.sleep(ms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Runnable run) {
|
||||
if(thread != null){
|
||||
thread.interrupt();
|
||||
thread = null;
|
||||
}
|
||||
|
||||
thread = new Thread(run);
|
||||
thread.setDaemon(true);
|
||||
thread.setName("Update Thread");
|
||||
thread.start();
|
||||
Log.info("Starting logic thread.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if(thread != null){
|
||||
thread.interrupt();
|
||||
thread = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wait(Object object) throws InterruptedException{
|
||||
object.wait();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notify(Object object) {
|
||||
object.notify();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user