Persist render queue in replay file (closes #317)
This commit is contained in:
@@ -1,9 +1,24 @@
|
|||||||
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.render.utils.RenderJob;
|
import com.replaymod.render.utils.RenderJob;
|
||||||
|
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.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.simplepathing.SPTimeline;
|
||||||
|
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;
|
||||||
import net.minecraft.util.crash.CrashException;
|
import net.minecraft.util.crash.CrashException;
|
||||||
@@ -13,12 +28,16 @@ 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;
|
||||||
|
|
||||||
import static com.replaymod.core.versions.MCVer.*;
|
|
||||||
|
|
||||||
public class ReplayModRender extends EventRegistrations implements Module {
|
public class ReplayModRender extends EventRegistrations implements Module {
|
||||||
{ instance = this; }
|
{ instance = this; }
|
||||||
public static ReplayModRender instance;
|
public static ReplayModRender instance;
|
||||||
@@ -27,6 +46,7 @@ public class ReplayModRender extends EventRegistrations implements Module {
|
|||||||
|
|
||||||
public static Logger LOGGER = LogManager.getLogger();
|
public static Logger LOGGER = LogManager.getLogger();
|
||||||
|
|
||||||
|
private ReplayFile replayFile;
|
||||||
private final List<RenderJob> renderQueue = new ArrayList<>();
|
private final List<RenderJob> renderQueue = new ArrayList<>();
|
||||||
|
|
||||||
public ReplayModRender(ReplayMod core) {
|
public ReplayModRender(ReplayMod core) {
|
||||||
@@ -41,8 +61,6 @@ public class ReplayModRender extends EventRegistrations implements Module {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initClient() {
|
public void initClient() {
|
||||||
on(ReplayClosedCallback.EVENT, replayHandler -> renderQueue.clear());
|
|
||||||
|
|
||||||
register();
|
register();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,4 +82,87 @@ public class ReplayModRender extends EventRegistrations implements Module {
|
|||||||
public List<RenderJob> getRenderQueue() {
|
public List<RenderJob> getRenderQueue() {
|
||||||
return renderQueue;
|
return renderQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ on(ReplayOpenedCallback.EVENT, this::onReplayOpened); }
|
||||||
|
private void onReplayOpened(ReplayHandler replayHandler) {
|
||||||
|
replayFile = replayHandler.getReplayFile();
|
||||||
|
try {
|
||||||
|
renderQueue.addAll(doLoadRenderQueue(replayFile));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new CrashException(CrashReport.create(e, "Reading timeline"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ on(ReplayClosedCallback.EVENT, replayHandler -> onReplayClosed()); }
|
||||||
|
private void onReplayClosed() {
|
||||||
|
renderQueue.clear();
|
||||||
|
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() {
|
||||||
|
try {
|
||||||
|
doSaveRenderQueue(replayFile, renderQueue);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
VanillaGuiScreen screen = VanillaGuiScreen.setup(getCore().getMinecraft().currentScreen);
|
||||||
|
CrashReport report = CrashReport.create(e, "Reading timeline");
|
||||||
|
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("");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,8 @@ public class GuiRenderQueue extends AbstractGuiPopup<GuiRenderQueue> implements
|
|||||||
}).addElements(null, title, list, buttonPanel);
|
}).addElements(null, title, list, buttonPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final List<RenderJob> jobs = ReplayModRender.instance.getRenderQueue();
|
private final ReplayModRender mod = ReplayModRender.instance;
|
||||||
|
private final List<RenderJob> jobs = mod.getRenderQueue();
|
||||||
|
|
||||||
public GuiRenderQueue(AbstractGuiScreen<?> container, ReplayHandler replayHandler, Supplier<Timeline> timelineSupplier) {
|
public GuiRenderQueue(AbstractGuiScreen<?> container, ReplayHandler replayHandler, Supplier<Timeline> timelineSupplier) {
|
||||||
super(container);
|
super(container);
|
||||||
@@ -131,6 +132,7 @@ public class GuiRenderQueue extends AbstractGuiPopup<GuiRenderQueue> implements
|
|||||||
}
|
}
|
||||||
selectedEntries.clear();
|
selectedEntries.clear();
|
||||||
updateButtons();
|
updateButtons();
|
||||||
|
mod.saveRenderQueue();
|
||||||
});
|
});
|
||||||
|
|
||||||
renderButton.onClick(() -> {
|
renderButton.onClick(() -> {
|
||||||
@@ -214,6 +216,7 @@ public class GuiRenderQueue extends AbstractGuiPopup<GuiRenderQueue> implements
|
|||||||
jobs.add(newJob);
|
jobs.add(newJob);
|
||||||
list.getListPanel().addElements(null, new Entry(newJob));
|
list.getListPanel().addElements(null, new Entry(newJob));
|
||||||
updateButtons();
|
updateButtons();
|
||||||
|
mod.saveRenderQueue();
|
||||||
|
|
||||||
// Need to close the inner popup before we can open the outer one
|
// Need to close the inner popup before we can open the outer one
|
||||||
close();
|
close();
|
||||||
|
|||||||
Reference in New Issue
Block a user