instance map: fix various races between game and event threads
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.instancemap;
|
package net.runelite.client.plugins.instancemap;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.MouseWheelEvent;
|
import java.awt.event.MouseWheelEvent;
|
||||||
@@ -114,7 +115,12 @@ public class InstanceMapInputListener extends MouseListener implements KeyListen
|
|||||||
|
|
||||||
private boolean isWithinOverlay(int x, int y)
|
private boolean isWithinOverlay(int x, int y)
|
||||||
{
|
{
|
||||||
return (x >= OVERLAY_POSITION.getX() && x <= OVERLAY_POSITION.getX() + plugin.getOverlaySize().width &&
|
Dimension dimm = plugin.getOverlaySize();
|
||||||
y >= OVERLAY_POSITION.getY() && y <= OVERLAY_POSITION.getY() + plugin.getOverlaySize().height);
|
if (dimm == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (x >= OVERLAY_POSITION.getX() && x <= OVERLAY_POSITION.getX() + dimm.width &&
|
||||||
|
y >= OVERLAY_POSITION.getY() && y <= OVERLAY_POSITION.getY() + dimm.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,26 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.instancemap;
|
package net.runelite.client.plugins.instancemap;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.GameObject;
|
||||||
|
import net.runelite.api.GroundObject;
|
||||||
|
import net.runelite.api.IndexedSprite;
|
||||||
|
import net.runelite.api.ObjectComposition;
|
||||||
|
import net.runelite.api.Player;
|
||||||
|
import net.runelite.api.Point;
|
||||||
|
import net.runelite.api.Region;
|
||||||
|
import net.runelite.api.SceneTileModel;
|
||||||
|
import net.runelite.api.SceneTilePaint;
|
||||||
|
import net.runelite.api.SpritePixels;
|
||||||
|
import net.runelite.api.Tile;
|
||||||
|
import net.runelite.api.WallObject;
|
||||||
|
import net.runelite.api.events.GameStateChanged;
|
||||||
|
import net.runelite.api.events.MapRegionChanged;
|
||||||
import static net.runelite.client.plugins.instancemap.PixelMaps.ALL;
|
import static net.runelite.client.plugins.instancemap.PixelMaps.ALL;
|
||||||
import static net.runelite.client.plugins.instancemap.PixelMaps.BOTTOM;
|
import static net.runelite.client.plugins.instancemap.PixelMaps.BOTTOM;
|
||||||
import static net.runelite.client.plugins.instancemap.PixelMaps.BOTTOM_LEFT_CORNER;
|
import static net.runelite.client.plugins.instancemap.PixelMaps.BOTTOM_LEFT_CORNER;
|
||||||
@@ -44,27 +64,6 @@ import static net.runelite.client.plugins.instancemap.WallOffset.BOTTOM_RIGHT;
|
|||||||
import static net.runelite.client.plugins.instancemap.WallOffset.NONE;
|
import static net.runelite.client.plugins.instancemap.WallOffset.NONE;
|
||||||
import static net.runelite.client.plugins.instancemap.WallOffset.TOP_LEFT;
|
import static net.runelite.client.plugins.instancemap.WallOffset.TOP_LEFT;
|
||||||
import static net.runelite.client.plugins.instancemap.WallOffset.TOP_RIGHT;
|
import static net.runelite.client.plugins.instancemap.WallOffset.TOP_RIGHT;
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import net.runelite.api.Client;
|
|
||||||
import net.runelite.api.GameObject;
|
|
||||||
import net.runelite.api.GroundObject;
|
|
||||||
import net.runelite.api.IndexedSprite;
|
|
||||||
import net.runelite.api.ObjectComposition;
|
|
||||||
import net.runelite.api.Player;
|
|
||||||
import net.runelite.api.Point;
|
|
||||||
import net.runelite.api.Region;
|
|
||||||
import net.runelite.api.SceneTileModel;
|
|
||||||
import net.runelite.api.SceneTilePaint;
|
|
||||||
import net.runelite.api.SpritePixels;
|
|
||||||
import net.runelite.api.Tile;
|
|
||||||
import net.runelite.api.WallObject;
|
|
||||||
import net.runelite.api.events.GameStateChanged;
|
|
||||||
import net.runelite.api.events.MapRegionChanged;
|
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
@@ -106,13 +105,13 @@ class InstanceMapOverlay extends Overlay
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Saved image of the region, no reason to draw the whole thing every
|
* Saved image of the region, no reason to draw the whole thing every
|
||||||
* frame. This is redrawn in the drawToBufferedImage method
|
* frame.
|
||||||
*/
|
*/
|
||||||
private BufferedImage mapImage;
|
private volatile BufferedImage mapImage;
|
||||||
private boolean showMap = false;
|
private volatile boolean showMap = false;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
InstanceMapOverlay(@Nullable Client client)
|
InstanceMapOverlay(Client client)
|
||||||
{
|
{
|
||||||
setPosition(OverlayPosition.DYNAMIC);
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
||||||
@@ -121,12 +120,14 @@ class InstanceMapOverlay extends Overlay
|
|||||||
|
|
||||||
public Dimension getInstanceMapDimension()
|
public Dimension getInstanceMapDimension()
|
||||||
{
|
{
|
||||||
if (mapImage == null)
|
BufferedImage image = mapImage;
|
||||||
|
|
||||||
|
if (image == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Dimension(mapImage.getWidth(), mapImage.getHeight());
|
return new Dimension(image.getWidth(), image.getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMapShown()
|
public boolean isMapShown()
|
||||||
@@ -140,20 +141,21 @@ class InstanceMapOverlay extends Overlay
|
|||||||
*
|
*
|
||||||
* @param show Whether or not the map should be shown.
|
* @param show Whether or not the map should be shown.
|
||||||
*/
|
*/
|
||||||
public void setShowMap(boolean show)
|
public synchronized void setShowMap(boolean show)
|
||||||
{
|
{
|
||||||
showMap = show;
|
showMap = show;
|
||||||
if (showMap)
|
if (showMap)
|
||||||
{
|
{
|
||||||
viewedPlane = client.getPlane();//When we open the map show the current plane
|
//When we open the map show the current plane
|
||||||
mapImage = drawMapImage(getTiles());
|
viewedPlane = client.getPlane();
|
||||||
}
|
}
|
||||||
|
mapImage = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increases the viewed plane. The maximum viewedPlane is 3
|
* Increases the viewed plane. The maximum viewedPlane is 3
|
||||||
*/
|
*/
|
||||||
public void onAscend()
|
public synchronized void onAscend()
|
||||||
{
|
{
|
||||||
if (viewedPlane >= MAX_PLANE)
|
if (viewedPlane >= MAX_PLANE)
|
||||||
{
|
{
|
||||||
@@ -161,13 +163,13 @@ class InstanceMapOverlay extends Overlay
|
|||||||
}
|
}
|
||||||
|
|
||||||
viewedPlane++;//Increment plane
|
viewedPlane++;//Increment plane
|
||||||
mapImage = drawMapImage(getTiles());
|
mapImage = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decreases the viewed plane. The minimum viewedPlane is 0
|
* Decreases the viewed plane. The minimum viewedPlane is 0
|
||||||
*/
|
*/
|
||||||
public void onDescend()
|
public synchronized void onDescend()
|
||||||
{
|
{
|
||||||
if (viewedPlane <= MIN_PLANE)
|
if (viewedPlane <= MIN_PLANE)
|
||||||
{
|
{
|
||||||
@@ -175,7 +177,7 @@ class InstanceMapOverlay extends Overlay
|
|||||||
}
|
}
|
||||||
|
|
||||||
viewedPlane--;
|
viewedPlane--;
|
||||||
mapImage = drawMapImage(getTiles());
|
mapImage = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -186,12 +188,22 @@ class InstanceMapOverlay extends Overlay
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapImage == null)
|
// avoid locking on fast path by creating a local ref
|
||||||
|
BufferedImage image = mapImage;
|
||||||
|
|
||||||
|
if (image == null)
|
||||||
{
|
{
|
||||||
mapImage = drawMapImage(getTiles());
|
image = drawMapImage(getTiles());
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
if (showMap)
|
||||||
|
{
|
||||||
|
mapImage = image;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics.drawImage(mapImage, OVERLAY_POSITION.getX(), OVERLAY_POSITION.getY(), null);
|
graphics.drawImage(image, OVERLAY_POSITION.getX(), OVERLAY_POSITION.getY(), null);
|
||||||
|
|
||||||
if (client.getPlane() == viewedPlane)//If we are not viewing the plane we are on, don't show player's position
|
if (client.getPlane() == viewedPlane)//If we are not viewing the plane we are on, don't show player's position
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user