From 7983362f2503de3f02b3e9e098254cc8d04adb10 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sat, 24 Apr 2021 14:44:21 +0200 Subject: [PATCH] ThreadProvider comment --- .../server/thread/ThreadProvider.java | 161 ++++++++++-------- 1 file changed, 94 insertions(+), 67 deletions(-) diff --git a/src/main/java/net/minestom/server/thread/ThreadProvider.java b/src/main/java/net/minestom/server/thread/ThreadProvider.java index 1b0652f01..919d98e37 100644 --- a/src/main/java/net/minestom/server/thread/ThreadProvider.java +++ b/src/main/java/net/minestom/server/thread/ThreadProvider.java @@ -31,10 +31,6 @@ public abstract class ThreadProvider { private final Set updatableEntities = ConcurrentHashMap.newKeySet(); private final Set removedEntities = ConcurrentHashMap.newKeySet(); - // Represents the maximum percentage of tick time - // that can be spent refreshing chunks thread - protected double refreshPercentage = 0.3f; - public ThreadProvider(int threadCount) { this.threads = new ArrayList<>(threadCount); @@ -83,6 +79,17 @@ public abstract class ThreadProvider { return RefreshType.CONSTANT; } + /** + * Represents the maximum percentage of tick time that can be spent refreshing chunks thread. + *

+ * Percentage based on {@link MinecraftServer#TICK_MS}. + * + * @return the refresh percentage + */ + public float getRefreshPercentage() { + return 0.3f; + } + /** * Minimum time used to refresh chunks & entities thread. * @@ -101,61 +108,6 @@ public abstract class ThreadProvider { return (int) (MinecraftServer.TICK_MS * 0.3); } - protected void addChunk(Chunk chunk) { - ChunkEntry chunkEntry = setChunkThread(chunk, (thread) -> new ChunkEntry(thread, chunk)); - this.chunkEntryMap.put(chunk, chunkEntry); - this.chunks.add(chunk); - } - - protected void switchChunk(@NotNull Chunk chunk) { - ChunkEntry chunkEntry = chunkEntryMap.get(chunk); - if (chunkEntry == null) - return; - var chunks = threadChunkMap.get(chunkEntry.thread); - if (chunks == null || chunks.isEmpty()) - return; - chunks.remove(chunkEntry); - - setChunkThread(chunk, tickThread -> { - chunkEntry.thread = tickThread; - return chunkEntry; - }); - } - - protected @NotNull ChunkEntry setChunkThread(@NotNull Chunk chunk, - @NotNull Function<@NotNull TickThread, @NotNull ChunkEntry> chunkEntrySupplier) { - final int threadId = getThreadId(chunk); - TickThread thread = threads.get(threadId); - var chunks = threadChunkMap.computeIfAbsent(thread, tickThread -> ConcurrentHashMap.newKeySet()); - - ChunkEntry chunkEntry = chunkEntrySupplier.apply(thread); - chunks.add(chunkEntry); - return chunkEntry; - } - - protected void removeChunk(Chunk chunk) { - ChunkEntry chunkEntry = chunkEntryMap.get(chunk); - if (chunkEntry != null) { - TickThread thread = chunkEntry.thread; - var chunks = threadChunkMap.get(thread); - if (chunks != null) { - chunks.remove(chunkEntry); - } - chunkEntryMap.remove(chunk); - } - this.chunks.remove(chunk); - } - - /** - * Finds the thread id associated to a {@link Chunk}. - * - * @param chunk the chunk to find the thread id from - * @return the chunk thread id - */ - protected int getThreadId(@NotNull Chunk chunk) { - return (int) (Math.abs(findThread(chunk)) % threads.size()); - } - /** * Prepares the update by creating the {@link TickThread} tasks. * @@ -195,6 +147,7 @@ public abstract class ThreadProvider { entity.tick(time); }); }); + AcquirableEntity.refresh(Collections.emptyList()); lock.unlock(); }); } @@ -210,19 +163,14 @@ public abstract class ThreadProvider { */ public synchronized void refreshThreads(long tickTime) { // Clear removed entities - { - processRemovedEntities(); - } - + processRemovedEntities(); // Update entities chunks - { - processUpdatedEntities(); - } + processUpdatedEntities(); if (getChunkRefreshType() == RefreshType.NEVER) return; - final int timeOffset = MathUtils.clamp((int) ((double) tickTime * refreshPercentage), + final int timeOffset = MathUtils.clamp((int) ((double) tickTime * getRefreshPercentage()), getMinimumRefreshTime(), getMaximumRefreshTime()); final long endTime = System.currentTimeMillis() + timeOffset; final int size = chunks.size(); @@ -248,22 +196,101 @@ public abstract class ThreadProvider { } } + /** + * Add an entity into the waiting list to get assigned in a thread. + *

+ * Called when entering a new chunk. + * + * @param entity the entity to add + */ public void updateEntity(@NotNull Entity entity) { this.updatableEntities.add(entity); } + /** + * Add an entity into the waiting list to get removed from its thread. + *

+ * Called in {@link Entity#remove()}. + * + * @param entity the entity to remove + */ public void removeEntity(@NotNull Entity entity) { this.removedEntities.add(entity); } + /** + * Shutdowns all the {@link TickThread tick threads}. + *

+ * Action is irreversible. + */ public void shutdown() { this.threads.forEach(TickThread::shutdown); } + /** + * Gets all the {@link TickThread tick threads}. + * + * @return the tick threads + */ public @NotNull List<@NotNull TickThread> getThreads() { return threads; } + protected void addChunk(@NotNull Chunk chunk) { + ChunkEntry chunkEntry = setChunkThread(chunk, (thread) -> new ChunkEntry(thread, chunk)); + this.chunkEntryMap.put(chunk, chunkEntry); + this.chunks.add(chunk); + } + + protected void switchChunk(@NotNull Chunk chunk) { + ChunkEntry chunkEntry = chunkEntryMap.get(chunk); + if (chunkEntry == null) + return; + var chunks = threadChunkMap.get(chunkEntry.thread); + if (chunks == null || chunks.isEmpty()) + return; + chunks.remove(chunkEntry); + + setChunkThread(chunk, tickThread -> { + chunkEntry.thread = tickThread; + return chunkEntry; + }); + } + + protected @NotNull ChunkEntry setChunkThread(@NotNull Chunk chunk, + @NotNull Function chunkEntrySupplier) { + final int threadId = getThreadId(chunk); + TickThread thread = threads.get(threadId); + var chunks = threadChunkMap.computeIfAbsent(thread, tickThread -> ConcurrentHashMap.newKeySet()); + + ChunkEntry chunkEntry = chunkEntrySupplier.apply(thread); + chunks.add(chunkEntry); + return chunkEntry; + } + + protected void removeChunk(Chunk chunk) { + ChunkEntry chunkEntry = chunkEntryMap.get(chunk); + if (chunkEntry != null) { + TickThread thread = chunkEntry.thread; + var chunks = threadChunkMap.get(thread); + if (chunks != null) { + chunks.remove(chunkEntry); + } + chunkEntryMap.remove(chunk); + } + this.chunks.remove(chunk); + } + + /** + * Finds the thread id associated to a {@link Chunk}. + * + * @param chunk the chunk to find the thread id from + * @return the chunk thread id + */ + protected int getThreadId(@NotNull Chunk chunk) { + return (int) (Math.abs(findThread(chunk)) % threads.size()); + } + private void processRemovedEntities() { for (Entity entity : removedEntities) { AcquirableEntity acquirableEntity = entity.getAcquirable();