diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index a68e51a3b0..5c33240e16 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -24,6 +24,7 @@ */ package net.runelite.client; +import net.runelite.client.game.ItemManager; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.SubscriberExceptionContext; import com.google.gson.Gson; diff --git a/runelite-client/src/main/java/net/runelite/client/ItemManager.java b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java similarity index 59% rename from runelite-client/src/main/java/net/runelite/client/ItemManager.java rename to runelite-client/src/main/java/net/runelite/client/game/ItemManager.java index 9d12828fb2..2bab56cf5b 100644 --- a/runelite-client/src/main/java/net/runelite/client/ItemManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java @@ -22,99 +22,77 @@ * (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; +package net.runelite.client.game; import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; -import com.google.common.util.concurrent.MoreExecutors; import java.io.IOException; import java.util.concurrent.TimeUnit; +import net.runelite.client.RuneLite; import net.runelite.http.api.item.ItemClient; import net.runelite.http.api.item.ItemPrice; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class ItemManager { - private static class ItemLoader extends CacheLoader - { - private static final Logger logger = LoggerFactory.getLogger(ItemLoader.class); + /** + * not yet looked up + */ - private final ListeningExecutorService executorService; - private final ItemClient client = new ItemClient(); - - ItemLoader(RuneLite runelite) - { - executorService = MoreExecutors.listeningDecorator(runelite.getExecutor()); - } - - @Override - public ItemPrice load(Integer key) throws Exception - { - // guava's Cache doesn't support null values - return EMPTY; - } - - @Override - public ListenableFuture reload(Integer key, ItemPrice oldValue) - { - logger.debug("Submitting lookup for item {}", key); - - return executorService.submit(() -> fetch(key)); - } - - private ItemPrice fetch(Integer key) - { - try - { - ItemPrice itemPrice = client.lookupItemPrice(key); - if (itemPrice == null) - { - return NONE; - } - return itemPrice; - } - catch (IOException ex) - { - logger.warn("unable to look up item!", ex); - return NONE; - } - } - }; + static final ItemPrice EMPTY = new ItemPrice(); + /** + * has no price + */ + static final ItemPrice NONE = new ItemPrice(); + private final ItemClient client = new ItemClient(); private final LoadingCache itemPrices; - private static final ItemPrice EMPTY = new ItemPrice(); - private static final ItemPrice NONE = new ItemPrice(); public ItemManager(RuneLite runelite) { itemPrices = CacheBuilder.newBuilder() - .concurrencyLevel(4) // from runelite's ScheduledExecutorService .maximumSize(512L) .expireAfterAccess(1, TimeUnit.HOURS) - .build(new ItemLoader(runelite)); + .build(new ItemPriceLoader(runelite, client)); } + /** + * Look up an item's price asynchronously. + * + * @param itemId + * @return the price, or null if the price is not yet loaded + */ public ItemPrice get(int itemId) { ItemPrice itemPrice = itemPrices.getIfPresent(itemId); if (itemPrice != null && itemPrice != EMPTY) { - if (itemPrice == NONE) - { - return null; - } - - return itemPrice; + return itemPrice == NONE ? null : itemPrice; } itemPrices.refresh(itemId); return null; } + /** + * Look up an item's price synchronously + * + * @param itemId + * @return + * @throws IOException + */ + public ItemPrice getItemPrice(int itemId) throws IOException + { + ItemPrice itemPrice = itemPrices.getIfPresent(itemId); + if (itemPrice != null && itemPrice != EMPTY) + { + return itemPrice == NONE ? null : itemPrice; + } + + itemPrice = client.lookupItemPrice(itemId); + itemPrices.put(itemId, itemPrice); + return itemPrice; + } + /** * Convert a quantity to stack size * diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemPriceLoader.java b/runelite-client/src/main/java/net/runelite/client/game/ItemPriceLoader.java new file mode 100644 index 0000000000..c2fbadb39c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemPriceLoader.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2017, Adam + * 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.game; + +import com.google.common.cache.CacheLoader; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import java.io.IOException; +import net.runelite.client.RuneLite; +import static net.runelite.client.game.ItemManager.EMPTY; +import static net.runelite.client.game.ItemManager.NONE; +import net.runelite.http.api.item.ItemClient; +import net.runelite.http.api.item.ItemPrice; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class ItemPriceLoader extends CacheLoader +{ + private static final Logger logger = LoggerFactory.getLogger(ItemPriceLoader.class); + + private final ListeningExecutorService executorService; + private final ItemClient client; + + ItemPriceLoader(RuneLite runelite, ItemClient client) + { + this.executorService = MoreExecutors.listeningDecorator(runelite.getExecutor()); + this.client = client; + } + + @Override + public ItemPrice load(Integer key) throws Exception + { + // guava's Cache doesn't support null values + return EMPTY; + } + + @Override + public ListenableFuture reload(Integer key, ItemPrice oldValue) + { + logger.debug("Submitting lookup for item {}", key); + + return executorService.submit(() -> fetch(key)); + } + + private ItemPrice fetch(Integer key) + { + try + { + ItemPrice itemPrice = client.lookupItemPrice(key); + if (itemPrice == null) + { + return NONE; + } + return itemPrice; + } + catch (IOException ex) + { + logger.warn("unable to look up item!", ex); + return NONE; + } + } +}; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java index 713e9a3539..719d685be9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java @@ -48,7 +48,7 @@ import net.runelite.api.Point; import net.runelite.api.Region; import net.runelite.api.Tile; import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.ItemManager; +import net.runelite.client.game.ItemManager; import net.runelite.client.RuneLite; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayPosition;