Fix parseSkin race condition (final2)

This commit is contained in:
Matthew Messinger 2018-09-04 18:51:07 -04:00
parent 953f17828c
commit 5d72c4f0b4
2 changed files with 32 additions and 37 deletions

View file

@ -24,6 +24,7 @@ import com.voxelmodpack.hdskins.skins.LegacySkinServer;
import com.voxelmodpack.hdskins.skins.ServerType;
import com.voxelmodpack.hdskins.skins.SkinServer;
import com.voxelmodpack.hdskins.skins.ValhallaSkinServer;
import com.voxelmodpack.hdskins.util.CallableFutures;
import com.voxelmodpack.hdskins.util.PlayerUtil;
import com.voxelmodpack.hdskins.util.ProfileTextureUtil;
import net.minecraft.client.Minecraft;
@ -310,14 +311,8 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
}
public void parseSkin(GameProfile profile, Type type, ResourceLocation resource, MinecraftProfileTexture texture) {
TextureManager tm = Minecraft.getMinecraft().getTextureManager();
try {
// this runs in a separate thread anyway, so just get with a timeout.
getUntilNonnull(() -> tm.getTexture(resource)).get(1, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
throw new CompletionException(e);
}
CallableFutures.scheduleTask(() -> {
// grab the metadata object via reflection. Object is live.
Map<String, String> metadata = ProfileTextureUtil.getMetadata(texture);
@ -339,20 +334,6 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
if (wasNull && !metadata.isEmpty()) {
ProfileTextureUtil.setMetadata(texture, metadata);
}
}
/**
* Continuously gets a item in a new thread until it returns nonnull.
*/
private static <T> CompletableFuture<T> getUntilNonnull(Supplier<T> getter) {
return CompletableFuture.supplyAsync(() -> {
T res = null;
while (res == null) {
res = getter.get();
}
return res;
});
}

View file

@ -1,12 +1,19 @@
package com.voxelmodpack.hdskins.util;
import net.minecraft.client.Minecraft;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
public class CallableFutures {
private static final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
public static <T> CompletableFuture<T> asyncFailableFuture(Callable<T> call, Executor exec) {
CompletableFuture<T> ret = new CompletableFuture<>();
exec.execute(() -> {
@ -31,4 +38,11 @@ public class CallableFutures {
return null;
};
}
public static void scheduleTask(Runnable task) {
// schedule a task for next tick.
executor.schedule(() -> {
Minecraft.getMinecraft().addScheduledTask(task);
}, 50, TimeUnit.MILLISECONDS);
}
}