mirror of
https://github.com/filoghost/HolographicDisplays.git
synced 2024-12-23 17:27:35 +01:00
Experimental and potentially unstable: async packet sending
This commit is contained in:
parent
ed3bbad1fb
commit
0754e0ac33
@ -24,6 +24,7 @@ import me.filoghost.holographicdisplays.core.placeholder.tracking.ActivePlacehol
|
||||
import me.filoghost.holographicdisplays.core.tick.TickClock;
|
||||
import me.filoghost.holographicdisplays.core.tick.TickingTask;
|
||||
import me.filoghost.holographicdisplays.core.tracking.LineTrackerManager;
|
||||
import me.filoghost.holographicdisplays.core.tracking.PacketSenderExecutor;
|
||||
import me.filoghost.holographicdisplays.nms.common.NMSManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -47,6 +48,8 @@ public class HolographicDisplaysCore {
|
||||
throw new PluginEnableException(t, "Couldn't initialize the NMS manager.");
|
||||
}
|
||||
|
||||
PacketSenderExecutor.start();
|
||||
|
||||
PlaceholderRegistry placeholderRegistry = new PlaceholderRegistry();
|
||||
TickClock tickClock = new TickClock();
|
||||
ActivePlaceholderTracker placeholderTracker = new ActivePlaceholderTracker(placeholderRegistry, tickClock);
|
||||
@ -103,6 +106,8 @@ public class HolographicDisplaysCore {
|
||||
nmsManager.uninjectPacketListener(player);
|
||||
}
|
||||
}
|
||||
|
||||
PacketSenderExecutor.stopGracefully();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -85,7 +85,11 @@ public abstract class ClickableLineTracker<T extends Viewer> extends LineTracker
|
||||
@Override
|
||||
protected void sendSpawnPackets(Viewers<T> viewers) {
|
||||
if (spawnClickableEntity) {
|
||||
viewers.sendPackets(clickableEntity.newSpawnPackets(getClickableEntityPosition()));
|
||||
// Copy for async use
|
||||
PositionCoordinates clickableEntityPosition = getClickableEntityPosition();
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(clickableEntity.newSpawnPackets(clickableEntityPosition));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,7 +97,9 @@ public abstract class ClickableLineTracker<T extends Viewer> extends LineTracker
|
||||
@Override
|
||||
protected void sendDestroyPackets(Viewers<T> viewers) {
|
||||
if (spawnClickableEntity) {
|
||||
viewers.sendPackets(clickableEntity.newDestroyPackets());
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(clickableEntity.newDestroyPackets());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,9 +110,15 @@ public abstract class ClickableLineTracker<T extends Viewer> extends LineTracker
|
||||
|
||||
if (spawnClickableEntityChanged) {
|
||||
if (spawnClickableEntity) {
|
||||
viewers.sendPackets(clickableEntity.newSpawnPackets(getClickableEntityPosition()));
|
||||
// Copy for async use
|
||||
PositionCoordinates clickableEntityPosition = getClickableEntityPosition();
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(clickableEntity.newSpawnPackets(clickableEntityPosition));
|
||||
});
|
||||
} else {
|
||||
viewers.sendPackets(clickableEntity.newDestroyPackets());
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(clickableEntity.newDestroyPackets());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -115,7 +127,11 @@ public abstract class ClickableLineTracker<T extends Viewer> extends LineTracker
|
||||
@Override
|
||||
protected void sendPositionChangePackets(Viewers<T> viewers) {
|
||||
if (spawnClickableEntity) {
|
||||
viewers.sendPackets(clickableEntity.newTeleportPackets(getClickableEntityPosition()));
|
||||
// Copy for async use
|
||||
PositionCoordinates clickableEntityPosition = getClickableEntityPosition();
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(clickableEntity.newTeleportPackets(clickableEntityPosition));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
package me.filoghost.holographicdisplays.core.tracking;
|
||||
|
||||
import me.filoghost.holographicdisplays.common.PositionCoordinates;
|
||||
import me.filoghost.holographicdisplays.core.base.BaseItemHologramLine;
|
||||
import me.filoghost.holographicdisplays.core.listener.LineClickListener;
|
||||
import me.filoghost.holographicdisplays.core.tick.CachedPlayer;
|
||||
@ -106,7 +107,12 @@ public class ItemLineTracker extends ClickableLineTracker<Viewer> {
|
||||
super.sendSpawnPackets(viewers);
|
||||
|
||||
if (spawnItemEntity) {
|
||||
viewers.sendPackets(itemEntity.newSpawnPackets(positionCoordinates, itemStack));
|
||||
// Copy for async use
|
||||
PositionCoordinates positionCoordinates = this.positionCoordinates;
|
||||
ItemStack itemStack = this.itemStack;
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(itemEntity.newSpawnPackets(positionCoordinates, itemStack));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,7 +122,9 @@ public class ItemLineTracker extends ClickableLineTracker<Viewer> {
|
||||
super.sendDestroyPackets(viewers);
|
||||
|
||||
if (spawnItemEntity) {
|
||||
viewers.sendPackets(itemEntity.newDestroyPackets());
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(itemEntity.newDestroyPackets());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,13 +135,24 @@ public class ItemLineTracker extends ClickableLineTracker<Viewer> {
|
||||
|
||||
if (spawnItemEntityChanged) {
|
||||
if (spawnItemEntity) {
|
||||
viewers.sendPackets(itemEntity.newSpawnPackets(positionCoordinates, itemStack));
|
||||
// Copy for async use
|
||||
PositionCoordinates positionCoordinates = this.positionCoordinates;
|
||||
ItemStack itemStack = this.itemStack;
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(itemEntity.newSpawnPackets(positionCoordinates, itemStack));
|
||||
});
|
||||
} else {
|
||||
viewers.sendPackets(itemEntity.newDestroyPackets());
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(itemEntity.newDestroyPackets());
|
||||
});
|
||||
}
|
||||
} else if (itemStackChanged) {
|
||||
// Only send item changes if full spawn/destroy packets were not sent
|
||||
viewers.sendPackets(itemEntity.newChangePackets(itemStack));
|
||||
// Copy for async use
|
||||
ItemStack itemStack = this.itemStack;
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(itemEntity.newChangePackets(itemStack));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,7 +162,11 @@ public class ItemLineTracker extends ClickableLineTracker<Viewer> {
|
||||
super.sendPositionChangePackets(viewers);
|
||||
|
||||
if (spawnItemEntity) {
|
||||
viewers.sendPackets(itemEntity.newTeleportPackets(positionCoordinates));
|
||||
// Copy for async use
|
||||
PositionCoordinates positionCoordinates = this.positionCoordinates;
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(itemEntity.newTeleportPackets(positionCoordinates));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,14 +14,14 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.MustBeInvokedByOverriders;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public abstract class LineTracker<T extends Viewer> {
|
||||
|
||||
private final Map<Player, T> viewers;
|
||||
private final ConcurrentMap<Player, T> viewers;
|
||||
private final Viewers<T> iterableViewers;
|
||||
|
||||
private String positionWorldName;
|
||||
@ -32,7 +32,7 @@ public abstract class LineTracker<T extends Viewer> {
|
||||
private int lastVisibilitySettingsVersion;
|
||||
|
||||
protected LineTracker() {
|
||||
this.viewers = new HashMap<>();
|
||||
this.viewers = new ConcurrentHashMap<>();
|
||||
this.iterableViewers = new DelegateViewers<>(viewers.values());
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ public class MutableViewers<T extends Viewer> implements Viewers<T> {
|
||||
private T viewer;
|
||||
private List<T> additionalViewers;
|
||||
|
||||
public void add(T viewer) {
|
||||
public synchronized void add(T viewer) {
|
||||
if (this.viewer == null) {
|
||||
this.viewer = viewer;
|
||||
} else {
|
||||
@ -27,7 +27,7 @@ public class MutableViewers<T extends Viewer> implements Viewers<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<? super T> action) {
|
||||
public synchronized void forEach(Consumer<? super T> action) {
|
||||
if (viewer != null) {
|
||||
action.accept(viewer);
|
||||
if (additionalViewers != null) {
|
||||
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) filoghost and contributors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
package me.filoghost.holographicdisplays.core.tracking;
|
||||
|
||||
import me.filoghost.fcommons.logging.Log;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
/**
|
||||
* This is a quick but ugly helper class for creating and sending packets async.
|
||||
* Static classes like this should be avoided.
|
||||
*/
|
||||
public class PacketSenderExecutor {
|
||||
|
||||
private static volatile BlockingQueue<Runnable> tasks;
|
||||
private static volatile Thread thread;
|
||||
|
||||
private static final Runnable STOP_MARKER_TASK = () -> {};
|
||||
|
||||
static {
|
||||
tasks = new LinkedBlockingQueue<>();
|
||||
thread = new Thread(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
Runnable task = tasks.take();
|
||||
task.run();
|
||||
} catch (Throwable t) {
|
||||
Log.severe("Error in packet sender task", t);
|
||||
}
|
||||
}
|
||||
});
|
||||
thread.setName("Holographic Displays async packets");
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public static void execute(Runnable task) {
|
||||
tasks.add(task);
|
||||
}
|
||||
|
||||
public static void start() {
|
||||
tasks = new LinkedBlockingQueue<>();
|
||||
thread = new Thread(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
Runnable task = tasks.take();
|
||||
if (task == STOP_MARKER_TASK) {
|
||||
return;
|
||||
}
|
||||
task.run();
|
||||
} catch (Throwable t) {
|
||||
Log.severe("Error in packet sender task", t);
|
||||
}
|
||||
}
|
||||
});
|
||||
thread.setName("Holographic Displays packet sender");
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public static void stopGracefully() {
|
||||
if (tasks != null) {
|
||||
tasks.add(STOP_MARKER_TASK);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
package me.filoghost.holographicdisplays.core.tracking;
|
||||
|
||||
import me.filoghost.holographicdisplays.common.PositionCoordinates;
|
||||
import me.filoghost.holographicdisplays.core.base.BaseTextHologramLine;
|
||||
import me.filoghost.holographicdisplays.core.listener.LineClickListener;
|
||||
import me.filoghost.holographicdisplays.core.placeholder.tracking.ActivePlaceholderTracker;
|
||||
@ -84,15 +85,22 @@ public class TextLineTracker extends ClickableLineTracker<TextLineViewer> {
|
||||
protected void sendSpawnPackets(Viewers<TextLineViewer> viewers) {
|
||||
super.sendSpawnPackets(viewers);
|
||||
|
||||
IndividualTextPacketGroup spawnPackets = textEntity.newSpawnPackets(positionCoordinates);
|
||||
viewers.forEach(viewer -> viewer.sendTextPackets(spawnPackets));
|
||||
// Copy for async use
|
||||
PositionCoordinates positionCoordinates = this.positionCoordinates;
|
||||
viewers.forEach(TextLineViewer::updateNextTextToSend);
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
IndividualTextPacketGroup spawnPackets = textEntity.newSpawnPackets(positionCoordinates);
|
||||
viewers.forEach(viewer -> viewer.sendTextPackets(spawnPackets));
|
||||
});
|
||||
}
|
||||
|
||||
@MustBeInvokedByOverriders
|
||||
@Override
|
||||
protected void sendDestroyPackets(Viewers<TextLineViewer> viewers) {
|
||||
super.sendDestroyPackets(viewers);
|
||||
viewers.sendPackets(textEntity.newDestroyPackets());
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(textEntity.newDestroyPackets());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -100,8 +108,11 @@ public class TextLineTracker extends ClickableLineTracker<TextLineViewer> {
|
||||
super.sendChangesPackets(viewers);
|
||||
|
||||
if (displayTextChanged) {
|
||||
IndividualTextPacketGroup changePackets = textEntity.newChangePackets();
|
||||
viewers.forEach(viewer -> viewer.sendTextPacketsIfNecessary(changePackets));
|
||||
viewers.forEach(TextLineViewer::updateNextTextToSend);
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
IndividualTextPacketGroup changePackets = textEntity.newChangePackets();
|
||||
viewers.forEach(viewer -> viewer.sendTextPacketsIfNecessary(changePackets));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,7 +120,11 @@ public class TextLineTracker extends ClickableLineTracker<TextLineViewer> {
|
||||
@Override
|
||||
protected void sendPositionChangePackets(Viewers<TextLineViewer> viewers) {
|
||||
super.sendPositionChangePackets(viewers);
|
||||
viewers.sendPackets(textEntity.newTeleportPackets(positionCoordinates));
|
||||
// Copy for async use
|
||||
PositionCoordinates positionCoordinates = this.positionCoordinates;
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(textEntity.newTeleportPackets(positionCoordinates));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -5,9 +5,8 @@
|
||||
*/
|
||||
package me.filoghost.holographicdisplays.core.tracking;
|
||||
|
||||
import me.filoghost.holographicdisplays.nms.common.IndividualTextPacketGroup;
|
||||
import me.filoghost.holographicdisplays.core.tick.CachedPlayer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import me.filoghost.holographicdisplays.nms.common.IndividualTextPacketGroup;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@ -15,8 +14,10 @@ class TextLineViewer extends Viewer {
|
||||
|
||||
private final DisplayText displayText;
|
||||
|
||||
// Access to these variables must be synchronized, they are accessed from multiple threads
|
||||
private String individualText;
|
||||
private String lastSentText;
|
||||
private String nextTextToSend;
|
||||
|
||||
TextLineViewer(CachedPlayer player, DisplayText displayText) {
|
||||
super(player);
|
||||
@ -24,39 +25,47 @@ class TextLineViewer extends Viewer {
|
||||
}
|
||||
|
||||
public void sendTextPackets(IndividualTextPacketGroup packets) {
|
||||
String text = getOrComputeText();
|
||||
this.lastSentText = text;
|
||||
String text;
|
||||
synchronized (this) {
|
||||
text = nextTextToSend;
|
||||
this.lastSentText = text;
|
||||
}
|
||||
sendIndividualPackets(packets, text);
|
||||
}
|
||||
|
||||
public void sendTextPacketsIfNecessary(IndividualTextPacketGroup packets) {
|
||||
String text = getOrComputeText();
|
||||
if (Objects.equals(lastSentText, text)) {
|
||||
return; // Avoid sending unnecessary packets
|
||||
String text;
|
||||
synchronized (this) {
|
||||
text = nextTextToSend;
|
||||
if (Objects.equals(lastSentText, text)) {
|
||||
return; // Avoid sending unnecessary packets
|
||||
}
|
||||
this.lastSentText = text;
|
||||
}
|
||||
this.lastSentText = text;
|
||||
sendIndividualPackets(packets, text);
|
||||
}
|
||||
|
||||
private @Nullable String getOrComputeText() {
|
||||
public synchronized void updateNextTextToSend() {
|
||||
if (displayText.containsIndividualPlaceholders()) {
|
||||
if (individualText == null) {
|
||||
individualText = displayText.computeIndividualText(this);
|
||||
}
|
||||
return individualText;
|
||||
nextTextToSend = individualText;
|
||||
} else {
|
||||
individualText = null;
|
||||
return displayText.getGlobalText();
|
||||
nextTextToSend = displayText.getGlobalText();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean updateIndividualText() {
|
||||
String individualText = displayText.computeIndividualText(this);
|
||||
if (!Objects.equals(this.individualText, individualText)) {
|
||||
this.individualText = individualText;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
synchronized (this) {
|
||||
if (!Objects.equals(this.individualText, individualText)) {
|
||||
this.individualText = individualText;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,13 +14,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -14,13 +14,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -14,13 +14,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -14,13 +14,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -14,13 +14,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -14,13 +14,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -14,13 +14,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
void writeBoolean(boolean flag) {
|
||||
|
@ -12,13 +12,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -12,13 +12,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -12,13 +12,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -12,13 +12,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -12,13 +12,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -12,13 +12,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -12,13 +12,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -12,13 +12,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -12,13 +12,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -14,13 +14,14 @@ import java.io.IOException;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
@ -14,13 +14,14 @@ import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new);
|
||||
|
||||
private final PacketDataSerializer serializer;
|
||||
|
||||
static PacketByteBuffer get() {
|
||||
INSTANCE.clear();
|
||||
return INSTANCE;
|
||||
PacketByteBuffer instance = LOCAL_INSTANCE.get();
|
||||
instance.clear();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PacketByteBuffer() {
|
||||
|
Loading…
Reference in New Issue
Block a user