Skip to content

Commit

Permalink
Rename Frames to AnimatedGlyph
Browse files Browse the repository at this point in the history
  • Loading branch information
Vinrobot committed Jul 17, 2023
1 parent 7dcd3c2 commit 29c53a8
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
package net.vinrobot.mcemote.client.font;

import net.minecraft.client.font.Glyph;

import java.time.Duration;
import java.time.Instant;
import java.util.stream.Stream;
import net.minecraft.client.font.Glyph;

public class Frames {
public class AnimatedGlyph {
private final Frame[] frames;
private final Duration loopTime;

public Frames(Frame[] frames) {
public AnimatedGlyph(Frame[] frames) {
this.frames = frames;
this.loopTime = Stream.of(frames)
.map(Frame::duration)
.reduce(Duration::plus)
.orElse(Duration.ofDays(1));
}

private static Duration modulo(Duration a, Duration b) {
private static Duration modulo(Instant a, Duration b) {
// TODO: Improve using Duration::getSeconds and Duration::getNano
return a.minus(b.multipliedBy(a.toMillis() / b.toMillis()));
return Duration.ofMillis(a.toEpochMilli() % b.toMillis());
}

public Frame getFrameAt(Duration at) {
public Glyph getGlyphAt(Instant at) {
final Duration time = modulo(at, loopTime);

Duration current = Duration.ZERO;
for (Frame frame : frames) {
current = current.plus(frame.duration());
if (current.compareTo(time) > 0) {
return frame;
return frame.image();
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
package net.vinrobot.mcemote.client.font;

import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.font.BuiltinEmptyGlyph;
import net.minecraft.client.font.FontStorage;
import net.minecraft.client.font.Glyph;
import net.minecraft.client.font.GlyphRenderer;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.TextureManager;
import net.minecraft.util.Identifier;
import net.vinrobot.mcemote.MinecraftEmoteMod;
import net.vinrobot.mcemote.client.helpers.NativeImageHelper;
import net.vinrobot.mcemote.client.text.EmotesManager;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

@Environment(EnvType.CLIENT)
public class EmoteFontStorage extends FontStorage {
public static final Identifier IDENTIFIER = new Identifier("mcemote.fonts", "emotes");
public static final float GLYPH_HEIGHT = 9;

private final EmotesManager emotesManager;
private final Map<Integer, Frames> framesCache = new HashMap<>();
private final Map<Integer, AnimatedGlyph> framesCache = new HashMap<>();
private final Map<Glyph, GlyphRenderer> glyphRendererCache = new HashMap<>();

public EmoteFontStorage(TextureManager textureManager, EmotesManager emotesManager) {
Expand All @@ -34,32 +31,31 @@ public EmoteFontStorage(TextureManager textureManager, EmotesManager emotesManag
@Override
public Glyph getGlyph(int codePoint, boolean validateAdvance) {
try {
return this.framesCache.computeIfAbsent(codePoint, this::loadAnimationManager)
.getFrameAt(Duration.ofMillis(System.currentTimeMillis()))
.image();
return this.framesCache.computeIfAbsent(codePoint, this::loadAnimatedGlyph)
.getGlyphAt(Instant.now());
} catch (RuntimeException ex) {
return BuiltinEmptyGlyph.MISSING;
}
}

private Frames loadAnimationManager(Integer integer) {
private AnimatedGlyph loadAnimatedGlyph(int codePoint) {
try {
final Emote emote = this.emotesManager.getByCodePoint(integer).orElseThrow();
final Emote emote = this.emotesManager.getByCodePoint(codePoint).orElseThrow();

final int width = emote.getWidth();
final int height = emote.getHeight();
final float advance = width * GLYPH_HEIGHT / height;
final float oversample = height / GLYPH_HEIGHT;
final Emote.Frame[] frames = emote.loadFrames();

final Frames.Frame[] animatedFrames = new Frames.Frame[frames.length];
final AnimatedGlyph.Frame[] animatedFrames = new AnimatedGlyph.Frame[frames.length];
for (int i = 0; i < frames.length; i++) {
final Emote.Frame frame = frames[i];
final Glyph glyph = new NativeImageGlyph(frame.image(), advance, oversample);
animatedFrames[i] = new Frames.Frame(glyph, frame.duration());
animatedFrames[i] = new AnimatedGlyph.Frame(glyph, frame.duration());
}

return new Frames(animatedFrames);
return new AnimatedGlyph(animatedFrames);
} catch (Exception ex) {
MinecraftEmoteMod.LOGGER.error("Unable to load emote", ex);
throw new RuntimeException(ex);
Expand Down

0 comments on commit 29c53a8

Please sign in to comment.