mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-07 17:14:06 +09:00
circular array is fixed and tested
This commit is contained in:
@@ -2,6 +2,8 @@ package net.torvald.dataclass
|
||||
|
||||
|
||||
/**
|
||||
* buffer[head] contains the most recent item, whereas buffer[tail] contains the oldest one.
|
||||
*
|
||||
* Notes for particle storage:
|
||||
* Particles does not need to be removed, just let it overwrite as their operation is rather
|
||||
* lightweight. So, just flagDespawn = true if it need to be "deleted" so that it won't update
|
||||
@@ -12,57 +14,63 @@ package net.torvald.dataclass
|
||||
class CircularArray<T>(val size: Int) {
|
||||
|
||||
val buffer: Array<T> = arrayOfNulls<Any>(size) as Array<T>
|
||||
var tail: Int = 0
|
||||
var head: Int = 0
|
||||
var tail: Int = 0; private set
|
||||
var head: Int = -1; private set
|
||||
|
||||
private var unreliableAddCount = 0
|
||||
|
||||
val lastIndex = size - 1
|
||||
|
||||
/** elemCount == size means it has the exact elements and no more.
|
||||
* If elemCount is greater by 1 against the size, it means it started to circle, elemCount won't increment at this point. */
|
||||
val elemCount: Int
|
||||
get() = if (tail >= head) tail - head else size
|
||||
get() = unreliableAddCount
|
||||
|
||||
fun add(item: T) {
|
||||
buffer[tail] = item // overwrites oldest item when eligible
|
||||
tail = (tail + 1) % size
|
||||
if (tail == head) {
|
||||
head = (head + 1) % size
|
||||
if (unreliableAddCount <= size) unreliableAddCount += 1
|
||||
|
||||
head = (head + 1) % size
|
||||
if (unreliableAddCount > size) {
|
||||
tail = (tail + 1) % size
|
||||
}
|
||||
|
||||
buffer[head] = item // overwrites oldest item when eligible
|
||||
|
||||
|
||||
//println("$this $unreliableAddCount")
|
||||
}
|
||||
|
||||
inline fun forEach(action: (T) -> Unit) {
|
||||
/**
|
||||
* Iterates the array with oldest element first.
|
||||
*/
|
||||
fun forEach(action: (T) -> Unit) {
|
||||
// has slightly better iteration performance than lambda
|
||||
if (tail >= head) {
|
||||
for (i in head..tail - 1)
|
||||
if (unreliableAddCount <= size) {
|
||||
for (i in 0..head)
|
||||
action(buffer[i])
|
||||
}
|
||||
else {
|
||||
for (i in 0..size - 1)
|
||||
action(buffer[(i + head) % size])
|
||||
action(buffer[(i + tail) % size])
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME not working as intended
|
||||
inline fun <R> fold(initial: R, operation: (R, T) -> R): R {
|
||||
fun <R> fold(initial: R, operation: (R, T) -> R): R {
|
||||
var accumulator = initial
|
||||
//for (element in buffer) accumulator = operation(accumulator, element)
|
||||
if (tail >= head) {
|
||||
for (i in head..tail - 1)
|
||||
operation(accumulator, buffer[i])
|
||||
if (unreliableAddCount <= size) {
|
||||
for (i in 0..head)
|
||||
accumulator = operation(accumulator, buffer[i])
|
||||
}
|
||||
else {
|
||||
for (i in 0..size - 1)
|
||||
operation(accumulator, buffer[(i + head) % size])
|
||||
accumulator = operation(accumulator, buffer[(i + tail) % size])
|
||||
}
|
||||
|
||||
return accumulator
|
||||
}
|
||||
|
||||
inline fun forEachConcurrent(action: (T) -> Unit) {
|
||||
TODO()
|
||||
}
|
||||
|
||||
inline fun forEachConcurrentWaitFor(action: (T) -> Unit) {
|
||||
TODO()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "CircularArray(size=" + buffer.size + ", head=" + head + ", tail=" + tail + ")"
|
||||
|
||||
Reference in New Issue
Block a user