Show content of replay's render queue in Replay Viewer
As part of #349.
This commit is contained in:
@@ -116,7 +116,7 @@ public class GuiSavingReplay {
|
|||||||
|
|
||||||
private GuiPanel createTooltip(Path path, ReplayMetaData metaData) {
|
private GuiPanel createTooltip(Path path, ReplayMetaData metaData) {
|
||||||
GuiTooltip tooltip = new GuiTooltip();
|
GuiTooltip tooltip = new GuiTooltip();
|
||||||
GuiReplayViewer.GuiReplayEntry entry = new GuiReplayViewer.GuiReplayEntry(path.toFile(), metaData, null);
|
GuiReplayViewer.GuiReplayEntry entry = new GuiReplayViewer.GuiReplayEntry(path.toFile(), metaData, null, new ArrayList<>());
|
||||||
return new GuiPanel().setLayout(new CustomLayout<GuiPanel>() {
|
return new GuiPanel().setLayout(new CustomLayout<GuiPanel>() {
|
||||||
@Override
|
@Override
|
||||||
protected void layout(GuiPanel container, int width, int height) {
|
protected void layout(GuiPanel container, int width, int height) {
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
package com.replaymod.render;
|
package com.replaymod.render;
|
||||||
|
|
||||||
import com.google.common.base.Optional;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.TypeAdapter;
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
import com.google.gson.stream.JsonReader;
|
|
||||||
import com.google.gson.stream.JsonWriter;
|
|
||||||
import com.replaymod.core.Module;
|
import com.replaymod.core.Module;
|
||||||
import com.replaymod.core.ReplayMod;
|
import com.replaymod.core.ReplayMod;
|
||||||
import com.replaymod.core.utils.Utils;
|
import com.replaymod.core.utils.Utils;
|
||||||
@@ -13,11 +7,7 @@ import com.replaymod.render.utils.RenderJob;
|
|||||||
import com.replaymod.replay.ReplayHandler;
|
import com.replaymod.replay.ReplayHandler;
|
||||||
import com.replaymod.replay.events.ReplayClosedCallback;
|
import com.replaymod.replay.events.ReplayClosedCallback;
|
||||||
import com.replaymod.replay.events.ReplayOpenedCallback;
|
import com.replaymod.replay.events.ReplayOpenedCallback;
|
||||||
import com.replaymod.replaystudio.pathing.PathingRegistry;
|
|
||||||
import com.replaymod.replaystudio.pathing.path.Timeline;
|
|
||||||
import com.replaymod.replaystudio.pathing.serialize.TimelineSerialization;
|
|
||||||
import com.replaymod.replaystudio.replay.ReplayFile;
|
import com.replaymod.replaystudio.replay.ReplayFile;
|
||||||
import com.replaymod.simplepathing.SPTimeline;
|
|
||||||
import de.johni0702.minecraft.gui.container.VanillaGuiScreen;
|
import de.johni0702.minecraft.gui.container.VanillaGuiScreen;
|
||||||
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
||||||
import net.minecraft.util.crash.CrashReport;
|
import net.minecraft.util.crash.CrashReport;
|
||||||
@@ -28,14 +18,8 @@ import org.apache.logging.log4j.Logger;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ReplayModRender extends EventRegistrations implements Module {
|
public class ReplayModRender extends EventRegistrations implements Module {
|
||||||
@@ -87,7 +71,7 @@ public class ReplayModRender extends EventRegistrations implements Module {
|
|||||||
private void onReplayOpened(ReplayHandler replayHandler) {
|
private void onReplayOpened(ReplayHandler replayHandler) {
|
||||||
replayFile = replayHandler.getReplayFile();
|
replayFile = replayHandler.getReplayFile();
|
||||||
try {
|
try {
|
||||||
renderQueue.addAll(doLoadRenderQueue(replayFile));
|
renderQueue.addAll(RenderJob.readQueue(replayFile));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new CrashException(CrashReport.create(e, "Reading timeline"));
|
throw new CrashException(CrashReport.create(e, "Reading timeline"));
|
||||||
}
|
}
|
||||||
@@ -99,37 +83,9 @@ public class ReplayModRender extends EventRegistrations implements Module {
|
|||||||
replayFile = null;
|
replayFile = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<RenderJob> doLoadRenderQueue(ReplayFile replayFile) throws IOException {
|
|
||||||
synchronized (replayFile) {
|
|
||||||
Optional<InputStream> optIn = replayFile.get("renderQueue.json");
|
|
||||||
if (!optIn.isPresent()) {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
try (InputStream in = optIn.get();
|
|
||||||
InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8)) {
|
|
||||||
return new GsonBuilder()
|
|
||||||
.registerTypeAdapter(Timeline.class, new TimelineTypeAdapter())
|
|
||||||
.create()
|
|
||||||
.fromJson(reader, new TypeToken<List<RenderJob>>(){}.getType());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void doSaveRenderQueue(ReplayFile replayFile, List<RenderJob> renderQueue) throws IOException {
|
|
||||||
synchronized (replayFile) {
|
|
||||||
try (OutputStream out = replayFile.write("renderQueue.json");
|
|
||||||
OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8)) {
|
|
||||||
new GsonBuilder()
|
|
||||||
.registerTypeAdapter(Timeline.class, new TimelineTypeAdapter())
|
|
||||||
.create()
|
|
||||||
.toJson(renderQueue, writer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveRenderQueue() {
|
public void saveRenderQueue() {
|
||||||
try {
|
try {
|
||||||
doSaveRenderQueue(replayFile, renderQueue);
|
RenderJob.writeQueue(replayFile, renderQueue);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
VanillaGuiScreen screen = VanillaGuiScreen.setup(getCore().getMinecraft().currentScreen);
|
VanillaGuiScreen screen = VanillaGuiScreen.setup(getCore().getMinecraft().currentScreen);
|
||||||
@@ -137,32 +93,4 @@ public class ReplayModRender extends EventRegistrations implements Module {
|
|||||||
Utils.error(LOGGER, screen, report, () -> {});
|
Utils.error(LOGGER, screen, report, () -> {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TimelineTypeAdapter extends TypeAdapter<Timeline> {
|
|
||||||
|
|
||||||
private final TimelineSerialization serialization;
|
|
||||||
|
|
||||||
public TimelineTypeAdapter(TimelineSerialization serialization) {
|
|
||||||
this.serialization = serialization;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimelineTypeAdapter(PathingRegistry registry) {
|
|
||||||
this(new TimelineSerialization(registry, null));
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimelineTypeAdapter() {
|
|
||||||
// TODO need to somehow get rid of the reliance on simplepathing
|
|
||||||
this(new SPTimeline());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(JsonWriter out, Timeline value) throws IOException {
|
|
||||||
out.value(serialization.serialize(Collections.singletonMap("", value)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Timeline read(JsonReader in) throws IOException {
|
|
||||||
return serialization.deserialize(in.nextString()).get("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,27 @@
|
|||||||
package com.replaymod.render.utils;
|
package com.replaymod.render.utils;
|
||||||
|
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.TypeAdapter;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
import com.replaymod.render.RenderSettings;
|
import com.replaymod.render.RenderSettings;
|
||||||
|
import com.replaymod.replaystudio.pathing.PathingRegistry;
|
||||||
import com.replaymod.replaystudio.pathing.path.Timeline;
|
import com.replaymod.replaystudio.pathing.path.Timeline;
|
||||||
|
import com.replaymod.replaystudio.pathing.serialize.TimelineSerialization;
|
||||||
|
import com.replaymod.replaystudio.replay.ReplayFile;
|
||||||
|
import com.replaymod.simplepathing.SPTimeline;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class RenderJob {
|
public class RenderJob {
|
||||||
@@ -53,4 +72,60 @@ public class RenderJob {
|
|||||||
", settings=" + settings +
|
", settings=" + settings +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<RenderJob> readQueue(ReplayFile replayFile) throws IOException {
|
||||||
|
synchronized (replayFile) {
|
||||||
|
Optional<InputStream> optIn = replayFile.get("renderQueue.json");
|
||||||
|
if (!optIn.isPresent()) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
try (InputStream in = optIn.get();
|
||||||
|
InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8)) {
|
||||||
|
return new GsonBuilder()
|
||||||
|
.registerTypeAdapter(Timeline.class, new TimelineTypeAdapter())
|
||||||
|
.create()
|
||||||
|
.fromJson(reader, new TypeToken<List<RenderJob>>(){}.getType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeQueue(ReplayFile replayFile, List<RenderJob> renderQueue) throws IOException {
|
||||||
|
synchronized (replayFile) {
|
||||||
|
try (OutputStream out = replayFile.write("renderQueue.json");
|
||||||
|
OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8)) {
|
||||||
|
new GsonBuilder()
|
||||||
|
.registerTypeAdapter(Timeline.class, new TimelineTypeAdapter())
|
||||||
|
.create()
|
||||||
|
.toJson(renderQueue, writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TimelineTypeAdapter extends TypeAdapter<Timeline> {
|
||||||
|
|
||||||
|
private final TimelineSerialization serialization;
|
||||||
|
|
||||||
|
public TimelineTypeAdapter(TimelineSerialization serialization) {
|
||||||
|
this.serialization = serialization;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimelineTypeAdapter(PathingRegistry registry) {
|
||||||
|
this(new TimelineSerialization(registry, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimelineTypeAdapter() {
|
||||||
|
// TODO need to somehow get rid of the reliance on simplepathing
|
||||||
|
this(new SPTimeline());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JsonWriter out, Timeline value) throws IOException {
|
||||||
|
out.value(serialization.serialize(Collections.singletonMap("", value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Timeline read(JsonReader in) throws IOException {
|
||||||
|
return serialization.deserialize(in.nextString()).get("");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.google.common.base.Supplier;
|
|||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.SettableFuture;
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
|
import com.replaymod.render.utils.RenderJob;
|
||||||
import de.johni0702.minecraft.gui.GuiRenderer;
|
import de.johni0702.minecraft.gui.GuiRenderer;
|
||||||
import de.johni0702.minecraft.gui.RenderInfo;
|
import de.johni0702.minecraft.gui.RenderInfo;
|
||||||
import de.johni0702.minecraft.gui.versions.Image;
|
import de.johni0702.minecraft.gui.versions.Image;
|
||||||
@@ -369,9 +370,10 @@ public class GuiReplayViewer extends GuiScreen {
|
|||||||
}
|
}
|
||||||
}).orElse(null);
|
}).orElse(null);
|
||||||
final ReplayMetaData metaData = replayFile.getMetaData();
|
final ReplayMetaData metaData = replayFile.getMetaData();
|
||||||
|
List<RenderJob> renderQueue = RenderJob.readQueue(replayFile);
|
||||||
|
|
||||||
if (metaData != null) {
|
if (metaData != null) {
|
||||||
results.consume(() -> new GuiReplayEntry(file, metaData, thumb) {
|
results.consume(() -> new GuiReplayEntry(file, metaData, thumb, renderQueue) {
|
||||||
@Override
|
@Override
|
||||||
public ReadableDimension calcMinSize() {
|
public ReadableDimension calcMinSize() {
|
||||||
if (isFiltered(this)) {
|
if (isFiltered(this)) {
|
||||||
@@ -483,12 +485,17 @@ public class GuiReplayViewer extends GuiScreen {
|
|||||||
return new Dimension(dimension.getWidth() + 2, dimension.getHeight() + 2);
|
return new Dimension(dimension.getWidth() + 2, dimension.getHeight() + 2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
public final GuiImage renderQueueIcon = new GuiImage()
|
||||||
|
.setSize(10, 10)
|
||||||
|
.setTexture(ReplayMod.TEXTURE, 40, 0, 20, 20);
|
||||||
|
|
||||||
private final long dateMillis;
|
private final long dateMillis;
|
||||||
private final boolean incompatible;
|
private final boolean incompatible;
|
||||||
|
private final List<RenderJob> renderQueue;
|
||||||
|
|
||||||
public GuiReplayEntry(File file, ReplayMetaData metaData, Image thumbImage) {
|
public GuiReplayEntry(File file, ReplayMetaData metaData, Image thumbImage, List<RenderJob> renderQueue) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
|
this.renderQueue = renderQueue;
|
||||||
|
|
||||||
name.setText(Formatting.UNDERLINE + Utils.fileNameToReplayName(file.getName()));
|
name.setText(Formatting.UNDERLINE + Utils.fileNameToReplayName(file.getName()));
|
||||||
if (StringUtils.isEmpty(metaData.getServerName())
|
if (StringUtils.isEmpty(metaData.getServerName())
|
||||||
@@ -512,6 +519,12 @@ public class GuiReplayViewer extends GuiScreen {
|
|||||||
duration.setText(Utils.convertSecondsToShortString(metaData.getDuration() / 1000));
|
duration.setText(Utils.convertSecondsToShortString(metaData.getDuration() / 1000));
|
||||||
addElements(null, durationPanel);
|
addElements(null, durationPanel);
|
||||||
|
|
||||||
|
if (!renderQueue.isEmpty()) {
|
||||||
|
renderQueueIcon.setTooltip(new GuiTooltip()
|
||||||
|
.setText(renderQueue.stream().map(RenderJob::getName).toArray(String[]::new)));
|
||||||
|
addElements(null, renderQueueIcon);
|
||||||
|
}
|
||||||
|
|
||||||
setLayout(new CustomLayout<GuiReplayEntry>() {
|
setLayout(new CustomLayout<GuiReplayEntry>() {
|
||||||
@Override
|
@Override
|
||||||
protected void layout(GuiReplayEntry container, int width, int height) {
|
protected void layout(GuiReplayEntry container, int width, int height) {
|
||||||
@@ -521,6 +534,10 @@ public class GuiReplayViewer extends GuiScreen {
|
|||||||
|
|
||||||
pos(infoPanel, width(thumbnail) + 5, 0);
|
pos(infoPanel, width(thumbnail) + 5, 0);
|
||||||
pos(version, width - width(version), 0);
|
pos(version, width - width(version), 0);
|
||||||
|
|
||||||
|
if (renderQueueIcon.getContainer() != null) {
|
||||||
|
pos(renderQueueIcon, width(thumbnail) - width(renderQueueIcon), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user