diff --git a/src/main/java/de/bixilon/minosoft/data/world/ChunkSection.kt b/src/main/java/de/bixilon/minosoft/data/world/ChunkSection.kt index 924af2577..e05aeb51c 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/ChunkSection.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/ChunkSection.kt @@ -36,7 +36,7 @@ class ChunkSection( var light: IntArray, // packed (skyLight: 0xF0, blockLight: 0x0F) ) { - constructor(registries: Registries) : this(RegistrySectionDataProvider(registries.blockStateRegistry.unsafeCast(), checkSize = true), RegistrySectionDataProvider(registries.biomeRegistry, checkSize = false), SectionDataProvider(checkSize = true), IntArray(ProtocolDefinition.BLOCKS_PER_SECTION)) + constructor(registries: Registries) : this(RegistrySectionDataProvider(registries.blockStateRegistry.unsafeCast(), checkSize = true), RegistrySectionDataProvider(registries.biomeRegistry, checkSize = false), SectionDataProvider(checkSize = false), IntArray(ProtocolDefinition.BLOCKS_PER_SECTION)) fun tick(connection: PlayConnection, chunkPosition: Vec2i, sectionHeight: Int) { if (blockEntities.isEmpty) { diff --git a/src/main/java/de/bixilon/minosoft/data/world/container/RegistrySectionDataProvider.kt b/src/main/java/de/bixilon/minosoft/data/world/container/RegistrySectionDataProvider.kt index 3f42fe6ed..93ff474ef 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/container/RegistrySectionDataProvider.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/container/RegistrySectionDataProvider.kt @@ -18,7 +18,7 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition class RegistrySectionDataProvider( val registry: AbstractRegistry, - data: Array = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION), + data: Array? = null, checkSize: Boolean = false, ) : SectionDataProvider(data, checkSize = checkSize) { diff --git a/src/main/java/de/bixilon/minosoft/data/world/container/SectionDataProvider.kt b/src/main/java/de/bixilon/minosoft/data/world/container/SectionDataProvider.kt index 6fbfd23cb..2b7bf7123 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/container/SectionDataProvider.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/container/SectionDataProvider.kt @@ -13,15 +13,16 @@ package de.bixilon.minosoft.data.world.container +import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.util.SemaphoreLock import glm_.vec3.Vec3i open class SectionDataProvider( - data: Array = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION), + data: Array? = null, val checkSize: Boolean = false, ) : Iterable { - protected var data = data + protected var data = data ?: arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION) private set protected val lock = SemaphoreLock() // lock while reading (blocks writing) var count: Int = 0 @@ -34,7 +35,12 @@ open class SectionDataProvider( private set init { - recalculate() + if (data != null) { + recalculate() + } else { + minPosition = Vec3i.EMPTY + maxPosition = Vec3i.EMPTY + } } @Suppress("UNCHECKED_CAST") @@ -55,9 +61,9 @@ open class SectionDataProvider( return data[y shl 8 or (z shl 4) or x] as T } + private fun recalculate() { var count = 0 - var value: Any? var minX = 16 var minY = 16 diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/CullUtil.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/CullUtil.kt index 12c49f969..aa5aa8dbe 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/CullUtil.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/CullUtil.kt @@ -5,12 +5,16 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparenci object CullUtil { fun Array.canCull(properties: FaceProperties, sameBlock: Boolean): Boolean { + val sizeStartX = properties.sizeStart.x + val sizeStartY = properties.sizeStart.y + val sizeEndX = properties.sizeEnd.x + val sizeEndY = properties.sizeEnd.y for (property in this) { if ( - property.sizeStart.x <= properties.sizeStart.x - && property.sizeStart.y <= properties.sizeStart.y - && property.sizeEnd.x >= properties.sizeEnd.x - && property.sizeEnd.y >= properties.sizeEnd.y + property.sizeStart.x <= sizeStartX + && property.sizeStart.y <= sizeStartY + && property.sizeEnd.x >= sizeEndX + && property.sizeEnd.y >= sizeEndY && !((properties.transparency == TextureTransparencies.OPAQUE && property.transparency != TextureTransparencies.OPAQUE) || (properties.transparency != TextureTransparencies.OPAQUE && property.transparency == properties.transparency && !sameBlock) || (properties.transparency == TextureTransparencies.TRANSPARENT && property.transparency == TextureTransparencies.TRANSLUCENT)) diff --git a/src/main/java/de/bixilon/minosoft/util/task/pool/ThreadPool.kt b/src/main/java/de/bixilon/minosoft/util/task/pool/ThreadPool.kt index 3560b8e65..8124b8eaf 100644 --- a/src/main/java/de/bixilon/minosoft/util/task/pool/ThreadPool.kt +++ b/src/main/java/de/bixilon/minosoft/util/task/pool/ThreadPool.kt @@ -13,22 +13,17 @@ package de.bixilon.minosoft.util.task.pool -import de.bixilon.minosoft.util.KUtil.synchronizedSetOf +import de.bixilon.minosoft.util.KUtil.synchronizedListOf import de.bixilon.minosoft.util.KUtil.toSynchronizedList -import de.bixilon.minosoft.util.KUtil.toSynchronizedSet -import java.util.concurrent.Callable -import java.util.concurrent.ExecutorService -import java.util.concurrent.Future -import java.util.concurrent.TimeUnit +import java.util.concurrent.* open class ThreadPool( val threadCount: Int = Runtime.getRuntime().availableProcessors(), private val name: String = "Worker#%d", ) : ExecutorService { private var state = ThreadPoolStates.STARTING - private val threads: MutableSet = synchronizedSetOf() - private val availableThreads: MutableSet = synchronizedSetOf() - private var pending: MutableSet = sortedSetOf({ a, b -> a.priority - b.priority }).toSynchronizedSet() + private var threads: MutableList = synchronizedListOf() + private var queue: PriorityBlockingQueue = PriorityBlockingQueue() private var nextThreadId = 0 init { @@ -37,43 +32,24 @@ open class ThreadPool( state = ThreadPoolStates.STARTED } - val pendingCount: Int - get() = pending.size + val queueSize: Int + get() = queue.size @Synchronized private fun checkThreads() { - fun wait() { - try { - availableThreads += Thread.currentThread() - Thread.sleep(Long.MAX_VALUE) - } catch (exception: InterruptedException) { - // Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Thread (${Thread.currentThread()} sleeping got interrupted" } - } - availableThreads -= Thread.currentThread() - } - for (i in 0 until threadCount - threads.size) { + var runnable: ThreadPoolRunnable val thread = Thread { while (true) { if (state == ThreadPoolStates.STOPPING) { break } - if (pending.isEmpty()) { - wait() + try { + runnable = queue.take() + } catch (exception: InterruptedException) { + break } - val runnable: ThreadPoolRunnable? - synchronized(pending) { - if (pending.isNotEmpty()) { - runnable = pending.iterator().next() - pending.remove(runnable) - } else { - runnable = null - } - } - if (runnable == null) { - continue - } try { runnable.thread = Thread.currentThread() runnable.runnable.run() @@ -83,9 +59,7 @@ open class ThreadPool( if (exception is InterruptedException) { // Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Thread ${Thread.currentThread()} was interrupted" } runnable.wasInterrupted = true - if (!runnable.interuptable) { - pending += runnable - } + queue += runnable if (state == ThreadPoolStates.STOPPING) { break @@ -94,30 +68,18 @@ open class ThreadPool( exception.printStackTrace() } } - - if (pending.isNotEmpty()) { - continue - } - wait() } threads -= Thread.currentThread() } thread.name = name.format(nextThreadId++) - threads += thread thread.start() + threads += thread } } + @Synchronized fun execute(runnable: ThreadPoolRunnable) { - pending += runnable - synchronized(availableThreads) { - if (availableThreads.isNotEmpty()) { - val thread = availableThreads.iterator().next() - availableThreads.remove(thread) - thread.interrupt() - // Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Interrupting thread $thread" } - } - } + queue += runnable } override fun execute(runnable: Runnable) { @@ -138,9 +100,7 @@ open class ThreadPool( state = ThreadPoolStates.STOPPING synchronized(threads) { for (thread in threads.toSynchronizedList()) { - if (thread.state == Thread.State.TIMED_WAITING) { - thread.interrupt() - } + thread.interrupt() } } while (threads.isNotEmpty()) { @@ -156,12 +116,8 @@ open class ThreadPool( thread.interrupt() } } - while (threads.isNotEmpty()) { - Thread.sleep(1L) - } state = ThreadPoolStates.STOPPED - - return mutableListOf() // ToDo + return mutableListOf() } override fun isShutdown(): Boolean { diff --git a/src/main/java/de/bixilon/minosoft/util/task/pool/ThreadPoolRunnable.kt b/src/main/java/de/bixilon/minosoft/util/task/pool/ThreadPoolRunnable.kt index 11fb071b8..909bd6d09 100644 --- a/src/main/java/de/bixilon/minosoft/util/task/pool/ThreadPoolRunnable.kt +++ b/src/main/java/de/bixilon/minosoft/util/task/pool/ThreadPoolRunnable.kt @@ -17,7 +17,7 @@ class ThreadPoolRunnable( val priority: Int = ThreadPool.NORMAL, var interuptable: Boolean = false, val runnable: Runnable, -) { +) : Comparable { var wasInterrupted = false var thread: Thread? = null @@ -27,4 +27,8 @@ class ThreadPoolRunnable( // Log.log(LogMessageType.OTHER, LogLevels.VERBOSE){"Interrupting runnable in thread $thread"} } } + + override fun compareTo(other: ThreadPoolRunnable): Int { + return priority - other.priority + } }