mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-09 07:20:04 -04:00
hud: improve memory usage
* Every HUDElement has its own mesh now * Reuse existing mesh data (don't allocate new memory) * Use Mesh data as cache for layouted elements (not a separate float array)
This commit is contained in:
parent
e2f4170bb8
commit
fc2b5a8502
@ -15,10 +15,10 @@ package de.bixilon.minosoft.gui.rendering.gui.elements
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMeshCache
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.isGreater
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.isSmaller
|
||||
@ -26,6 +26,7 @@ import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.max
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.min
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec4.Vec4iUtil.EMPTY
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec4.Vec4iUtil.spaceSize
|
||||
import de.bixilon.minosoft.util.collections.floats.DirectArrayFloatList
|
||||
import glm_.vec2.Vec2i
|
||||
import glm_.vec4.Vec4i
|
||||
|
||||
@ -41,7 +42,9 @@ abstract class Element(val hudRenderer: HUDRenderer) {
|
||||
_parent = value
|
||||
silentApply()
|
||||
}
|
||||
protected var cache = GUIMeshCache(hudRenderer.matrix, Mesh.TRIANGLE_TO_QUAD_ORDER, 0)
|
||||
|
||||
@Deprecated("Warning: Should not be directly accessed!")
|
||||
val cache = GUIMeshCache(hudRenderer.matrix, renderWindow.renderSystem.primitiveMeshOrder, 1000)
|
||||
open var cacheEnabled: Boolean = true
|
||||
open var initialCacheSize: Int = 100
|
||||
open var cacheUpToDate: Boolean = false
|
||||
@ -123,21 +126,36 @@ abstract class Element(val hudRenderer: HUDRenderer) {
|
||||
*/
|
||||
fun render(offset: Vec2i, z: Int, consumer: GUIVertexConsumer, options: GUIVertexOptions?): Int {
|
||||
val offset = Vec2i(offset)
|
||||
var directRendering = false
|
||||
if (consumer is GUIMesh && consumer.data == cache.data) {
|
||||
directRendering = true
|
||||
}
|
||||
if (RenderConstants.DISABLE_GUI_CACHE || !cacheEnabled) {
|
||||
return forceRender(offset, z, consumer, options)
|
||||
if (directRendering) {
|
||||
cache.clear()
|
||||
}
|
||||
val maxZ = forceRender(offset, z, consumer, options)
|
||||
if (directRendering) {
|
||||
cache.revision++
|
||||
}
|
||||
return maxZ
|
||||
}
|
||||
if (!cacheUpToDate || cache.offset != offset || hudRenderer.matrixChange || cache.matrix !== hudRenderer.matrix || z != cache.z) {
|
||||
val cache = GUIMeshCache(hudRenderer.matrix, renderWindow.renderSystem.primitiveMeshOrder)
|
||||
this.cache.clear()
|
||||
cache.matrix = hudRenderer.matrix
|
||||
cache.offset = Vec2i(offset)
|
||||
cache.z = z
|
||||
val maxZ = forceRender(offset, z, cache, options)
|
||||
cache.maxZ = maxZ
|
||||
cache.data.finish()
|
||||
this.cache = cache
|
||||
if (cache.data !is DirectArrayFloatList) {
|
||||
// raw mesh data
|
||||
cache.data.finish()
|
||||
}
|
||||
cacheUpToDate = true
|
||||
}
|
||||
|
||||
consumer.addCache(cache)
|
||||
if (!directRendering) {
|
||||
consumer.addCache(cache)
|
||||
}
|
||||
return cache.maxZ
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,6 @@ import de.bixilon.minosoft.gui.rendering.gui.hud.elements.other.WorldInfoHUDElem
|
||||
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.scoreboard.ScoreboardHUDElement
|
||||
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.tab.TabListHUDElement
|
||||
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.title.TitleHUDElement
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.IntegratedBufferTypes
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
|
||||
@ -49,7 +48,6 @@ import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
|
||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
|
||||
import de.bixilon.minosoft.util.KUtil.unsafeCast
|
||||
import de.bixilon.minosoft.util.collections.DirectArrayFloatList
|
||||
import glm_.glm
|
||||
import glm_.mat4x4.Mat4
|
||||
import glm_.vec2.Vec2
|
||||
@ -61,7 +59,6 @@ class HUDRenderer(
|
||||
) : Renderer, OtherDrawable {
|
||||
override val renderSystem: RenderSystem = renderWindow.renderSystem
|
||||
val shader = renderWindow.renderSystem.createShader("minosoft:hud".toResourceLocation())
|
||||
private lateinit var mesh: GUIMesh
|
||||
var scaledSize: Vec2i = renderWindow.window.size
|
||||
var matrix: Mat4 = Mat4()
|
||||
private var enabled = true
|
||||
@ -144,6 +141,9 @@ class HUDRenderer(
|
||||
|
||||
for (element in this.hudElements.toSynchronizedMap().values) {
|
||||
element.postInit()
|
||||
if (element is LayoutedHUDElement<*>) {
|
||||
element.initMesh()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,15 +154,6 @@ class HUDRenderer(
|
||||
}
|
||||
|
||||
override fun drawOther() {
|
||||
val data = if (this::mesh.isInitialized) {
|
||||
mesh.unload()
|
||||
mesh.data.buffer.clear()
|
||||
mesh.data
|
||||
} else {
|
||||
DirectArrayFloatList()
|
||||
}
|
||||
|
||||
mesh = GUIMesh(renderWindow, matrix, data)
|
||||
val hudElements = hudElements.toSynchronizedMap().values
|
||||
|
||||
val time = System.currentTimeMillis()
|
||||
@ -192,13 +183,18 @@ class HUDRenderer(
|
||||
element.draw()
|
||||
}
|
||||
if (element is LayoutedHUDElement<*>) {
|
||||
z += element.layout.render(element.layoutOffset, z, mesh, null)
|
||||
z += element.prepare(z)
|
||||
}
|
||||
}
|
||||
|
||||
setup()
|
||||
mesh.load()
|
||||
mesh.draw()
|
||||
|
||||
for (element in hudElements) {
|
||||
if (element !is LayoutedHUDElement<*> || !element.enabled || element.mesh.data.isEmpty) {
|
||||
continue
|
||||
}
|
||||
element.mesh.draw()
|
||||
}
|
||||
|
||||
if (matrixChange) {
|
||||
matrixChange = false
|
||||
|
@ -17,11 +17,17 @@ import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
||||
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDElement
|
||||
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh
|
||||
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
|
||||
import de.bixilon.minosoft.util.collections.floats.DirectArrayFloatList
|
||||
import glm_.vec2.Vec2i
|
||||
|
||||
abstract class LayoutedHUDElement<T : Element>(final override val hudRenderer: HUDRenderer) : HUDElement {
|
||||
override val renderWindow: RenderWindow = hudRenderer.renderWindow
|
||||
final override val renderWindow: RenderWindow = hudRenderer.renderWindow
|
||||
override var enabled = true
|
||||
var mesh: GUIMesh = GUIMesh(renderWindow, hudRenderer.matrix, DirectArrayFloatList(1000))
|
||||
private var lastRevision = 0L
|
||||
|
||||
|
||||
abstract val layout: T
|
||||
abstract val layoutOffset: Vec2i
|
||||
@ -29,4 +35,32 @@ abstract class LayoutedHUDElement<T : Element>(final override val hudRenderer: H
|
||||
override fun tick() {
|
||||
layout.tick()
|
||||
}
|
||||
|
||||
private fun createNewMesh() {
|
||||
val mesh = this.mesh
|
||||
if (mesh.state == Mesh.MeshStates.LOADED) {
|
||||
mesh.unload()
|
||||
}
|
||||
this.mesh = GUIMesh(renderWindow, hudRenderer.matrix, mesh.data)
|
||||
}
|
||||
|
||||
fun prepare(z: Int): Int {
|
||||
val layoutOffset = layoutOffset
|
||||
val usedZ = layout.render(layoutOffset, z, mesh, null)
|
||||
|
||||
val revision = layout.cache.revision
|
||||
if (revision != lastRevision) {
|
||||
createNewMesh()
|
||||
this.mesh.load()
|
||||
this.lastRevision = revision
|
||||
}
|
||||
|
||||
return usedZ
|
||||
}
|
||||
|
||||
|
||||
fun initMesh() {
|
||||
layout.cache.data = mesh.data
|
||||
mesh.load()
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.EntityRaycastHit
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.BlendingFunctions
|
||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
import de.bixilon.minosoft.util.collections.DirectArrayFloatList
|
||||
import de.bixilon.minosoft.util.collections.floats.DirectArrayFloatList
|
||||
|
||||
class CrosshairHUDElement(hudRenderer: HUDRenderer) : CustomHUDElement(hudRenderer) {
|
||||
private lateinit var crosshairAtlasElement: HUDAtlasElement
|
||||
|
@ -19,7 +19,7 @@ import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
|
||||
import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct
|
||||
import de.bixilon.minosoft.util.collections.DirectArrayFloatList
|
||||
import de.bixilon.minosoft.util.collections.floats.DirectArrayFloatList
|
||||
import glm_.mat4x4.Mat4
|
||||
import glm_.vec2.Vec2
|
||||
import glm_.vec2.Vec2t
|
||||
|
@ -16,27 +16,39 @@ package de.bixilon.minosoft.gui.rendering.gui.mesh
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
|
||||
import de.bixilon.minosoft.util.collections.ArrayFloatList
|
||||
import de.bixilon.minosoft.util.collections.floats.AbstractFloatList
|
||||
import de.bixilon.minosoft.util.collections.floats.HeapArrayFloatList
|
||||
import glm_.mat4x4.Mat4
|
||||
import glm_.vec2.Vec2
|
||||
import glm_.vec2.Vec2i
|
||||
import glm_.vec2.Vec2t
|
||||
|
||||
class GUIMeshCache(
|
||||
val matrix: Mat4,
|
||||
var matrix: Mat4,
|
||||
override val order: Array<Pair<Int, Int>>,
|
||||
initialCacheSize: Int = 1000,
|
||||
var data: AbstractFloatList = HeapArrayFloatList(initialCacheSize),
|
||||
) : GUIVertexConsumer {
|
||||
val data: ArrayFloatList = ArrayFloatList(initialCacheSize)
|
||||
var revision: Long = 0
|
||||
var offset: Vec2i = Vec2i.EMPTY
|
||||
var z: Int = 0
|
||||
var maxZ: Int = 0
|
||||
|
||||
fun clear() {
|
||||
if (data.finished) {
|
||||
data = HeapArrayFloatList(initialSize = data.size)
|
||||
} else {
|
||||
data.clear()
|
||||
}
|
||||
}
|
||||
|
||||
override fun addVertex(position: Vec2t<*>, z: Int, texture: AbstractTexture, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
data.addAll(GUIMesh.createVertex(matrix, position, z, texture, uv, tint, options))
|
||||
revision++
|
||||
}
|
||||
|
||||
override fun addCache(cache: GUIMeshCache) {
|
||||
data.addAll(cache.data)
|
||||
revision++
|
||||
}
|
||||
}
|
||||
|
@ -27,9 +27,13 @@ class FloatOpenGLVertexBuffer(override val structure: MeshStruct, data: FloatBuf
|
||||
glBindVertexArray(vao)
|
||||
|
||||
bind()
|
||||
val previousLimit = buffer.limit()
|
||||
val previousPosition = buffer.position()
|
||||
buffer.limit(buffer.position())
|
||||
buffer.flip()
|
||||
glBufferData(type.gl, buffer, drawTypes.gl)
|
||||
buffer.limit(previousLimit)
|
||||
buffer.position(previousPosition)
|
||||
state = RenderBufferStates.UPLOADED
|
||||
|
||||
_data = null
|
||||
|
@ -16,7 +16,7 @@ package de.bixilon.minosoft.gui.rendering.util.mesh
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.FloatVertexBuffer
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.PrimitiveTypes
|
||||
import de.bixilon.minosoft.util.collections.DirectArrayFloatList
|
||||
import de.bixilon.minosoft.util.collections.floats.DirectArrayFloatList
|
||||
import glm_.vec2.Vec2
|
||||
import glm_.vec3.Vec3
|
||||
|
||||
@ -53,6 +53,7 @@ abstract class Mesh(
|
||||
_data = null
|
||||
}
|
||||
vertices = buffer.vertices
|
||||
state = MeshStates.LOADED
|
||||
}
|
||||
|
||||
fun draw() {
|
||||
|
@ -0,0 +1,15 @@
|
||||
package de.bixilon.minosoft.util.collections
|
||||
|
||||
abstract class AbstractPrimitiveList<T> : Clearable {
|
||||
var finished: Boolean = false
|
||||
protected set
|
||||
abstract val limit: Int
|
||||
abstract val size: Int
|
||||
abstract val isEmpty: Boolean
|
||||
|
||||
protected abstract fun ensureSize(needed: Int)
|
||||
abstract fun add(value: T)
|
||||
|
||||
abstract fun finish()
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package de.bixilon.minosoft.util.collections.floats
|
||||
|
||||
import de.bixilon.minosoft.util.collections.AbstractPrimitiveList
|
||||
|
||||
abstract class AbstractFloatList : AbstractPrimitiveList<Float>() {
|
||||
|
||||
abstract fun addAll(floats: FloatArray)
|
||||
abstract fun addAll(floatList: AbstractFloatList)
|
||||
|
||||
abstract fun toArray(): FloatArray
|
||||
}
|
@ -11,25 +11,24 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.util.collections
|
||||
package de.bixilon.minosoft.util.collections.floats
|
||||
|
||||
import de.bixilon.minosoft.util.KUtil
|
||||
import org.lwjgl.system.MemoryUtil.memAllocFloat
|
||||
import org.lwjgl.system.MemoryUtil.memFree
|
||||
import java.nio.BufferOverflowException
|
||||
import java.nio.FloatBuffer
|
||||
|
||||
class DirectArrayFloatList(
|
||||
initialSize: Int = DEFAULT_INITIAL_SIZE,
|
||||
) {
|
||||
var buffer: FloatBuffer = memAllocFloat(initialSize) // ToDo: Clear when disconnected
|
||||
) : AbstractFloatList() {
|
||||
var buffer: FloatBuffer = memAllocFloat(initialSize)
|
||||
private set
|
||||
var finalized: Boolean = false
|
||||
private set
|
||||
val capacity: Int
|
||||
override val limit: Int
|
||||
get() = buffer.capacity()
|
||||
val size: Int
|
||||
override val size: Int
|
||||
get() = buffer.position()
|
||||
val isEmpty: Boolean
|
||||
override val isEmpty: Boolean
|
||||
get() = size == 0
|
||||
private var unloaded = false
|
||||
|
||||
@ -43,17 +42,17 @@ class DirectArrayFloatList(
|
||||
private var outputUpToDate = false
|
||||
|
||||
private fun checkFinalized() {
|
||||
if (finalized) {
|
||||
if (finished) {
|
||||
throw IllegalStateException("ArrayFloatList is already finalized!")
|
||||
}
|
||||
}
|
||||
|
||||
private fun ensureSize(needed: Int) {
|
||||
override fun ensureSize(needed: Int) {
|
||||
checkFinalized()
|
||||
if (capacity - size >= needed) {
|
||||
if (limit - size >= needed) {
|
||||
return
|
||||
}
|
||||
var newSize = capacity
|
||||
var newSize = limit
|
||||
while (newSize - size < needed) {
|
||||
newSize += nextGrowStep
|
||||
}
|
||||
@ -70,35 +69,40 @@ class DirectArrayFloatList(
|
||||
memFree(oldBuffer)
|
||||
}
|
||||
|
||||
fun add(float: Float) {
|
||||
override fun add(value: Float) {
|
||||
ensureSize(1)
|
||||
buffer.put(float)
|
||||
buffer.put(value)
|
||||
outputUpToDate = false
|
||||
}
|
||||
|
||||
fun addAll(floats: FloatArray) {
|
||||
override fun addAll(floats: FloatArray) {
|
||||
ensureSize(floats.size)
|
||||
buffer.put(floats)
|
||||
try {
|
||||
buffer.put(floats)
|
||||
} catch (exception: BufferOverflowException) {
|
||||
ensureSize(floats.size)
|
||||
|
||||
exception.printStackTrace()
|
||||
}
|
||||
outputUpToDate = false
|
||||
}
|
||||
|
||||
fun addAll(floatList: DirectArrayFloatList) {
|
||||
ensureSize(floatList.size)
|
||||
if (FLOAT_PUT_METHOD == null) { // Java < 16
|
||||
for (i in 0 until floatList.buffer.position()) {
|
||||
buffer.put(floatList.buffer.get(i))
|
||||
override fun addAll(floatList: AbstractFloatList) {
|
||||
if (floatList is DirectArrayFloatList) {
|
||||
ensureSize(floatList.size)
|
||||
if (FLOAT_PUT_METHOD == null) { // Java < 16
|
||||
for (i in 0 until floatList.buffer.position()) {
|
||||
buffer.put(floatList.buffer.get(i))
|
||||
}
|
||||
} else {
|
||||
FLOAT_PUT_METHOD.invoke(buffer, buffer.position(), floatList.buffer, 0, floatList.buffer.position())
|
||||
buffer.position(buffer.position() + floatList.buffer.position())
|
||||
}
|
||||
} else {
|
||||
FLOAT_PUT_METHOD.invoke(buffer, buffer.position(), floatList.buffer, 0, floatList.buffer.position())
|
||||
buffer.position(buffer.position() + floatList.buffer.position())
|
||||
addAll(floatList.toArray())
|
||||
}
|
||||
}
|
||||
|
||||
fun addAll(floatList: ArrayFloatList) {
|
||||
ensureSize(floatList.size)
|
||||
buffer.put(floatList.toArray())
|
||||
}
|
||||
|
||||
private fun checkOutputArray() {
|
||||
if (outputUpToDate) {
|
||||
return
|
||||
@ -111,7 +115,7 @@ class DirectArrayFloatList(
|
||||
outputUpToDate = true
|
||||
}
|
||||
|
||||
fun toArray(): FloatArray {
|
||||
override fun toArray(): FloatArray {
|
||||
checkOutputArray()
|
||||
return output
|
||||
}
|
||||
@ -119,12 +123,20 @@ class DirectArrayFloatList(
|
||||
fun unload() {
|
||||
check(!unloaded) { "Already unloaded!" }
|
||||
unloaded = true
|
||||
finalized = true // Is unloaded
|
||||
finished = true // Is unloaded
|
||||
memFree(buffer)
|
||||
}
|
||||
|
||||
fun finish() {
|
||||
finalized = true
|
||||
override fun clear() {
|
||||
buffer.clear()
|
||||
if (output.isNotEmpty()) {
|
||||
output = FloatArray(0)
|
||||
}
|
||||
outputUpToDate = false
|
||||
}
|
||||
|
||||
override fun finish() {
|
||||
finished = true
|
||||
val oldBuffer = buffer
|
||||
buffer = memAllocFloat(oldBuffer.position())
|
||||
if (FLOAT_PUT_METHOD == null) { // Java < 16
|
@ -10,19 +10,16 @@
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
package de.bixilon.minosoft.util.collections
|
||||
package de.bixilon.minosoft.util.collections.floats
|
||||
|
||||
class ArrayFloatList(
|
||||
class HeapArrayFloatList(
|
||||
initialSize: Int = DEFAULT_INITIAL_SIZE,
|
||||
) {
|
||||
) : AbstractFloatList() {
|
||||
private var data: FloatArray = FloatArray(initialSize)
|
||||
var finalized: Boolean = false
|
||||
private set
|
||||
val limit: Int
|
||||
override val limit: Int
|
||||
get() = data.size
|
||||
var size = 0
|
||||
private set
|
||||
val isEmpty: Boolean
|
||||
override var size = 0
|
||||
override val isEmpty: Boolean
|
||||
get() = size == 0
|
||||
|
||||
private val nextGrowStep = when {
|
||||
@ -35,19 +32,19 @@ class ArrayFloatList(
|
||||
private var outputUpToDate = false
|
||||
|
||||
private fun checkFinalized() {
|
||||
if (finalized) {
|
||||
if (finished) {
|
||||
throw IllegalStateException("ArrayFloatList is already finalized!")
|
||||
}
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
override fun clear() {
|
||||
checkFinalized()
|
||||
size = 0
|
||||
outputUpToDate = false
|
||||
output = FloatArray(0)
|
||||
}
|
||||
|
||||
private fun ensureSize(needed: Int) {
|
||||
override fun ensureSize(needed: Int) {
|
||||
checkFinalized()
|
||||
if (limit - size >= needed) {
|
||||
return
|
||||
@ -61,25 +58,29 @@ class ArrayFloatList(
|
||||
System.arraycopy(oldData, 0, data, 0, oldData.size)
|
||||
}
|
||||
|
||||
fun add(float: Float) {
|
||||
override fun add(value: Float) {
|
||||
ensureSize(1)
|
||||
data[size++] = float
|
||||
data[size++] = value
|
||||
outputUpToDate = false
|
||||
}
|
||||
|
||||
fun addAll(floats: FloatArray) {
|
||||
override fun addAll(floats: FloatArray) {
|
||||
ensureSize(floats.size)
|
||||
System.arraycopy(floats, 0, data, size, floats.size)
|
||||
size += floats.size
|
||||
outputUpToDate = false
|
||||
}
|
||||
|
||||
fun addAll(floatList: ArrayFloatList) {
|
||||
override fun addAll(floatList: AbstractFloatList) {
|
||||
ensureSize(floatList.size)
|
||||
val source = if (floatList.finalized) {
|
||||
floatList.output
|
||||
val source: FloatArray = if (floatList is HeapArrayFloatList) {
|
||||
if (floatList.finished) {
|
||||
floatList.output
|
||||
} else {
|
||||
floatList.data
|
||||
}
|
||||
} else {
|
||||
floatList.data
|
||||
floatList.toArray()
|
||||
}
|
||||
System.arraycopy(source, 0, data, size, floatList.size)
|
||||
size += floatList.size
|
||||
@ -94,13 +95,13 @@ class ArrayFloatList(
|
||||
outputUpToDate = true
|
||||
}
|
||||
|
||||
fun toArray(): FloatArray {
|
||||
override fun toArray(): FloatArray {
|
||||
checkOutputArray()
|
||||
return output
|
||||
}
|
||||
|
||||
fun finish() {
|
||||
finalized = true
|
||||
override fun finish() {
|
||||
finished = true
|
||||
checkOutputArray()
|
||||
data = FloatArray(0)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user