Skip to content

Commit

Permalink
Load glyphs in a separate thread with ThreadPoolExecutor
Browse files Browse the repository at this point in the history
  • Loading branch information
Vinrobot committed Jul 17, 2023
1 parent 29c53a8 commit 61db8af
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.font.BuiltinEmptyGlyph;
Expand All @@ -12,6 +17,7 @@
import net.minecraft.client.texture.TextureManager;
import net.minecraft.util.Identifier;
import net.vinrobot.mcemote.MinecraftEmoteMod;
import net.vinrobot.mcemote.client.helpers.FutureHelper;
import net.vinrobot.mcemote.client.text.EmotesManager;

@Environment(EnvType.CLIENT)
Expand All @@ -20,8 +26,9 @@ public class EmoteFontStorage extends FontStorage {
public static final float GLYPH_HEIGHT = 9;

private final EmotesManager emotesManager;
private final Map<Integer, AnimatedGlyph> framesCache = new HashMap<>();
private final Map<Integer, Future<AnimatedGlyph>> framesCache = new HashMap<>();
private final Map<Glyph, GlyphRenderer> glyphRendererCache = new HashMap<>();
private final ExecutorService executorService = new ThreadPoolExecutor(1, 10, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

public EmoteFontStorage(TextureManager textureManager, EmotesManager emotesManager) {
super(textureManager, IDENTIFIER);
Expand All @@ -31,13 +38,18 @@ public EmoteFontStorage(TextureManager textureManager, EmotesManager emotesManag
@Override
public Glyph getGlyph(int codePoint, boolean validateAdvance) {
try {
return this.framesCache.computeIfAbsent(codePoint, this::loadAnimatedGlyph)
.getGlyphAt(Instant.now());
return FutureHelper.asOptional(this.framesCache.computeIfAbsent(codePoint, this::asyncLoadAnimatedGlyph))
.map(m -> m.getGlyphAt(Instant.now()))
.orElse(BuiltinEmptyGlyph.MISSING);
} catch (RuntimeException ex) {
return BuiltinEmptyGlyph.MISSING;
}
}

private Future<AnimatedGlyph> asyncLoadAnimatedGlyph(int codePoint) {
return this.executorService.submit(() -> this.loadAnimatedGlyph(codePoint));
}

private AnimatedGlyph loadAnimatedGlyph(int codePoint) {
try {
final Emote emote = this.emotesManager.getByCodePoint(codePoint).orElseThrow();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package net.vinrobot.mcemote.client.helpers;

import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

public final class FutureHelper {
public static <T> Optional<T> asOptional(Future<T> future) {
if (!future.isDone()) {
return Optional.empty();
}

try {
return Optional.of(future.get());
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e.getCause());
}
}
}

0 comments on commit 61db8af

Please sign in to comment.