mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-17 00:56:07 +09:00
sortedarraylist update; physball breaks the actor render dunno why
This commit is contained in:
@@ -95,6 +95,7 @@ class SpriteAssemblerApp(val gdxWindow: SpriteAssemblerPreview) : JFrame() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
panelCode.font = Font(Font.MONOSPACED, Font.PLAIN, 12)
|
panelCode.font = Font(Font.MONOSPACED, Font.PLAIN, 12)
|
||||||
|
panelCode.text = "Enter your descriptor code here…"
|
||||||
|
|
||||||
panelAnimationsList.model = DefaultListModel()
|
panelAnimationsList.model = DefaultListModel()
|
||||||
panelBodypartsList.model = DefaultListModel()
|
panelBodypartsList.model = DefaultListModel()
|
||||||
@@ -278,7 +279,7 @@ class SpriteAssemblerPreview: Game() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gdxClearAndSetBlend(.62f,.79f,1f,1f)
|
gdxClearAndSetBlend(bgCol)
|
||||||
|
|
||||||
|
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ public class AppLoader implements ApplicationListener {
|
|||||||
|
|
||||||
/** A gamepad. Multiple gamepads may controll this single virtualised gamepad. */
|
/** A gamepad. Multiple gamepads may controll this single virtualised gamepad. */
|
||||||
public static TerrarumController gamepad = null;
|
public static TerrarumController gamepad = null;
|
||||||
public static float gamepadDeadzone = 0.2f;
|
public static float gamepadDeadzone = 0.3f;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -688,6 +688,7 @@ public class AppLoader implements ApplicationListener {
|
|||||||
System.out.println(String.format("os.name = %s (with identifier %s)", OSName, operationSystem));
|
System.out.println(String.format("os.name = %s (with identifier %s)", OSName, operationSystem));
|
||||||
System.out.println(String.format("os.version = %s", OSVersion));
|
System.out.println(String.format("os.version = %s", OSVersion));
|
||||||
System.out.println(String.format("default directory: %s", defaultDir));
|
System.out.println(String.format("default directory: %s", defaultDir));
|
||||||
|
System.out.println(String.format("java version = %s", System.getProperty("java.version")));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createDirs() {
|
private static void createDirs() {
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
|||||||
import net.torvald.terrarum.realestate.LandUtil
|
import net.torvald.terrarum.realestate.LandUtil
|
||||||
import net.torvald.terrarum.ui.ConsoleWindow
|
import net.torvald.terrarum.ui.ConsoleWindow
|
||||||
import net.torvald.util.SortedArrayList
|
import net.torvald.util.SortedArrayList
|
||||||
import java.util.*
|
|
||||||
import java.util.concurrent.locks.Lock
|
import java.util.concurrent.locks.Lock
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -143,11 +142,11 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
|||||||
if (actorContainerActive.size == 0 && actorContainerInactive.size == 0)
|
if (actorContainerActive.size == 0 && actorContainerInactive.size == 0)
|
||||||
throw IllegalArgumentException("Actor with ID $ID does not exist.")
|
throw IllegalArgumentException("Actor with ID $ID does not exist.")
|
||||||
|
|
||||||
var index = actorContainerActive.binarySearch(ID)
|
var actor = actorContainerActive.searchFor(ID) { it.referenceID!! }
|
||||||
if (index < 0) {
|
if (actor == null) {
|
||||||
index = actorContainerInactive.binarySearch(ID)
|
actor = actorContainerInactive.searchFor(ID) { it.referenceID!! }
|
||||||
|
|
||||||
if (index < 0) {
|
if (actor == null) {
|
||||||
/*JOptionPane.showMessageDialog(
|
/*JOptionPane.showMessageDialog(
|
||||||
null,
|
null,
|
||||||
"Actor with ID $ID does not exist.",
|
"Actor with ID $ID does not exist.",
|
||||||
@@ -156,36 +155,14 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
|||||||
throw IllegalArgumentException("Actor with ID $ID does not exist.")
|
throw IllegalArgumentException("Actor with ID $ID does not exist.")
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return actorContainerInactive[index]
|
return actor
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return actorContainerActive[index]
|
return actor
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ArrayList<*>.binarySearch(actor: Actor) = this.binarySearch(actor.referenceID!!)
|
//fun SortedArrayList<*>.binarySearch(actor: Actor) = this.toArrayList().binarySearch(actor.referenceID!!)
|
||||||
|
//fun SortedArrayList<*>.binarySearch(ID: Int) = this.toArrayList().binarySearch(ID)
|
||||||
fun ArrayList<*>.binarySearch(ID: Int): Int {
|
|
||||||
// code from collections/Collections.kt
|
|
||||||
var low = 0
|
|
||||||
var high = this.size - 1
|
|
||||||
|
|
||||||
while (low <= high) {
|
|
||||||
val mid = (low + high).ushr(1) // safe from overflows
|
|
||||||
|
|
||||||
val midVal = get(mid)!!
|
|
||||||
|
|
||||||
if (ID > midVal.hashCode())
|
|
||||||
low = mid + 1
|
|
||||||
else if (ID < midVal.hashCode())
|
|
||||||
high = mid - 1
|
|
||||||
else
|
|
||||||
return mid // key found
|
|
||||||
}
|
|
||||||
return -(low + 1) // key not found
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SortedArrayList<*>.binarySearch(actor: Actor) = this.toArrayList().binarySearch(actor.referenceID!!)
|
|
||||||
fun SortedArrayList<*>.binarySearch(ID: Int) = this.toArrayList().binarySearch(ID)
|
|
||||||
|
|
||||||
open fun removeActor(ID: Int) = removeActor(getActorByID(ID))
|
open fun removeActor(ID: Int) = removeActor(getActorByID(ID))
|
||||||
/**
|
/**
|
||||||
@@ -199,9 +176,9 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
|||||||
open fun removeActor(actor: Actor?) {
|
open fun removeActor(actor: Actor?) {
|
||||||
if (actor == null) return
|
if (actor == null) return
|
||||||
|
|
||||||
val indexToDelete = actorContainerActive.binarySearch(actor.referenceID!!)
|
val indexToDelete = actorContainerActive.searchFor(actor.referenceID!!) { it.referenceID!! }
|
||||||
if (indexToDelete >= 0) {
|
if (indexToDelete != null) {
|
||||||
actorContainerActive.removeAt(indexToDelete)
|
actorContainerActive.remove(indexToDelete)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,13 +200,13 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
|||||||
if (actorContainerActive.size == 0)
|
if (actorContainerActive.size == 0)
|
||||||
false
|
false
|
||||||
else
|
else
|
||||||
actorContainerActive.binarySearch(ID) >= 0
|
actorContainerActive.searchFor(ID) { it.referenceID!! } != null
|
||||||
|
|
||||||
fun isInactive(ID: Int): Boolean =
|
fun isInactive(ID: Int): Boolean =
|
||||||
if (actorContainerInactive.size == 0)
|
if (actorContainerInactive.size == 0)
|
||||||
false
|
false
|
||||||
else
|
else
|
||||||
actorContainerInactive.binarySearch(ID) >= 0
|
actorContainerInactive.searchFor(ID) { it.referenceID!! } != null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* actorContainerActive extensions
|
* actorContainerActive extensions
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
|||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
|
||||||
import com.badlogic.gdx.utils.GdxRuntimeException
|
import com.badlogic.gdx.utils.GdxRuntimeException
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.util.CircularArray
|
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
import net.torvald.terrarum.AppLoader.*
|
import net.torvald.terrarum.AppLoader.*
|
||||||
import net.torvald.terrarum.gameactors.Actor
|
import net.torvald.terrarum.gameactors.Actor
|
||||||
@@ -23,6 +22,7 @@ import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
|||||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||||
import net.torvald.terrarumsansbitmap.gdx.GameFontBase
|
import net.torvald.terrarumsansbitmap.gdx.GameFontBase
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
|
import net.torvald.util.CircularArray
|
||||||
import org.lwjgl.BufferUtils
|
import org.lwjgl.BufferUtils
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
@@ -196,7 +196,6 @@ object Terrarum : Screen {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
println("$NAME version ${AppLoader.getVERSION_STRING()}")
|
println("$NAME version ${AppLoader.getVERSION_STRING()}")
|
||||||
println("Java Runtime version ${System.getProperty("java.version")}")
|
|
||||||
println("LibGDX version ${com.badlogic.gdx.Version.VERSION}")
|
println("LibGDX version ${com.badlogic.gdx.Version.VERSION}")
|
||||||
|
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ fun blendNormal(batch: SpriteBatch) {
|
|||||||
// - https://www.andersriggelsen.dk/glblendfunc.php
|
// - https://www.andersriggelsen.dk/glblendfunc.php
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun gdxClearAndSetBlend(color: Color) {
|
||||||
|
gdxClearAndSetBlend(color.r, color.g, color.b, color.a)
|
||||||
|
}
|
||||||
|
|
||||||
fun gdxClearAndSetBlend(r: Float, g: Float, b: Float, a: Float) {
|
fun gdxClearAndSetBlend(r: Float, g: Float, b: Float, a: Float) {
|
||||||
Gdx.gl.glClearColor(r,g,b,a)
|
Gdx.gl.glClearColor(r,g,b,a)
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ object Wire {
|
|||||||
const val BIT_UTILITY_PROTOTYPE = 2
|
const val BIT_UTILITY_PROTOTYPE = 2
|
||||||
const val BIT_POWER_LOW = 4
|
const val BIT_POWER_LOW = 4
|
||||||
const val BIT_POWER_HIGHT = 8
|
const val BIT_POWER_HIGHT = 8
|
||||||
const val BIT_ETHERNET = 16
|
const val BIT_PARALLEL_8B = 16 // uses bit-to-mantissa encoding
|
||||||
|
const val BIT_PARALLEL_16B = 32 // uses bit-to-mantissa encoding
|
||||||
|
const val BIT_ETHERNET = 64 // the actual datagramme should be represented by another means than the ConduitFills
|
||||||
|
|
||||||
/* A mapping for World's conduitFills[] index */
|
/* A mapping for World's WiringNode.fills[] index */
|
||||||
const val FILL_ID_SIGNAL_RED = 0
|
const val FILL_ID_SIGNAL_RED = 0
|
||||||
const val FILL_ID_UTILITY_PROTOTYPE = 1
|
const val FILL_ID_UTILITY_PROTOTYPE = 1
|
||||||
|
|
||||||
@@ -23,4 +25,22 @@ object Wire {
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes a byte to Float's mantissa. Normal value range is 1.0..1.99609375. When decoding, the sign and exponent bits
|
||||||
|
* must be ignored. (e.g. the encoded float might have non-one-point-something value after "bitwise" add/subtraction.
|
||||||
|
*
|
||||||
|
* MSB of the byte is also the highest bit in the mantissa. Therefore ```0x80``` will be encoded as ```1.5```
|
||||||
|
*/
|
||||||
|
fun Byte.toFloatMantissa(): Float = Float.fromBits(0x3F800000 or (this.toInt().and(0xFF) shl 15))
|
||||||
|
fun Short.toFloatMantissa(): Float = Float.fromBits(0x3F800000 or (this.toInt().and(0xFFFF) shl 7))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function does the reversal calculation.
|
||||||
|
*
|
||||||
|
* @see net.torvald.terrarum.blockproperties.Wire.toFloatMantissa
|
||||||
|
*/
|
||||||
|
fun Float.fromMantissaToByte(): Byte = this.toRawBits().ushr(15).and(0xFF).toByte()
|
||||||
|
fun Float.fromMantissaToShort(): Short = this.toRawBits().ushr(7).and(0xFFFF).toShort()
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ object CommandDict {
|
|||||||
"kill" to KillActor,
|
"kill" to KillActor,
|
||||||
"money" to MoneyDisp,
|
"money" to MoneyDisp,
|
||||||
"screenshot" to TakeScreenshot,
|
"screenshot" to TakeScreenshot,
|
||||||
//"resize" to ResizeScreen,
|
"resize" to ResizeScreen,
|
||||||
|
|
||||||
// Test codes
|
// Test codes
|
||||||
"bulletintest" to SetBulletin,
|
"bulletintest" to SetBulletin,
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
package net.torvald.terrarum.console
|
package net.torvald.terrarum.console
|
||||||
|
|
||||||
import net.torvald.terrarum.AppLoader
|
import net.torvald.terrarum.AppLoader
|
||||||
import net.torvald.terrarum.Terrarum
|
|
||||||
|
|
||||||
object ResizeScreen: ConsoleCommand {
|
object ResizeScreen: ConsoleCommand {
|
||||||
override fun execute(args: Array<String>) {
|
override fun execute(args: Array<String>) {
|
||||||
if (args.size == 3) {
|
if (args.size == 3) {
|
||||||
Terrarum.resize(args[1].toInt(), args[2].toInt())
|
AppLoader.resizeScreen(args[1].toInt(), args[2].toInt())
|
||||||
}
|
}
|
||||||
else if (args.size == 2) {
|
else if (args.size == 2) {
|
||||||
when (args[1]) {
|
when (args[1]) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.torvald.terrarum.gameactors
|
package net.torvald.terrarum.gameactors
|
||||||
|
|
||||||
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.itemproperties.ItemCodex.ACTORID_MIN
|
import net.torvald.terrarum.itemproperties.ItemCodex.ACTORID_MIN
|
||||||
|
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ abstract class Actor(val renderOrder: RenderOrder) : Comparable<Actor>, Runnable
|
|||||||
* Valid RefID is equal to or greater than 16777216.
|
* Valid RefID is equal to or greater than 16777216.
|
||||||
* @return Reference ID. (16777216-0x7FFF_FFFF)
|
* @return Reference ID. (16777216-0x7FFF_FFFF)
|
||||||
*/
|
*/
|
||||||
open var referenceID: ActorID? = null
|
open var referenceID: ActorID = Terrarum.generateUniqueReferenceID(renderOrder) // once this was nullable without initialiser. If you're going to revert to that, add the reason why this should be nullable.
|
||||||
var actorValue = ActorValue(this) // FIXME cyclic reference on GSON
|
var actorValue = ActorValue(this) // FIXME cyclic reference on GSON
|
||||||
@Volatile var flagDespawn = false
|
@Volatile var flagDespawn = false
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
package net.torvald.terrarum.gameworld
|
package net.torvald.terrarum.gameworld
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import net.torvald.util.SortedArrayList
|
|
||||||
import net.torvald.terrarum.AppLoader.printdbg
|
import net.torvald.terrarum.AppLoader.printdbg
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
@@ -12,6 +11,7 @@ import net.torvald.terrarum.modulebasegame.gameworld.WorldSimulator
|
|||||||
import net.torvald.terrarum.realestate.LandUtil
|
import net.torvald.terrarum.realestate.LandUtil
|
||||||
import net.torvald.terrarum.serialise.ReadLayerDataZip
|
import net.torvald.terrarum.serialise.ReadLayerDataZip
|
||||||
import net.torvald.terrarum.toInt
|
import net.torvald.terrarum.toInt
|
||||||
|
import net.torvald.util.SortedArrayList
|
||||||
import org.dyn4j.geometry.Vector2
|
import org.dyn4j.geometry.Vector2
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
import kotlin.math.sign
|
import kotlin.math.sign
|
||||||
@@ -74,6 +74,9 @@ open class GameWorld {
|
|||||||
val fluidTypes: HashMap<BlockAddress, FluidType>
|
val fluidTypes: HashMap<BlockAddress, FluidType>
|
||||||
@TEMzPayload("FlFL", TEMzPayload.INT48_FLOAT_PAIR)
|
@TEMzPayload("FlFL", TEMzPayload.INT48_FLOAT_PAIR)
|
||||||
val fluidFills: HashMap<BlockAddress, Float>
|
val fluidFills: HashMap<BlockAddress, Float>
|
||||||
|
|
||||||
|
// Actually stores the wiring data; used by renderers //
|
||||||
|
|
||||||
@TEMzPayload("CtYP", TEMzPayload.INT48_INT_PAIR)
|
@TEMzPayload("CtYP", TEMzPayload.INT48_INT_PAIR)
|
||||||
val conduitTypes: HashMap<BlockAddress, Int> // 1 bit = 1 conduit (pipe/wire) type
|
val conduitTypes: HashMap<BlockAddress, Int> // 1 bit = 1 conduit (pipe/wire) type
|
||||||
@TEMzPayload("CfL", TEMzPayload.INT48_FLOAT_PAIR)
|
@TEMzPayload("CfL", TEMzPayload.INT48_FLOAT_PAIR)
|
||||||
@@ -83,6 +86,8 @@ open class GameWorld {
|
|||||||
val conduitFills1: HashMap<BlockAddress, Float> // size of gas packet on the block
|
val conduitFills1: HashMap<BlockAddress, Float> // size of gas packet on the block
|
||||||
get() = conduitFills[1]
|
get() = conduitFills[1]
|
||||||
|
|
||||||
|
// Built from the above data; used by hypothetical updater //
|
||||||
|
|
||||||
private val wiringNodes = SortedArrayList<WiringNode>()
|
private val wiringNodes = SortedArrayList<WiringNode>()
|
||||||
|
|
||||||
//public World physWorld = new World( new Vec2(0, -Terrarum.game.gravitationalAccel) );
|
//public World physWorld = new World( new Vec2(0, -Terrarum.game.gravitationalAccel) );
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
internal var showSelection = true
|
internal var showSelection = true
|
||||||
val blockPointingCursor = object : ActorWithBody(Actor.RenderOrder.OVERLAY) {
|
val blockPointingCursor = object : ActorWithBody(Actor.RenderOrder.OVERLAY) {
|
||||||
|
|
||||||
override var referenceID: ActorID? = 1048575 // custom refID
|
override var referenceID: ActorID = 1048575 // custom refID
|
||||||
override val hitbox = Hitbox(0.0, 0.0, 16.0, 16.0)
|
override val hitbox = Hitbox(0.0, 0.0, 16.0, 16.0)
|
||||||
|
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
private var _testMarkerDrawCalls = 0L
|
private var _testMarkerDrawCalls = 0L
|
||||||
|
|
||||||
private fun generateNewBlockMarkerVisible(x: Int, y: Int) = object : ActorWithBody(Actor.RenderOrder.OVERLAY) {
|
private fun generateNewBlockMarkerVisible(x: Int, y: Int) = object : ActorWithBody(Actor.RenderOrder.OVERLAY) {
|
||||||
override var referenceID: ActorID? = blockPosToRefID(x, y) // custom refID
|
override var referenceID: ActorID = blockPosToRefID(x, y) // custom refID
|
||||||
override val hitbox = Hitbox(x * 16.0, y * 16.0, 16.0, 16.0)
|
override val hitbox = Hitbox(x * 16.0, y * 16.0, 16.0, 16.0)
|
||||||
|
|
||||||
override fun drawBody(batch: SpriteBatch) {
|
override fun drawBody(batch: SpriteBatch) {
|
||||||
|
|||||||
@@ -747,8 +747,8 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
if (actor.referenceID == theRealGamer.referenceID || actor.referenceID == 0x51621D) // do not delete this magic
|
if (actor.referenceID == theRealGamer.referenceID || actor.referenceID == 0x51621D) // do not delete this magic
|
||||||
throw RuntimeException("Attempted to remove player.")
|
throw RuntimeException("Attempted to remove player.")
|
||||||
val indexToDelete = actorContainerActive.binarySearch(actor.referenceID!!)
|
val indexToDelete = actorContainerActive.searchForIndex(actor.referenceID!!) { it.referenceID!! }
|
||||||
if (indexToDelete >= 0) {
|
if (indexToDelete != null) {
|
||||||
printdbg(this, "Removing actor $actor")
|
printdbg(this, "Removing actor $actor")
|
||||||
printStackTrace()
|
printStackTrace()
|
||||||
|
|
||||||
@@ -783,6 +783,28 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ArrayList<*>.binarySearch(actor: Actor) = this.binarySearch(actor.referenceID!!)
|
||||||
|
|
||||||
|
private fun ArrayList<*>.binarySearch(ID: Int): Int {
|
||||||
|
// code from collections/Collections.kt
|
||||||
|
var low = 0
|
||||||
|
var high = this.size - 1
|
||||||
|
|
||||||
|
while (low <= high) {
|
||||||
|
val mid = (low + high).ushr(1) // safe from overflows
|
||||||
|
|
||||||
|
val midVal = get(mid)!!
|
||||||
|
|
||||||
|
if (ID > midVal.hashCode())
|
||||||
|
low = mid + 1
|
||||||
|
else if (ID < midVal.hashCode())
|
||||||
|
high = mid - 1
|
||||||
|
else
|
||||||
|
return mid // key found
|
||||||
|
}
|
||||||
|
return -(low + 1) // key not found
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for duplicates, append actor and sort the list
|
* Check for duplicates, append actor and sort the list
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -39,9 +39,58 @@ class SortedArrayList<T: Comparable<T>>(initialSize: Int = 10) {
|
|||||||
|
|
||||||
fun removeAt(index: Int) = arrayList.removeAt(index)
|
fun removeAt(index: Int) = arrayList.removeAt(index)
|
||||||
fun remove(element: T) = arrayList.remove(element)
|
fun remove(element: T) = arrayList.remove(element)
|
||||||
fun removeLast() = arrayList.removeAt(arrayList.size)
|
fun removeLast() = arrayList.removeAt(arrayList.size - 1)
|
||||||
|
|
||||||
operator fun get(index: Int) = arrayList[index]
|
operator fun get(index: Int) = arrayList[index]
|
||||||
|
fun getOrNull(index: Int?) = if (index == null) null else get(index)
|
||||||
|
/**
|
||||||
|
* Searches for the element. Null if the element was not found
|
||||||
|
*/
|
||||||
|
fun contains(element: T): Boolean {
|
||||||
|
// code from collections/Collections.kt
|
||||||
|
var low = 0
|
||||||
|
var high = this.size - 1
|
||||||
|
|
||||||
|
while (low <= high) {
|
||||||
|
val mid = (low + high).ushr(1) // safe from overflows
|
||||||
|
|
||||||
|
val midVal = get(mid)
|
||||||
|
|
||||||
|
if (element > midVal)
|
||||||
|
low = mid + 1
|
||||||
|
else if (element < midVal)
|
||||||
|
high = mid - 1
|
||||||
|
else
|
||||||
|
return true // key found
|
||||||
|
}
|
||||||
|
return false // key not found
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Searches the element using given predicate instead of the element itself. Returns index in the array where desired
|
||||||
|
* element is stored.
|
||||||
|
* (e.g. search the Actor by its ID rather than the actor instance) */
|
||||||
|
fun <R: Comparable<R>> searchForIndex(key: R, predicate: (T) -> R): Int? {
|
||||||
|
var low = 0
|
||||||
|
var high = this.size - 1
|
||||||
|
|
||||||
|
while (low <= high) {
|
||||||
|
val mid = (low + high).ushr(1) // safe from overflows
|
||||||
|
|
||||||
|
val midVal = predicate(get(mid))
|
||||||
|
|
||||||
|
if (key > midVal)
|
||||||
|
low = mid + 1
|
||||||
|
else if (key < midVal)
|
||||||
|
high = mid - 1
|
||||||
|
else
|
||||||
|
return mid // key found
|
||||||
|
}
|
||||||
|
return null // key not found
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Searches the element using given predicate instead of the element itself. Returns the element desired.
|
||||||
|
* (e.g. search the Actor by its ID rather than the actor instance) */
|
||||||
|
fun <R: Comparable<R>> searchFor(key: R, predicate: (T) -> R): T? = getOrNull(searchForIndex(key, predicate))
|
||||||
|
|
||||||
fun iterator() = arrayList.iterator()
|
fun iterator() = arrayList.iterator()
|
||||||
fun forEach(action: (T) -> Unit) = arrayList.forEach(action)
|
fun forEach(action: (T) -> Unit) = arrayList.forEach(action)
|
||||||
|
|||||||
Reference in New Issue
Block a user