Merge pull request #66 from starlis/improvNav

Improve NavigationListener patches.
This commit is contained in:
Zach Brown 2016-03-08 20:14:07 -06:00
commit d995d003f4
2 changed files with 48 additions and 93 deletions

View file

@ -1,14 +1,22 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 7 Mar 2016 22:43:26 -0500
Subject: [PATCH] Optimize NavigationListener Iteration
Date: Tue, 8 Mar 2016 19:13:54 -0500
Subject: [PATCH] Optimize Navigation Listener
I don't know what the person who wrote that code was smoking, but I
don't think it was good.
Mojang was abusing a WeakHashMap to do clean up. However this has some
scary object life concerns as you could have a NavigationListener being
ticked even after the entity it was bound to was removed from world.
Gets rid of the WeakHashMap that mojang was abusing purely to be lazy
on clean up, and handles registering and deregistering navigation
upon world add/remove operations.
Switching this to an Array List gives superior iteration performance
at a slight cost to removal performance.
Additionally, change listener registration to be done upon world add
instead of immediate up creation.
This provides benefit of only registering and ticking REAL Navigation
objects, and not invalid entities (cancelled entity spawns for example)
Gives us a much leaner NavigationListener list.
diff --git a/src/main/java/net/minecraft/server/NavigationAbstract.java b/src/main/java/net/minecraft/server/NavigationAbstract.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
@ -19,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.g = entityinsentient.getAttributeInstance(GenericAttributes.FOLLOW_RANGE);
this.s = this.a();
- this.b.C().a(this);
+ //this.b.C().a(this); // Paper
+ //this.b.C().a(this); // Paper - Optimized Nav Listener - registered on world add
}
protected abstract Pathfinder a();
@ -42,57 +50,50 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public NavigationListener() {}
+
public void a(NavigationAbstract navigationabstract) {
- this.b.put(navigationabstract, NavigationListener.a);
+ this.add(navigationabstract); // Paper
+ //this.b.put(navigationabstract, NavigationListener.a); // Paper
+ System.err.println("Unexpected NavigationListener add"); // Paper
}
+ // Paper start
+ public void add(NavigationAbstract navigationabstract) {
+ this.navigators.add(navigationabstract);
+ }
+ public void remove(NavigationAbstract navigationabstract) {
+ this.navigators.remove(navigationabstract);
+ }
+ // Paper end
+
public void a(World world, BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1, int i) {
if (this.a(world, blockposition, iblockdata, iblockdata1)) {
- NavigationAbstract[] anavigationabstract = (NavigationAbstract[]) this.b.keySet().toArray(new NavigationAbstract[0]);
- NavigationAbstract[] anavigationabstract1 = anavigationabstract;
- int j = anavigationabstract.length;
+ // Paper start
+ //NavigationAbstract[] anavigationabstract = (NavigationAbstract[]) this.navigators.keySet().toArray(new NavigationAbstract[0]);
+ //NavigationAbstract[] anavigationabstract1 = anavigationabstract;
+ int j = this.navigators.size();
+
+ /* // Paper start
NavigationAbstract[] anavigationabstract = (NavigationAbstract[]) this.b.keySet().toArray(new NavigationAbstract[0]);
NavigationAbstract[] anavigationabstract1 = anavigationabstract;
int j = anavigationabstract.length;
for (int k = 0; k < j; ++k) {
- for (int k = 0; k < j; ++k) {
- NavigationAbstract navigationabstract = anavigationabstract1[k];
+ */
+ for (int k = 0; k < this.navigators.size(); ++k) {
+ NavigationAbstract navigationabstract = this.navigators.get(k);
+ // Paper end
if (navigationabstract != null && !navigationabstract.i()) {
PathEntity pathentity = navigationabstract.k();
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
this.getChunkAt(i, j).a(entity);
this.entityList.add(entity);
this.b(entity);
+ if (entity instanceof EntityInsentient) { this.getNavListener().add(((EntityInsentient) entity).navigation); } // Paper
return true;
}
}
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
}
// CraftBukkit end
} // Spigot
+ if (entity instanceof EntityInsentient) { this.getNavListener().remove(((EntityInsentient) entity).navigation); } // Paper
this.c(entity);
}
@@ -0,0 +0,0 @@ public class NavigationListener implements IWorldAccess {
public void a(int i, boolean flag, double d0, double d1, double d2, double d3, double d4, double d5, int... aint) {}
- public void a(Entity entity) {}
+ public void a(Entity entity) {
+ // Paper start
+ if (entity instanceof EntityInsentient) {
+ this.navigators.add(((EntityInsentient) entity).navigation);
+ }
+ // Paper end
+ }
- public void b(Entity entity) {}
+ public void b(Entity entity) {
+ // Paper start
+ if (entity instanceof EntityInsentient) {
+ this.navigators.remove(((EntityInsentient) entity).navigation);
+ }
+ // Paper end
+ }
public void a(SoundEffect soundeffect, BlockPosition blockposition) {}
--

View file

@ -1,46 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 7 Mar 2016 20:41:27 -0500
Subject: [PATCH] Optimize NavigationListener
I believe Mojang intended to call the NavigationListener Block Update
method anytime a block is changed, but accidently added it for every
block physics event instead.
This code is massively ineffecient, and physics is so super hot, it
destroys server performance.
This patch moves the block update call to setTypeAndData instead of
on Physics.
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
private int K;
public final Random random = new Random();
public WorldProvider worldProvider;
- protected NavigationListener t = new NavigationListener();
+ protected NavigationListener t = new NavigationListener(); public NavigationListener getNavListener() { return this.t; } // Paper
protected List<IWorldAccess> u;
protected IChunkProvider chunkProvider;
protected final IDataManager dataManager;
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit
this.ticksPerMonsterSpawns = this.getServer().getTicksPerMonsterSpawns(); // CraftBukkit
// CraftBukkit end
- this.u = Lists.newArrayList(new IWorldAccess[] { this.t});
+ this.u = Lists.newArrayList(new IWorldAccess[] {}); // Paper
this.L = Calendar.getInstance();
this.scoreboard = new Scoreboard();
this.allowMonsters = true;
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
if (!this.captureBlockStates) { // Don't notify clients or update physics while capturing blockstates
// Modularize client and physic updates
notifyAndUpdatePhysics(blockposition, chunk, iblockdata1, iblockdata, i);
+ this.getNavListener().a(this, blockposition, iblockdata1, iblockdata, i); // Paper
}
// CraftBukkit end
--