Improve entity viewer iterator creation

This commit is contained in:
themode 2022-03-01 04:21:16 +01:00
parent fa5fe8f208
commit 45fe2f1ac9

View File

@ -1,6 +1,7 @@
package net.minestom.server.entity; package net.minestom.server.entity;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntIterator;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.ints.IntSet;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
@ -46,18 +47,19 @@ final class EntityView {
} }
} }
entity.updateNewViewer(player); entity.updateNewViewer(player);
}, player -> { },
// Remove viewable player -> {
var lock1 = player.getEntityId() < entity.getEntityId() ? player : entity; // Remove viewable
var lock2 = lock1 == entity ? player : entity; var lock1 = player.getEntityId() < entity.getEntityId() ? player : entity;
synchronized (lock1.viewEngine.mutex) { var lock2 = lock1 == entity ? player : entity;
synchronized (lock2.viewEngine.mutex) { synchronized (lock1.viewEngine.mutex) {
entity.viewEngine.viewableOption.unregister(player); synchronized (lock2.viewEngine.mutex) {
player.viewEngine.viewerOption.unregister(entity); entity.viewEngine.viewableOption.unregister(player);
} player.viewEngine.viewerOption.unregister(entity);
} }
entity.updateOldViewer(player); }
}); entity.updateOldViewer(player);
});
this.viewerOption = new Option<>(EntityTracker.Target.ENTITIES, Entity::isAutoViewable, this.viewerOption = new Option<>(EntityTracker.Target.ENTITIES, Entity::isAutoViewable,
entity instanceof Player player ? e -> e.viewEngine.viewableOption.addition.accept(player) : null, entity instanceof Player player ? e -> e.viewEngine.viewableOption.addition.accept(player) : null,
entity instanceof Player player ? e -> e.viewEngine.viewableOption.removal.accept(player) : null); entity instanceof Player player ? e -> e.viewEngine.viewableOption.removal.accept(player) : null);
@ -106,21 +108,18 @@ final class EntityView {
} }
public void handleAutoViewAddition(Entity entity) { public void handleAutoViewAddition(Entity entity) {
handleAutoView(entity, viewerOption.addition, viewableOption.addition, false); handleAutoView(entity, viewerOption.addition, viewableOption.addition);
} }
public void handleAutoViewRemoval(Entity entity) { public void handleAutoViewRemoval(Entity entity) {
handleAutoView(entity, viewerOption.removal, viewableOption.removal, true); handleAutoView(entity, viewerOption.removal, viewableOption.removal);
} }
private void handleAutoView(Entity entity, Consumer<Entity> viewer, Consumer<Player> viewable, private void handleAutoView(Entity entity, Consumer<Entity> viewer, Consumer<Player> viewable) {
boolean requirement) {
if (this.entity instanceof Player && viewerOption.isAuto() && entity.isAutoViewable()) { if (this.entity instanceof Player && viewerOption.isAuto() && entity.isAutoViewable()) {
assert viewerOption.isRegistered(entity) == requirement : "Entity is already registered";
if (viewer != null) viewer.accept(entity); // Send packet to this player if (viewer != null) viewer.accept(entity); // Send packet to this player
} }
if (entity instanceof Player player && player.autoViewEntities() && viewableOption.isAuto()) { if (entity instanceof Player player && player.autoViewEntities() && viewableOption.isAuto()) {
assert viewableOption.isRegistered(player) == requirement : "Entity is already registered";
if (viewable != null) viewable.accept(player); // Send packet to the range-visible player if (viewable != null) viewable.accept(player); // Send packet to the range-visible player
} }
} }
@ -231,11 +230,19 @@ final class EntityView {
final class SetImpl extends AbstractSet<Player> { final class SetImpl extends AbstractSet<Player> {
@Override @Override
public @NotNull Iterator<Player> iterator() { public @NotNull Iterator<Player> iterator() {
Player[] players;
synchronized (mutex) { synchronized (mutex) {
return viewableOption.bitSet.intStream() var bitSet = viewableOption.bitSet;
.mapToObj(operand -> (Player) Entity.getEntity(operand)) players = new Player[bitSet.size()];
.toList().iterator(); int i = 0;
for (IntIterator it = bitSet.intIterator(); it.hasNext(); ) {
final int id = it.nextInt();
final Player player = (Player) Entity.getEntity(id);
assert player != null;
players[i++] = player;
}
} }
return Arrays.asList(players).iterator();
} }
@Override @Override
@ -259,12 +266,5 @@ final class EntityView {
return viewableOption.isRegistered(player); return viewableOption.isRegistered(player);
} }
} }
@Override
public void forEach(Consumer<? super Player> action) {
synchronized (mutex) {
viewableOption.bitSet.forEach((int id) -> action.accept((Player) Entity.getEntity(id)));
}
}
} }
} }