Refactor overlay renderer screenshot code into a draw manager

This will be required for #1350
This commit is contained in:
Levi
2018-04-28 13:26:39 -05:00
committed by Adam
parent d9e279a489
commit f8ac1f18b5
6 changed files with 106 additions and 35 deletions

View File

@@ -50,6 +50,7 @@ import net.runelite.client.game.ItemManager;
import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.MenuManager;
import net.runelite.client.plugins.PluginManager; import net.runelite.client.plugins.PluginManager;
import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.DrawManager;
import net.runelite.client.ui.TitleToolbar; import net.runelite.client.ui.TitleToolbar;
import net.runelite.client.ui.overlay.OverlayRenderer; import net.runelite.client.ui.overlay.OverlayRenderer;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -89,6 +90,9 @@ public class RuneLite
@Inject @Inject
private OverlayRenderer overlayRenderer; private OverlayRenderer overlayRenderer;
@Inject
private DrawManager drawManager;
@Inject @Inject
private SessionManager sessionManager; private SessionManager sessionManager;
@@ -166,6 +170,7 @@ public class RuneLite
// Register event listeners // Register event listeners
eventBus.register(clientUI); eventBus.register(clientUI);
eventBus.register(overlayRenderer); eventBus.register(overlayRenderer);
eventBus.register(drawManager);
eventBus.register(menuManager); eventBus.register(menuManager);
eventBus.register(chatMessageManager); eventBus.register(chatMessageManager);
eventBus.register(commandManager); eventBus.register(commandManager);

View File

@@ -69,6 +69,7 @@ import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.input.KeyManager; import net.runelite.client.input.KeyManager;
import net.runelite.client.input.MouseManager; import net.runelite.client.input.MouseManager;
import net.runelite.client.task.Scheduler; import net.runelite.client.task.Scheduler;
import net.runelite.client.ui.DrawManager;
import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayRenderer; import net.runelite.client.ui.overlay.OverlayRenderer;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
@@ -96,6 +97,7 @@ public class Hooks
private static final KeyManager keyManager = injector.getInstance(KeyManager.class); private static final KeyManager keyManager = injector.getInstance(KeyManager.class);
private static final ClientThread clientThread = injector.getInstance(ClientThread.class); private static final ClientThread clientThread = injector.getInstance(ClientThread.class);
private static final GameTick tick = new GameTick(); private static final GameTick tick = new GameTick();
private static final DrawManager renderHooks = injector.getInstance(DrawManager.class);
private static Dimension lastStretchedDimensions; private static Dimension lastStretchedDimensions;
private static BufferedImage stretchedImage; private static BufferedImage stretchedImage;
@@ -304,7 +306,7 @@ public class Hooks
// Draw the image onto the game canvas // Draw the image onto the game canvas
graphics.drawImage(image, 0, 0, client.getCanvas()); graphics.drawImage(image, 0, 0, client.getCanvas());
renderer.provideScreenshot(image); renderHooks.processDrawComplete(image);
} }
public static void drawRegion(Region region, int var1, int var2, int var3, int var4, int var5, int var6) public static void drawRegion(Region region, int var1, int var2, int var3, int var4, int var5, int var6)

View File

@@ -71,6 +71,7 @@ import net.runelite.api.widgets.WidgetInfo;
import static net.runelite.api.widgets.WidgetInfo.TO_GROUP; import static net.runelite.api.widgets.WidgetInfo.TO_GROUP;
import net.runelite.client.Notifier; import net.runelite.client.Notifier;
import static net.runelite.client.RuneLite.SCREENSHOT_DIR; import static net.runelite.client.RuneLite.SCREENSHOT_DIR;
import net.runelite.client.ui.DrawManager;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.input.KeyManager; import net.runelite.client.input.KeyManager;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
@@ -81,7 +82,6 @@ import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.FontManager; import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.NavigationButton;
import net.runelite.client.ui.TitleToolbar; import net.runelite.client.ui.TitleToolbar;
import net.runelite.client.ui.overlay.OverlayRenderer;
import net.runelite.client.util.Text; import net.runelite.client.util.Text;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import okhttp3.Call; import okhttp3.Call;
@@ -131,7 +131,7 @@ public class ScreenshotPlugin extends Plugin
private TitleToolbar titleToolbar; private TitleToolbar titleToolbar;
@Inject @Inject
private OverlayRenderer overlayRenderer; private DrawManager drawManager;
@Inject @Inject
private ScreenshotInput inputListener; private ScreenshotInput inputListener;
@@ -405,7 +405,7 @@ public class ScreenshotPlugin extends Plugin
return; return;
} }
overlayRenderer.requestScreenshot(image -> drawManager.requestNextFrameListener(image ->
{ {
BufferedImage screenshot = config.includeFrame() BufferedImage screenshot = config.includeFrame()
? new BufferedImage(clientUi.getWidth(), clientUi.getHeight(), BufferedImage.TYPE_INT_ARGB) ? new BufferedImage(clientUi.getWidth(), clientUi.getHeight(), BufferedImage.TYPE_INT_ARGB)

View File

@@ -0,0 +1,89 @@
/*
* Copyright (c) 2017, Levi <me@levischuck.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.ui;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
@Singleton
@Slf4j
public class DrawManager
{
private final List<Consumer<BufferedImage>> everyFrame = new CopyOnWriteArrayList<>();
private final Queue<Consumer<BufferedImage>> nextFrame = new ConcurrentLinkedQueue<>();
public void registerEveryFrameListener(Consumer<BufferedImage> everyFrameListener)
{
if (!everyFrame.contains(everyFrameListener))
{
everyFrame.add(everyFrameListener);
}
}
public void unregisterEveryFrameListener(Consumer<BufferedImage> everyFrameListener)
{
everyFrame.remove(everyFrameListener);
}
public void requestNextFrameListener(Consumer<BufferedImage> nextFrameListener)
{
nextFrame.add(nextFrameListener);
}
public void processDrawComplete(BufferedImage image)
{
for (Consumer<BufferedImage> everyFrameListener : everyFrame)
{
try
{
everyFrameListener.accept(image);
}
catch (Exception e)
{
log.error("Error in draw consumer", e);
}
}
Consumer<BufferedImage> nextFrameListener = nextFrame.poll();
while (nextFrameListener != null)
{
try
{
nextFrameListener.accept(image);
}
catch (Exception e)
{
log.error("Error in draw consumer", e);
}
nextFrameListener = nextFrame.poll();
}
}
}

View File

@@ -33,15 +33,12 @@ import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.inject.Inject; import javax.inject.Inject;
@@ -95,7 +92,6 @@ public class OverlayRenderer extends MouseListener implements KeyListener
private final RuneLiteConfig runeLiteConfig; private final RuneLiteConfig runeLiteConfig;
private final TooltipOverlay tooltipOverlay; private final TooltipOverlay tooltipOverlay;
private final List<Overlay> allOverlays = new CopyOnWriteArrayList<>(); private final List<Overlay> allOverlays = new CopyOnWriteArrayList<>();
private final ConcurrentLinkedQueue<Consumer<BufferedImage>> screenshotRequests = new ConcurrentLinkedQueue<>();
private final String runeliteGroupName = RuneLiteConfig.class.getAnnotation(ConfigGroup.class).keyName(); private final String runeliteGroupName = RuneLiteConfig.class.getAnnotation(ConfigGroup.class).keyName();
// Overlay movement variables // Overlay movement variables
@@ -655,25 +651,4 @@ public class OverlayRenderer extends MouseListener implements KeyListener
final String locationKey = overlay.getClass().getSimpleName() + OVERLAY_CONFIG_PREFERRED_POSITION; final String locationKey = overlay.getClass().getSimpleName() + OVERLAY_CONFIG_PREFERRED_POSITION;
return configManager.getConfiguration(runeliteGroupName, locationKey, OverlayPosition.class); return configManager.getConfiguration(runeliteGroupName, locationKey, OverlayPosition.class);
} }
public void provideScreenshot(BufferedImage image)
{
Consumer<BufferedImage> consumer;
while ((consumer = screenshotRequests.poll()) != null)
{
try
{
consumer.accept(image);
}
catch (Exception ex)
{
log.warn("error in screenshot callback", ex);
}
}
}
public void requestScreenshot(Consumer<BufferedImage> consumer)
{
screenshotRequests.add(consumer);
}
} }

View File

@@ -43,7 +43,7 @@ import static net.runelite.api.widgets.WidgetInfo.PACK;
import net.runelite.client.Notifier; import net.runelite.client.Notifier;
import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.overlay.OverlayRenderer; import net.runelite.client.ui.DrawManager;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -83,7 +83,7 @@ public class ScreenshotPluginTest
@Mock @Mock
@Bind @Bind
private OverlayRenderer overlayRenderer; DrawManager drawManager;
@Mock @Mock
@Bind @Bind
@@ -146,7 +146,7 @@ public class ScreenshotPluginTest
event.setWidget(widget); event.setWidget(widget);
screenshotPlugin.hideWidgets(event); screenshotPlugin.hideWidgets(event);
verify(overlayRenderer).requestScreenshot(Matchers.any(Consumer.class)); verify(drawManager).requestNextFrameListener(Matchers.any(Consumer.class));
} }
@Test @Test
@@ -166,7 +166,7 @@ public class ScreenshotPluginTest
event.setWidget(widget); event.setWidget(widget);
screenshotPlugin.hideWidgets(event); screenshotPlugin.hideWidgets(event);
verify(overlayRenderer).requestScreenshot(Matchers.any(Consumer.class)); verify(drawManager).requestNextFrameListener(Matchers.any(Consumer.class));
} }
@Test @Test
@@ -186,7 +186,7 @@ public class ScreenshotPluginTest
event.setWidget(widget); event.setWidget(widget);
screenshotPlugin.hideWidgets(event); screenshotPlugin.hideWidgets(event);
verify(overlayRenderer).requestScreenshot(Matchers.any(Consumer.class)); verify(drawManager).requestNextFrameListener(Matchers.any(Consumer.class));
} }
@Test @Test
@@ -206,6 +206,6 @@ public class ScreenshotPluginTest
event.setWidget(widget); event.setWidget(widget);
screenshotPlugin.hideWidgets(event); screenshotPlugin.hideWidgets(event);
verify(overlayRenderer).requestScreenshot(Matchers.any(Consumer.class)); verify(drawManager).requestNextFrameListener(Matchers.any(Consumer.class));
} }
} }