From 808797760d4da0fa43eb3db3f2319a4127278263 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Wed, 9 Jan 2019 05:43:56 +0900 Subject: [PATCH] circular array is fixed and tested --- build.gradle | 8 +++ src/net/torvald/dataclass/CircularArray.kt | 54 +++++++++++-------- src/net/torvald/terrarum/AppLoader.java | 6 ++- src/net/torvald/terrarum/Terrarum.kt | 2 +- .../debuggerapp/TraversingCircularArray.java | 7 +++ .../terrarum/tests/CircularArrayTest.kt | 47 ++++++++++++++++ .../SurroundPannerTest.kt | 5 +- 7 files changed, 102 insertions(+), 27 deletions(-) create mode 100644 src/net/torvald/terrarum/debuggerapp/TraversingCircularArray.java create mode 100644 src/net/torvald/terrarum/tests/CircularArrayTest.kt rename src/net/torvald/terrarum/{audio/surroundpanner => tests}/SurroundPannerTest.kt (98%) diff --git a/build.gradle b/build.gradle index 889cc6b8c..4aa5cf526 100644 --- a/build.gradle +++ b/build.gradle @@ -52,6 +52,14 @@ task game(type: JavaExec) { description = "Launches the game. Should be the same as 'gradlew run'." } +task gamedebug(type: JavaExec) { + classpath sourceSets.main.runtimeClasspath + main = 'net.torvald.terrarum.AppLoader' + group = "Application" + description = "Launches the game with debuy key." + args = ["isdev=true"] +} + task spriteassembler(type: JavaExec) { classpath sourceSets.main.runtimeClasspath main = 'net.torvald.spriteassembler.SpriteAssemblerAppKt' diff --git a/src/net/torvald/dataclass/CircularArray.kt b/src/net/torvald/dataclass/CircularArray.kt index 9b2be72cf..ed932bd3d 100644 --- a/src/net/torvald/dataclass/CircularArray.kt +++ b/src/net/torvald/dataclass/CircularArray.kt @@ -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(val size: Int) { val buffer: Array = arrayOfNulls(size) as Array - 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 fold(initial: R, operation: (R, T) -> R): R { + fun 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 + ")" diff --git a/src/net/torvald/terrarum/AppLoader.java b/src/net/torvald/terrarum/AppLoader.java index aee92603a..60817297b 100644 --- a/src/net/torvald/terrarum/AppLoader.java +++ b/src/net/torvald/terrarum/AppLoader.java @@ -53,7 +53,7 @@ public class AppLoader implements ApplicationListener { /** * when FALSE, some assertion and print code will not execute */ - public static final boolean IS_DEVELOPMENT_BUILD = true; + public static boolean IS_DEVELOPMENT_BUILD = false; /** @@ -169,6 +169,10 @@ public class AppLoader implements ApplicationListener { appConfig.title = GAME_NAME; appConfig.forceExit = false; + if (args.length == 1 && args[0].equals("isdev=true")) { + IS_DEVELOPMENT_BUILD = true; + } + new LwjglApplication(new AppLoader(appConfig), appConfig); } diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index bf18e73f5..324f791cc 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -621,8 +621,8 @@ fun gdxClearAndSetBlend(r: Float, g: Float, b: Float, a: Float) { // this assumens premultiplied alpha? //Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) - // alpha must not be premultiplied + // alpha must not be premultiplied Gdx.gl.glBlendFuncSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_SRC_ALPHA, GL20.GL_ONE) Gdx.gl.glBlendEquation(GL20.GL_FUNC_ADD) } diff --git a/src/net/torvald/terrarum/debuggerapp/TraversingCircularArray.java b/src/net/torvald/terrarum/debuggerapp/TraversingCircularArray.java new file mode 100644 index 000000000..6e9762c0b --- /dev/null +++ b/src/net/torvald/terrarum/debuggerapp/TraversingCircularArray.java @@ -0,0 +1,7 @@ +package net.torvald.terrarum.debuggerapp; + +/** + * Created by minjaesong on 2019-01-09. + */ +public class TraversingCircularArray { +} diff --git a/src/net/torvald/terrarum/tests/CircularArrayTest.kt b/src/net/torvald/terrarum/tests/CircularArrayTest.kt new file mode 100644 index 000000000..8bcb0b580 --- /dev/null +++ b/src/net/torvald/terrarum/tests/CircularArrayTest.kt @@ -0,0 +1,47 @@ +import net.torvald.dataclass.CircularArray + +/** + * Created by minjaesong on 2019-01-09. + */ +class CircularArrayTest { + + operator fun invoke() { + val testSet = CircularArray(5) + val testSet2 = CircularArray(5) + + for (i in 1..5) { + testSet.add(i) + } + + println("Metadata:") + println(testSet) + println("forEach():") + testSet.forEach { print("$it ") } + println("\nfold(0, sum):") + println(testSet.fold(0) { acc, v -> acc + (v ?: 0) }) + println("Raw:") + testSet.buffer.forEach { print("$it ") } + println() + + println() + for (i in 1..6) { + testSet2.add(i) + } + + println("Metadata:") + println(testSet2) + println("forEach():") + testSet2.forEach { print("$it ") } + println("\nfold(0, sum):") + println(testSet2.fold(0) { acc, v -> acc + (v ?: 0) }) + println("Raw:") + testSet2.buffer.forEach { print("$it ") } + println() + + } + +} + +fun main(args: Array) { + CircularArrayTest().invoke() +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/audio/surroundpanner/SurroundPannerTest.kt b/src/net/torvald/terrarum/tests/SurroundPannerTest.kt similarity index 98% rename from src/net/torvald/terrarum/audio/surroundpanner/SurroundPannerTest.kt rename to src/net/torvald/terrarum/tests/SurroundPannerTest.kt index 22a3cf90a..2daae4d08 100644 --- a/src/net/torvald/terrarum/audio/surroundpanner/SurroundPannerTest.kt +++ b/src/net/torvald/terrarum/tests/SurroundPannerTest.kt @@ -1,4 +1,3 @@ -package net.torvald.terrarum.audio.surroundpanner import com.badlogic.gdx.Game import com.badlogic.gdx.Gdx @@ -7,7 +6,9 @@ import com.badlogic.gdx.backends.lwjgl.LwjglApplication import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration import com.badlogic.gdx.files.FileHandle import java.awt.BorderLayout -import javax.swing.* +import javax.swing.JFrame +import javax.swing.JPanel +import javax.swing.JSlider /** * Created by minjaesong on 2018-05-18.