Ensure that the viewable element can be collected

Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
TheMode 2021-09-16 07:43:08 +02:00
parent e061c1e640
commit 3211831073

View File

@ -23,6 +23,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.lang.ref.WeakReference;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -261,12 +262,12 @@ public final class PacketUtils {
} }
private static final class ViewableStorage { private static final class ViewableStorage {
private final Viewable viewable; private final WeakReference<Viewable> viewable;
private final Map<PlayerConnection, List<IntIntPair>> entityIdMap = new HashMap<>(); private final Map<PlayerConnection, List<IntIntPair>> entityIdMap = new HashMap<>();
private final BinaryBuffer buffer = PooledBuffers.get(); private final BinaryBuffer buffer = PooledBuffers.get();
private ViewableStorage(Viewable viewable) { private ViewableStorage(Viewable viewable) {
this.viewable = viewable; this.viewable = new WeakReference<>(viewable);
PooledBuffers.registerBuffer(this, buffer); PooledBuffers.registerBuffer(this, buffer);
} }
@ -274,7 +275,7 @@ public final class PacketUtils {
final ByteBuffer framedPacket = createFramedPacket(serverPacket).flip(); final ByteBuffer framedPacket = createFramedPacket(serverPacket).flip();
final int packetSize = framedPacket.limit(); final int packetSize = framedPacket.limit();
if (packetSize >= buffer.capacity()) { if (packetSize >= buffer.capacity()) {
processSingle(framedPacket, connection); process(new SingleEntry(framedPacket, connection));
return; return;
} }
if (!buffer.canWrite(packetSize)) process(); if (!buffer.canWrite(packetSize)) process();
@ -287,9 +288,11 @@ public final class PacketUtils {
} }
} }
private synchronized void process() { private synchronized void process(@Nullable SingleEntry singleEntry) {
if (buffer.writerOffset() == 0) if (buffer.writerOffset() == 0)
return; // TODO: there is nothing in the buffer, remove from VIEWABLE_STORAGE_MAP return; // TODO: there is nothing in the buffer, remove from VIEWABLE_STORAGE_MAP
final Viewable viewable = this.viewable.get();
if (viewable == null) return;
for (Player player : viewable.getViewers()) { for (Player player : viewable.getViewers()) {
PlayerConnection connection = player.getPlayerConnection(); PlayerConnection connection = player.getPlayerConnection();
Consumer<ByteBuffer> writer = connection instanceof PlayerSocketConnection Consumer<ByteBuffer> writer = connection instanceof PlayerSocketConnection
@ -316,21 +319,28 @@ public final class PacketUtils {
ByteBuffer remainSlice = buffer.asByteBuffer(lastWrite, remaining); ByteBuffer remainSlice = buffer.asByteBuffer(lastWrite, remaining);
writer.accept(remainSlice); writer.accept(remainSlice);
} }
// Handle single entry
if (singleEntry != null && !singleEntry.exception.equals(connection)) {
writer.accept(singleEntry.buffer.position(0));
}
} }
// Clear state // Clear state
this.entityIdMap.clear(); this.entityIdMap.clear();
this.buffer.clear(); this.buffer.clear();
} }
private synchronized void processSingle(ByteBuffer buffer, PlayerConnection exception) { private void process() {
process(); process(null);
for (Player player : viewable.getViewers()) { }
PlayerConnection connection = player.getPlayerConnection();
if (Objects.equals(connection, exception)) continue; private static final class SingleEntry {
if (connection instanceof PlayerSocketConnection) { private final ByteBuffer buffer;
((PlayerSocketConnection) connection).write(buffer.position(0)); private final PlayerConnection exception;
}
// TODO for non-socket connection public SingleEntry(ByteBuffer buffer, PlayerConnection exception) {
this.buffer = buffer;
this.exception = exception;
} }
} }
} }