screenshot plugin: fix to paint client ui from EDT
Fix deadlock between the game thread and the EDT
This commit is contained in:
@@ -40,6 +40,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
@@ -51,6 +52,7 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Inject;
|
||||
import javax.swing.SwingUtilities;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -524,7 +526,23 @@ public class ScreenshotPlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
Consumer<Image> screenshotConsumer = image ->
|
||||
Consumer<Image> imageCallback = (img) ->
|
||||
{
|
||||
// This callback is on the game thread, move to executor thread
|
||||
executor.submit(() -> takeScreenshot(fileName, img));
|
||||
};
|
||||
|
||||
if (config.displayDate())
|
||||
{
|
||||
screenshotOverlay.queueForTimestamp(imageCallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawManager.requestNextFrameListener(imageCallback);
|
||||
}
|
||||
}
|
||||
|
||||
private void takeScreenshot(String fileName, Image image)
|
||||
{
|
||||
BufferedImage screenshot = config.includeFrame()
|
||||
? new BufferedImage(clientUi.getWidth(), clientUi.getHeight(), BufferedImage.TYPE_INT_ARGB)
|
||||
@@ -538,7 +556,14 @@ public class ScreenshotPlugin extends Plugin
|
||||
if (config.includeFrame())
|
||||
{
|
||||
// Draw the client frame onto the screenshot
|
||||
clientUi.paint(graphics);
|
||||
try
|
||||
{
|
||||
SwingUtilities.invokeAndWait(() -> clientUi.paint(graphics));
|
||||
}
|
||||
catch (InterruptedException | InvocationTargetException e)
|
||||
{
|
||||
log.warn("unable to paint client UI on screenshot", e);
|
||||
}
|
||||
|
||||
// Evaluate the position of the game inside the frame
|
||||
final Point canvasOffset = clientUi.getCanvasOffset();
|
||||
@@ -572,8 +597,6 @@ public class ScreenshotPlugin extends Plugin
|
||||
|
||||
playerFolder.mkdirs();
|
||||
|
||||
executor.execute(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
File screenshotFile = new File(playerFolder, fileName + ".png");
|
||||
@@ -593,17 +616,6 @@ public class ScreenshotPlugin extends Plugin
|
||||
{
|
||||
log.warn("error writing screenshot", ex);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (config.displayDate())
|
||||
{
|
||||
screenshotOverlay.queueForTimestamp(screenshotConsumer);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawManager.requestNextFrameListener(screenshotConsumer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -543,6 +543,7 @@ public class ClientUI
|
||||
*/
|
||||
public void paint(final Graphics graphics)
|
||||
{
|
||||
assert SwingUtilities.isEventDispatchThread() : "paint must be called on EDT";
|
||||
frame.paint(graphics);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user