Optimize lookup of getBukkitEntity.

This commit is contained in:
Kristian S. Stangeland 2014-03-03 23:11:05 +01:00
parent b84aace585
commit 4259a86740
3 changed files with 61 additions and 12 deletions

View File

@ -56,6 +56,7 @@ import com.comphenix.protocol.reflect.ClassAnalyser;
import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.ClassAnalyser.AsmMethod;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
import com.comphenix.protocol.reflect.compiler.EmptyClassVisitor;
import com.comphenix.protocol.reflect.compiler.EmptyMethodVisitor;
import com.comphenix.protocol.reflect.fuzzy.AbstractFuzzyMatcher;
@ -69,6 +70,9 @@ import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
import com.comphenix.protocol.wrappers.nbt.NbtType;
import com.google.common.base.Joiner;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
/**
* Methods and constants specifically used in conjuction with reflecting Minecraft object.
@ -141,6 +145,14 @@ public class MinecraftReflection {
// net.minecraft.server
private static Class<?> itemStackArrayClass;
// Cache of getBukkitEntity
private static Cache<Class<?>, MethodAccessor> getBukkitEntityCache = CacheBuilder.newBuilder().build(
new CacheLoader<Class<?>, MethodAccessor>() {
public MethodAccessor load(java.lang.Class<?> paramK) throws Exception {
return Accessors.getMethodAccessor(paramK, "getBukkitEntity");
};
});
// The current class source
private static ClassSource classSource;
@ -367,9 +379,9 @@ public class MinecraftReflection {
// We will have to do this dynamically, unfortunately
try {
return nmsObject.getClass().getMethod("getBukkitEntity").invoke(nmsObject);
return getBukkitEntityCache.apply(nmsObject.getClass()).invoke(nmsObject);
} catch (Exception e) {
throw new RuntimeException("Cannot get Bukkit entity from " + nmsObject, e);
throw new IllegalArgumentException("Cannot get Bukkit entity from " + nmsObject, e);
}
}

View File

@ -106,24 +106,32 @@ public class SimpleCraftBukkitITCase {
@SuppressWarnings("deprecation")
private static void setupPlugins() throws IOException {
File pluginDirectory = new File("plugins/");
File srcDirectory = new File("../");
File bestFile = null;
int bestLength = Integer.MAX_VALUE;
for (File file : srcDirectory.listFiles()) {
String name = file.getName();
if (file.isFile() && name.startsWith("ProtocolLib") && name.length() < bestLength) {
bestLength = name.length();
bestFile = file;
}
}
if (bestFile == null) {
throw new IllegalStateException("Cannot find ProtocolLib in " + srcDirectory);
}
// Copy the ProtocolLib plugin to the server
if (pluginDirectory.exists()) {
Files.deleteDirectoryContents(pluginDirectory);
}
for (File file : new File("../").listFiles()) {
String name = file.getName();
if (name.startsWith("ProtocolLib") && name.length() < bestLength) {
bestLength = name.length();
bestFile = file;
}
}
pluginDirectory.mkdirs();
Files.copy(bestFile, new File(pluginDirectory, bestFile.getName()));
File destination = new File(pluginDirectory, bestFile.getName()).getAbsoluteFile();
Files.copy(bestFile, destination);
}
/**

View File

@ -1,6 +1,7 @@
package com.comphenix.protocol.utility;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import net.minecraft.server.v1_7_R1.ChatComponentText;
import net.minecraft.server.v1_7_R1.ChatSerializer;
@ -11,6 +12,8 @@ import net.minecraft.server.v1_7_R1.ServerPing;
import net.minecraft.server.v1_7_R1.ServerPingPlayerSample;
import net.minecraft.server.v1_7_R1.ServerPingServerData;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@ -19,6 +22,15 @@ import com.comphenix.protocol.BukkitInitialization;
import com.google.common.collect.Maps;
public class MinecraftReflectionTest {
// Mocking objects
private interface FakeEntity {
public Entity getBukkitEntity();
}
private interface FakeBlock {
public Block getBukkitEntity();
}
@BeforeClass
public static void initializeReflection() throws IllegalAccessException {
BukkitInitialization.initializePackage();
@ -32,7 +44,24 @@ public class MinecraftReflectionTest {
@AfterClass
public static void undoMocking() {
MinecraftReflection.minecraftPackage = null;
// NOP
}
@Test
public void testBukkitMethod() {
FakeEntity entity = mock(FakeEntity.class);
FakeBlock block = mock(FakeBlock.class);
MinecraftReflection.getBukkitEntity(entity);
MinecraftReflection.getBukkitEntity(block);
verify(entity, times(1)).getBukkitEntity();
verify(block, times(1)).getBukkitEntity();
}
@Test(expected = IllegalArgumentException.class)
public void testIllegalClass() {
MinecraftReflection.getBukkitEntity("Hello");
}
@Test