Merge pull request #3099 from open-osrs/EvictingDualNodeHashTable

This commit is contained in:
Owain van Brakel
2021-12-21 20:06:20 +01:00
committed by GitHub
11 changed files with 321 additions and 44 deletions

View File

@@ -133,13 +133,6 @@ public interface ItemComposition extends ParamHolder
*/
void resetShiftClickActionIndex();
/**
* With this you can make certain (ground) items look like different ones.
*
* @param id The itemID of the item with desired model
*/
void setModelOverride(int id);
/**
* Gets the model ID of the inventory item.
*

View File

@@ -145,6 +145,7 @@ import net.runelite.rs.api.RSChatChannel;
import net.runelite.rs.api.RSClanChannel;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSEnumComposition;
import net.runelite.rs.api.RSEvictingDualNodeHashTable;
import net.runelite.rs.api.RSFriendSystem;
import net.runelite.rs.api.RSIndexedSprite;
import net.runelite.rs.api.RSInterfaceParent;
@@ -1767,6 +1768,13 @@ public abstract class RSClientMixin implements RSClient
updateCamera();
}
@Inject
@MethodHook(value = "draw", end = true)
public void drawEnd(boolean var1)
{
checkResize();
}
@MethodHook("drawInterface")
@Inject
public static void preRenderWidgetLayer(Widget[] widgets, int parentId, int minX, int minY, int maxX, int maxY, int x, int y, int var8)
@@ -2695,5 +2703,68 @@ public abstract class RSClientMixin implements RSClient
{
client.getCallbacks().tick();
}
@Inject
public static void check(String name, RSEvictingDualNodeHashTable dualNodeHashTable)
{
boolean var3 = dualNodeHashTable.isTrashing();
dualNodeHashTable.setThreshold(dualNodeHashTable.getThreshold() * 0.92F + (var3 ? 0.07999998F : 0.0F));
if (var3)
{
if (dualNodeHashTable.getThreshold() > 0.2F)
{
client.getLogger().trace("cache {} is thrashing", name);
}
if (dualNodeHashTable.getThreshold() > 0.9F && dualNodeHashTable.getCapacity() < dualNodeHashTable.getTmpCapacity() * 8)
{
dualNodeHashTable.increaseCapacity(dualNodeHashTable.getCapacity() * 2);
client.getLogger().info("cache {} thrashing, enlarging to {} entries", name, dualNodeHashTable.getCapacity());
}
}
dualNodeHashTable.getDeque().add(dualNodeHashTable.getDualNode());
}
@Inject
public static void checkResize()
{
check("Script_cached", client.getScriptCache());
check("StructDefinition_cached", client.getRSStructCompositionCache());
check("HealthBarDefinition_cached", client.getHealthBarCache());
check("HealthBarDefinition_cachedSprites", client.getHealthBarSpriteCache());
check("ObjectDefinition_cachedModels", client.getObjectDefinitionModelsCache());
check("Widget_cachedSprites", client.getWidgetSpriteCache());
check("ItemDefinition_cached", client.getItemCompositionCache());
check("VarbitDefinition_cached", client.getVarbitCache());
check("EnumDefinition_cached", client.getEnumDefinitionCache());
check("FloorUnderlayDefinition_cached", client.getFloorUnderlayDefinitionCache());
check("FloorOverlayDefinition_cached", client.getFloorOverlayDefinitionCache());
check("HitSplatDefinition_cached", client.getHitSplatDefinitionCache());
check("HitSplatDefinition_cachedSprites", client.getHitSplatDefinitionSpritesCache());
check("HitSplatDefinition_cachedFonts", client.getHitSplatDefinitionDontsCache());
check("InvDefinition_cached", client.getInvDefinitionCache());
check("ItemDefinition_cachedModels", client.getItemDefinitionModelsCache());
check("ItemDefinition_cachedSprites", client.getItemDefinitionSpritesCache());
check("KitDefinition_cached", client.getKitDefinitionCache());
check("NpcDefinition_cached", client.getNpcDefinitionCache());
check("NpcDefinition_cachedModels", client.getNpcDefinitionModelsCache());
check("ObjectDefinition_cached", client.getObjectDefinitionCache());
check("ObjectDefinition_cachedModelData", client.getObjectDefinitionModelDataCache());
check("ObjectDefinition_cachedEntities", client.getObjectDefinitionEntitiesCache());
check("ParamDefinition_cached", client.getParamDefinitionCache());
check("PlayerAppearance_cachedModels", client.getPlayerAppearanceModelsCache());
check("SequenceDefinition_cached", client.getSequenceDefinitionCache());
check("SequenceDefinition_cachedFrames", client.getSequenceDefinitionFramesCache());
check("SequenceDefinition_cachedModel", client.getSequenceDefinitionModelsCache());
check("SpotAnimationDefinition_cached", client.getSpotAnimationDefinitionCache());
check("SpotAnimationDefinition_cachedModels", client.getSpotAnimationDefinitionModlesCache());
check("VarcInt_cached", client.getVarcIntCache());
check("VarpDefinition_cached", client.getVarpDefinitionCache());
check("Widget_cachedModels", client.getModelsCache());
check("Widget_cachedFonts", client.getFontsCache());
check("Widget_cachedSpriteMasks", client.getSpriteMasksCache());
check("WorldMapElement_cachedSprites", client.getSpritesCache());
}
}

View File

@@ -0,0 +1,84 @@
package net.runelite.mixins;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Shadow;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSEvictingDualNodeHashTable;
import net.runelite.rs.api.RSIterableNodeHashTable;
@Mixin(RSEvictingDualNodeHashTable.class)
public abstract class RSEvictingDualNodeHashTableMixin implements RSEvictingDualNodeHashTable
{
@Shadow("client")
private static RSClient client;
@Inject
public float threshold;
@Inject
public int tmpCapacity;
@Inject
RSEvictingDualNodeHashTableMixin()
{
setTmpCapacity(this.getCapacity());
}
@Inject
public float getThreshold()
{
return threshold;
}
@Inject
public void setThreshold(float threshold)
{
this.threshold = threshold;
}
@Inject
public int getTmpCapacity()
{
return tmpCapacity;
}
@Inject
public void setTmpCapacity(int tmpCapacity)
{
this.tmpCapacity = tmpCapacity;
}
@Inject
public boolean isTrashing()
{
return this.getRemainingCapacity() <= 0 && this.getDualNode().previousDual() == null;
}
@Inject
public void resize(int newSize)
{
this.increaseCapacity(newSize);
this.tmpCapacity = this.getCapacity();
}
@Inject
public void increaseCapacity(int newSize)
{
if (newSize > this.getCapacity())
{
int i;
for (i = 1; i < newSize; i += i)
{
// ignore
}
this.setCapacity(i);
this.reset();
RSIterableNodeHashTable iterableNodeHashTable = client.createIterableNodeHashTable(i);
this.setHashTable(iterableNodeHashTable);
}
}
}

View File

@@ -8,8 +8,8 @@ import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Replace;
import net.runelite.api.mixins.Shadow;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSEvictingDualNodeHashTable;
import net.runelite.rs.api.RSItemComposition;
import net.runelite.rs.api.RSModel;
@Mixin(RSItemComposition.class)
public abstract class RSItemCompositionMixin implements RSItemComposition
@@ -22,19 +22,12 @@ public abstract class RSItemCompositionMixin implements RSItemComposition
@Inject
private int shiftClickActionIndex = DEFAULT_CUSTOM_SHIFT_CLICK_INDEX;
@MethodHook(value = "<clinit>", end = true)
@Inject
private int modelOverride = -1;
@Override
@Inject
public void setModelOverride(int id)
{
modelOverride = id;
}
@Inject
RSItemCompositionMixin()
public static void rl$clinit()
{
RSEvictingDualNodeHashTable cachedModels2 = client.getItemCompositionCache();
cachedModels2.resize(1024);
}
@Inject
@@ -74,18 +67,6 @@ public abstract class RSItemCompositionMixin implements RSItemComposition
client.getCallbacks().post(event);
}
@Copy("getModel")
@Replace("getModel")
public RSModel copy$getModel(int quantity)
{
if (modelOverride == -1)
{
return copy$getModel(quantity);
}
return client.getRSItemDefinition(modelOverride).getModel(quantity);
}
@Inject
@Override
public int getHaPrice()

View File

@@ -2,10 +2,10 @@ package net.runelite.mixins;
import net.runelite.api.IterableHashTable;
import net.runelite.api.Node;
import net.runelite.api.NodeCache;
import net.runelite.api.mixins.*;
import net.runelite.rs.api.RSBuffer;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSEvictingDualNodeHashTable;
import net.runelite.rs.api.RSObjectComposition;
@Mixin(RSObjectComposition.class)
@@ -17,14 +17,12 @@ public abstract class RSObjectCompositionMixin implements RSObjectComposition
@Inject
private int accessBitMask = 0;
@MethodHook(value = "<init>", end = true)
@MethodHook(value = "<clinit>", end = true)
@Inject
public void rl$init()
public static void rl$clinit()
{
NodeCache cachedModels2 = client.getCachedModels2();
cachedModels2.setCapacity(256);
cachedModels2.setRemainingCapacity(256);
cachedModels2.reset();
RSEvictingDualNodeHashTable objectDefinitionModelsCache = client.getObjectDefinitionModelsCache();
objectDefinitionModelsCache.resize(256);
}
@Inject

View File

@@ -0,0 +1,24 @@
package net.runelite.mixins;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.MethodHook;
import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Shadow;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSEvictingDualNodeHashTable;
import net.runelite.rs.api.RSVarbitComposition;
@Mixin(RSVarbitComposition.class)
public abstract class RSVarbitCompositionMixin implements RSVarbitComposition
{
@Shadow("client")
private static RSClient client;
@MethodHook(value = "<clinit>", end = true)
@Inject
public static void rl$clinit()
{
RSEvictingDualNodeHashTable varbitCache = client.getVarbitCache();
varbitCache.resize(256);
}
}

View File

@@ -926,7 +926,7 @@ public interface RSClient extends RSGameEngine, Client
int[][] getOccupiedTilesTick();
@Import("ObjectDefinition_cachedModels")
RSEvictingDualNodeHashTable getCachedModels2();
RSEvictingDualNodeHashTable getObjectDefinitionModelsCache();
@Import("Scene_drawnCount")
int getCycle();
@@ -1483,4 +1483,91 @@ public interface RSClient extends RSGameEngine, Client
@Import("objectSounds")
Deque<AmbientSoundEffect> getAmbientSoundEffects();
@Import("EnumDefinition_cached")
RSEvictingDualNodeHashTable getEnumDefinitionCache();
@Import("FloorUnderlayDefinition_cached")
RSEvictingDualNodeHashTable getFloorUnderlayDefinitionCache();
@Import("FloorOverlayDefinition_cached")
RSEvictingDualNodeHashTable getFloorOverlayDefinitionCache();
@Import("HitSplatDefinition_cached")
RSEvictingDualNodeHashTable getHitSplatDefinitionCache();
@Import("HitSplatDefinition_cachedSprites")
RSEvictingDualNodeHashTable getHitSplatDefinitionSpritesCache();
@Import("HitSplatDefinition_cachedFonts")
RSEvictingDualNodeHashTable getHitSplatDefinitionDontsCache();
@Import("InvDefinition_cached")
RSEvictingDualNodeHashTable getInvDefinitionCache();
@Import("ItemDefinition_cachedModels")
RSEvictingDualNodeHashTable getItemDefinitionModelsCache();
@Import("ItemDefinition_cachedSprites")
RSEvictingDualNodeHashTable getItemDefinitionSpritesCache();
@Import("KitDefinition_cached")
RSEvictingDualNodeHashTable getKitDefinitionCache();
@Import("NpcDefinition_cached")
RSEvictingDualNodeHashTable getNpcDefinitionCache();
@Import("NpcDefinition_cachedModels")
RSEvictingDualNodeHashTable getNpcDefinitionModelsCache();
@Import("ObjectDefinition_cached")
RSEvictingDualNodeHashTable getObjectDefinitionCache();
@Import("ObjectDefinition_cachedModelData")
RSEvictingDualNodeHashTable getObjectDefinitionModelDataCache();
@Import("ObjectDefinition_cachedEntities")
RSEvictingDualNodeHashTable getObjectDefinitionEntitiesCache();
@Import("ParamDefinition_cached")
RSEvictingDualNodeHashTable getParamDefinitionCache();
@Import("PlayerAppearance_cachedModels")
RSEvictingDualNodeHashTable getPlayerAppearanceModelsCache();
@Import("SequenceDefinition_cached")
RSEvictingDualNodeHashTable getSequenceDefinitionCache();
@Import("SequenceDefinition_cachedFrames")
RSEvictingDualNodeHashTable getSequenceDefinitionFramesCache();
@Import("SequenceDefinition_cachedModel")
RSEvictingDualNodeHashTable getSequenceDefinitionModelsCache();
@Import("SpotAnimationDefinition_cached")
RSEvictingDualNodeHashTable getSpotAnimationDefinitionCache();
@Import("SpotAnimationDefinition_cachedModels")
RSEvictingDualNodeHashTable getSpotAnimationDefinitionModlesCache();
@Import("VarcInt_cached")
RSEvictingDualNodeHashTable getVarcIntCache();
@Import("VarpDefinition_cached")
RSEvictingDualNodeHashTable getVarpDefinitionCache();
@Import("Widget_cachedModels")
RSEvictingDualNodeHashTable getModelsCache();
@Import("Widget_cachedFonts")
RSEvictingDualNodeHashTable getFontsCache();
@Import("Widget_cachedSpriteMasks")
RSEvictingDualNodeHashTable getSpriteMasksCache();
@Import("WorldMapElement_cachedSprites")
RSEvictingDualNodeHashTable getSpritesCache();
@Construct
RSIterableNodeHashTable createIterableNodeHashTable(int size);
}

View File

@@ -29,6 +29,9 @@ import net.runelite.mapping.Import;
public interface RSDualNode extends RSNode, DualNode
{
@Import("previousDual")
RSDualNode previousDual();
@Import("removeDual")
void unlinkDual();
}

View File

@@ -8,15 +8,44 @@ public interface RSEvictingDualNodeHashTable extends NodeCache
@Import("get")
RSDualNode get(long id);
@Import("dualNode")
RSDualNode getDualNode();
@Import("clear")
@Override
void reset();
@Import("capacity")
int getCapacity();
@Import("capacity")
@Override
void setCapacity(int capacity);
@Import("remainingCapacity")
int getRemainingCapacity();
@Import("remainingCapacity")
@Override
void setRemainingCapacity(int remainingCapacity);
@Import("deque")
RSIterableDualNodeQueue getDeque();
@Import("hashTable")
void setHashTable(RSIterableNodeHashTable hashTable);
float getThreshold();
void setThreshold(float threshold);
int getTmpCapacity();
void setTmpCapacity(int tmpCapacity);
boolean isTrashing();
void resize(int newSize);
void increaseCapacity(int newSize);
}

View File

@@ -1,3 +1,9 @@
package net.runelite.rs.api;
public interface RSIterableDualNodeQueue {}
import net.runelite.mapping.Import;
public interface RSIterableDualNodeQueue
{
@Import("add")
void add(RSDualNode var1);
}

View File

@@ -10,7 +10,8 @@ public final class EvictingDualNodeHashTable {
@ObfuscatedSignature(
descriptor = "Lnc;"
)
DualNode field2797;
@Export("dualNode")
DualNode dualNode;
@ObfuscatedName("b")
@Export("capacity")
int capacity;
@@ -31,7 +32,7 @@ public final class EvictingDualNodeHashTable {
IterableDualNodeQueue deque;
public EvictingDualNodeHashTable(int var1) {
this.field2797 = new DualNode();
this.dualNode = new DualNode();
this.deque = new IterableDualNodeQueue();
this.capacity = var1;
this.remainingCapacity = var1;
@@ -79,7 +80,7 @@ public final class EvictingDualNodeHashTable {
DualNode var4 = this.deque.removeLast();
var4.remove();
var4.removeDual();
if (var4 == this.field2797) {
if (var4 == this.dualNode) {
var4 = this.deque.removeLast();
var4.remove();
var4.removeDual();
@@ -97,7 +98,7 @@ public final class EvictingDualNodeHashTable {
public void clear() {
this.deque.clear();
this.hashTable.clear();
this.field2797 = new DualNode();
this.dualNode = new DualNode();
this.remainingCapacity = this.capacity;
}
}