Skip to content

Commit

Permalink
fix: AnimationRender not handling animations that take longer than 1 …
Browse files Browse the repository at this point in the history
…frame

---

Signed-off-by: AterAnimAvis <[email protected]>
  • Loading branch information
AterAnimAvis committed Jan 10, 2021
1 parent f5f28c2 commit 9e7818f
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public static <S, T> void bulk(IRenderer<S, T> renderer, ImageHandler<T> handler
private static final int FPS = 20;
private static final int AUTO_LOOP_LENGTH = 30;
private static final long NANOS_IN_A_SECOND = 1_000_000_000L;
private static final int MAX_CONSUME = FPS * AUTO_LOOP_LENGTH;

public static <S, T> void animated(IAnimatedRenderer<S, T> renderer,
Function<T, ImageOutputStream> provider,
Expand Down Expand Up @@ -118,29 +119,53 @@ public static <S, T> void animated(IAnimatedRenderer<S, T> renderer,

private static final Text RENDERING_GIF = new LiteralText("Rendering GIF").formatted(Formatting.GOLD);
private static final Text RENDERING_AUTO = new LiteralText("Auto Loop").formatted(Formatting.GOLD);
private static final Text RENDERING_SKIP = new LiteralText("Skipping First").formatted(Formatting.GOLD);

private static <S, T> void animated(IAnimatedRenderer<S, T> renderer, Consumer<T> callback, S params, int length, boolean loop, T value, ImageHandler<T> write) throws RuntimeException {

AtomicBoolean isSameAsInitial = new AtomicBoolean(false);
AtomicBoolean isSameAsInitial = new AtomicBoolean(true);
AtomicReference<BufferedImage> initial = new AtomicReference<>();

RenderManager.isRendering = true;
int frame = 0;

renderer.setup(params);

ImageHandler<T> init = (v, image) -> initial.compareAndSet(null, image);
ImageHandler<T> checkImage = (v, image) -> isSameAsInitial.set(Images.same(initial.get(), image));
ImageHandler<T> writeFinal = checkImage.andThen((v, image) -> {
ImageHandler<T> checkWrite = checkImage.andThen(write);
ImageHandler<T> writeDifferent = checkImage.andThen((v, image) -> {
if (!isSameAsInitial.get()) write.accept(v, image);
});
ImageHandler<T> writeSame = checkImage.andThen((v, image) -> {
if (isSameAsInitial.get()) write.accept(v, image);
});

/* Skip First Frame + Render Second */
ProgressManager.init(RENDERING_SKIP, -1);
/* We need to handle the case where the target doesn't actually animate so we add a timeout */
int timeout = MAX_CONSUME;
while (isSameAsInitial.get() && timeout > 0) {
timeout--;
final ImageHandler<T> consumer = frame == 0 ? init : timeout == 0 ? write : writeDifferent;

ProgressManager.push(ProgressManager.getProgress());
renderer.render(value, consumer, NANOS_IN_A_SECOND / FPS * frame++);
ProgressManager.pop();

ProgressManager.render();
}
ProgressManager.end();

/* Render for Specified Length */
ProgressManager.init(RENDERING_GIF, length);
for (int i = 0; i < length; i++) {
final ImageHandler<T> consumer = i == 0 ? init.andThen(write) : i == length - 1 ? checkImage.andThen(write) : write;
ProgressManager.skip();

for (int i = 1; i < length; i++) {
final ImageHandler<T> consumer = i == length - 1 ? checkWrite : write;

ProgressManager.push(ProgressManager.getProgress());
renderer.render(value, consumer, NANOS_IN_A_SECOND / FPS * i);
renderer.render(value, consumer, NANOS_IN_A_SECOND / FPS * frame++);
ProgressManager.pop();

ProgressManager.render();
Expand All @@ -153,10 +178,21 @@ private static <S, T> void animated(IAnimatedRenderer<S, T> renderer, Consumer<T
ProgressManager.init(RENDERING_AUTO, -1);
for (int i = 0; i < FPS * AUTO_LOOP_LENGTH; i++) {
ProgressManager.push(ProgressManager.getProgress());
renderer.render(value, writeFinal, NANOS_IN_A_SECOND / FPS * (length + i));
renderer.render(value, checkWrite, NANOS_IN_A_SECOND / FPS * frame++);
ProgressManager.pop();

ProgressManager.render();
if (isSameAsInitial.get()) break;
}
/* Consume Additional Frames */
timeout = MAX_CONSUME;
while (isSameAsInitial.get() && timeout > 0) {
timeout--;

ProgressManager.push(ProgressManager.getProgress());
renderer.render(value, writeSame, NANOS_IN_A_SECOND / FPS * frame++);
ProgressManager.pop();

ProgressManager.render();
}
ProgressManager.end();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.unascribed.blockrenderer.fabric.client.render.report;


import com.unascribed.blockrenderer.fabric.client.varia.rendering.Display;
import com.unascribed.blockrenderer.fabric.client.varia.rendering.GL;
import com.unascribed.blockrenderer.varia.debug.Debug;
Expand Down Expand Up @@ -56,6 +55,11 @@ public static void pop() {
last = now;
}

public static void skip() {
push(getProgress());
pop();
}

public static void end() {
/* Log Time */
long now = System.nanoTime();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public static <S, T> void bulk(IRenderer<S, T> renderer, ImageHandler<T> handler
private static final int FPS = 20;
private static final int AUTO_LOOP_LENGTH = 30;
private static final long NANOS_IN_A_SECOND = 1_000_000_000L;
private static final int MAX_CONSUME = FPS * AUTO_LOOP_LENGTH;

public static <S, T> void animated(IAnimatedRenderer<S, T> renderer,
Function<T, ImageOutputStream> provider,
Expand Down Expand Up @@ -118,29 +119,52 @@ public static <S, T> void animated(IAnimatedRenderer<S, T> renderer,

private static final ITextComponent RENDERING_GIF = new StringTextComponent("Rendering GIF").mergeStyle(TextFormatting.GOLD);
private static final ITextComponent RENDERING_AUTO = new StringTextComponent("Auto Loop").mergeStyle(TextFormatting.GOLD);
private static final ITextComponent RENDERING_SKIP = new StringTextComponent("Skipping First").mergeStyle(TextFormatting.GOLD);

private static <S, T> void animated(IAnimatedRenderer<S, T> renderer, Consumer<T> callback, S params, int length, boolean loop, T value, ImageHandler<T> write) throws RuntimeException {

AtomicBoolean isSameAsInitial = new AtomicBoolean(false);
AtomicBoolean isSameAsInitial = new AtomicBoolean(true);
AtomicReference<BufferedImage> initial = new AtomicReference<>();

RenderManager.isRendering = true;
int frame = 0;

renderer.setup(params);

ImageHandler<T> init = (v, image) -> initial.compareAndSet(null, image);
ImageHandler<T> checkImage = (v, image) -> isSameAsInitial.set(Images.same(initial.get(), image));
ImageHandler<T> writeFinal = checkImage.andThen((v, image) -> {
ImageHandler<T> checkWrite = checkImage.andThen(write);
ImageHandler<T> writeDifferent = checkImage.andThen((v, image) -> {
if (!isSameAsInitial.get()) write.accept(v, image);
});
ImageHandler<T> writeSame = checkImage.andThen((v, image) -> {
if (isSameAsInitial.get()) write.accept(v, image);
});

/* Skip First Frame + Render Second */
ProgressManager.init(RENDERING_SKIP, -1);
/* We need to handle the case where the target doesn't actually animate so we add a timeout */
int timeout = MAX_CONSUME;
while (isSameAsInitial.get() && timeout > 0) {
timeout--;
final ImageHandler<T> consumer = frame == 0 ? init : timeout == 0 ? write : writeDifferent;

ProgressManager.push(ProgressManager.getProgress());
renderer.render(value, consumer, NANOS_IN_A_SECOND / FPS * frame++);
ProgressManager.pop();

ProgressManager.render();
}
ProgressManager.end();

/* Render for Specified Length */
ProgressManager.init(RENDERING_GIF, length);
for (int i = 0; i < length; i++) {
final ImageHandler<T> consumer = i == 0 ? init.andThen(write) : i == length - 1 ? checkImage.andThen(write) : write;
ProgressManager.skip();
for (int i = 1; i < length; i++) {
final ImageHandler<T> consumer = i == length - 1 ? checkWrite : write;

ProgressManager.push(ProgressManager.getProgress());
renderer.render(value, consumer, NANOS_IN_A_SECOND / FPS * i);
renderer.render(value, consumer, NANOS_IN_A_SECOND / FPS * frame++);
ProgressManager.pop();

ProgressManager.render();
Expand All @@ -153,10 +177,21 @@ private static <S, T> void animated(IAnimatedRenderer<S, T> renderer, Consumer<T
ProgressManager.init(RENDERING_AUTO, -1);
for (int i = 0; i < FPS * AUTO_LOOP_LENGTH; i++) {
ProgressManager.push(ProgressManager.getProgress());
renderer.render(value, writeFinal, NANOS_IN_A_SECOND / FPS * (length + i));
renderer.render(value, checkWrite, NANOS_IN_A_SECOND / FPS * frame++);
ProgressManager.pop();

ProgressManager.render();
if (isSameAsInitial.get()) break;
}
/* Consume Additional Frames */
timeout = MAX_CONSUME;
while (isSameAsInitial.get() && timeout > 0) {
timeout--;

ProgressManager.push(ProgressManager.getProgress());
renderer.render(value, writeSame, NANOS_IN_A_SECOND / FPS * frame++);
ProgressManager.pop();

ProgressManager.render();
}
ProgressManager.end();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ public static void pop() {
last = now;
}

public static void skip() {
push(getProgress());
pop();
}

public static void end() {
/* Log Time */
long now = System.nanoTime();
Expand Down

0 comments on commit 9e7818f

Please sign in to comment.