mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
fixed a long bug where item would be used twice but discounted by only one on single click
This commit is contained in:
@@ -205,9 +205,9 @@ public class AppLoader implements ApplicationListener {
|
||||
|
||||
|
||||
try { processor = GetCpuName.getModelName(); }
|
||||
catch (IOException e1) { processor = "Unknown"; }
|
||||
catch (IOException e1) { processor = "Unknown CPU"; }
|
||||
try { processorVendor = GetCpuName.getCPUID(); }
|
||||
catch (IOException e2) { processorVendor = "Unknown"; }
|
||||
catch (IOException e2) { processorVendor = "Unknown CPU"; }
|
||||
|
||||
|
||||
ShaderProgram.pedantic = false;
|
||||
|
||||
@@ -126,6 +126,9 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
||||
|
||||
/**
|
||||
* Wire version of terrainChanged() event
|
||||
*
|
||||
* @param old previous settings of conduits in bit set format.
|
||||
* @param new current settings of conduits in bit set format.
|
||||
*/
|
||||
open fun queueWireChangedEvent(old: Int, new: Int, position: Long) {
|
||||
val (x, y) = LandUtil.resolveBlockAddr(world, position)
|
||||
|
||||
@@ -6,24 +6,25 @@ package net.torvald.terrarum.blockproperties
|
||||
object Wire {
|
||||
|
||||
/* A mapping for World's conduitTypes bits */
|
||||
/* Must be aligned with the sprite sheet */
|
||||
const val BIT_NONE = 0
|
||||
const val BIT_SIGNAL_RED = 1
|
||||
const val BIT_UTILITY_PROTOTYPE = 2 // logic gates/PCLs/Diodes/Caps/etc.
|
||||
const val BIT_POWER_LOW = 4
|
||||
const val BIT_POWER_HIGHT = 8
|
||||
const val BIT_PARALLEL_8B = 16 // uses bit-to-mantissa encoding
|
||||
const val BIT_PARALLEL_16B = 32 // uses bit-to-mantissa encoding. 16 bit half duplex OR 8 bit full duplex
|
||||
const val BIT_ETHERNET = 64 // the actual datagramme should be represented by another means than the ConduitFills
|
||||
const val BIT_THICKNET = 16 // the actual datagramme should be represented by another means than the ConduitFills
|
||||
const val BIT_PARALLEL_8B = 32 // uses bit-to-mantissa encoding
|
||||
const val BIT_PARALLEL_16B = 64 // uses bit-to-mantissa encoding. 16 bit half duplex OR 8 bit full duplex
|
||||
|
||||
/* 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
|
||||
|
||||
fun bitToConduitFillID(bit: Int) = when(bit) {
|
||||
BIT_SIGNAL_RED -> FILL_ID_SIGNAL_RED
|
||||
BIT_UTILITY_PROTOTYPE -> FILL_ID_UTILITY_PROTOTYPE
|
||||
else -> null
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
/**
|
||||
@@ -35,8 +36,8 @@ object Wire {
|
||||
* s eeeeeeee bbbbbbbb cccccccc xxxxxxx
|
||||
* s: sign (ignored)
|
||||
* e: binary32 exponent (non-zero and non-255)
|
||||
* b: upper byte
|
||||
* c: lower byte (zero for Byte representation)
|
||||
* b: upper octet
|
||||
* c: lower octet (zero for Byte representation)
|
||||
* x: not used, all zero
|
||||
* ```
|
||||
*
|
||||
|
||||
@@ -6,16 +6,12 @@ import com.badlogic.gdx.InputAdapter
|
||||
import com.badlogic.gdx.controllers.Controllers
|
||||
import net.torvald.terrarum.AppLoader
|
||||
import net.torvald.terrarum.AppLoader.printdbg
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.controller.TerrarumController
|
||||
import net.torvald.terrarum.floorInt
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.gameworld.fmod
|
||||
import net.torvald.terrarum.itemproperties.GameItem
|
||||
import net.torvald.terrarum.itemproperties.ItemCodex
|
||||
import net.torvald.terrarum.modulebasegame.Ingame
|
||||
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
||||
import net.torvald.terrarum.worlddrawer.FeaturesDrawer
|
||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||
|
||||
/**
|
||||
@@ -57,22 +53,16 @@ class IngameController(val ingame: Ingame) : InputAdapter() {
|
||||
///////////////////
|
||||
|
||||
// Use item: assuming the player has only one effective grip (EquipPosition.HAND_GRIP)
|
||||
// don't separate Player from this! Physics will break, esp. airborne manoeuvre
|
||||
if (ingame.canPlayerControl) {
|
||||
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mouseprimary")) ||
|
||||
Gdx.input.isButtonPressed(AppLoader.getConfigInt("mousesecondary"))) {
|
||||
// fire world click events; the event is defined as Ingame's (or any others') WorldClick event
|
||||
if (ingame.uiContainer.map { if ((it.isOpening || it.isOpened) && it.mouseUp) 1 else 0 }.sum() == 0) { // no UI on the mouse, right?
|
||||
|
||||
val player = (Terrarum.ingame!! as Ingame).actorNowPlaying
|
||||
if (player == null) return
|
||||
|
||||
val itemOnGrip = player.inventory.itemEquipped[GameItem.EquipPosition.HAND_GRIP]
|
||||
|
||||
itemOnGrip?.let {
|
||||
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mouseprimary"))) {
|
||||
player.consumePrimary(ItemCodex[it]!!)
|
||||
}
|
||||
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mousesecondary"))) {
|
||||
player.consumeSecondary(ItemCodex[it]!!)
|
||||
}
|
||||
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mouseprimary"))) {
|
||||
ingame.worldPrimaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
||||
}
|
||||
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mousesecondary"))) {
|
||||
ingame.worldSecondaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,21 +182,6 @@ class IngameController(val ingame: Ingame) : InputAdapter() {
|
||||
}
|
||||
|
||||
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||
// don't separate Player from this! Physics will break, esp. airborne manoeuvre
|
||||
if (ingame.canPlayerControl) {
|
||||
// fire world click events; the event is defined as Ingame's (or any others') WorldClick event
|
||||
if (ingame.uiContainer.map { if ((it.isOpening || it.isOpened) && it.mouseUp) 1 else 0 }.sum() == 0) { // no UI on the mouse, right?
|
||||
|
||||
if (button == AppLoader.getConfigInt("mouseprimary")) {
|
||||
ingame.worldPrimaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
||||
}
|
||||
if (button == AppLoader.getConfigInt("mousesecondary")) {
|
||||
ingame.worldSecondaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ingame.uiContainer.forEach { it.touchDown(screenX, screenY, pointer, button) }
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import net.torvald.terrarum.blockproperties.Fluid
|
||||
import net.torvald.terrarum.modulebasegame.gameworld.WorldSimulator
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.serialise.ReadLayerDataZip
|
||||
import net.torvald.terrarum.toInt
|
||||
import net.torvald.util.SortedArrayList
|
||||
import org.dyn4j.geometry.Vector2
|
||||
import kotlin.math.absoluteValue
|
||||
@@ -75,20 +74,16 @@ open class GameWorld {
|
||||
@TEMzPayload("FlFL", TEMzPayload.INT48_FLOAT_PAIR)
|
||||
val fluidFills: HashMap<BlockAddress, Float>
|
||||
|
||||
// Actually stores the wiring data; used by renderers //
|
||||
/**
|
||||
* Single block can have multiple conduits, different types of conduits are stored separately.
|
||||
*/
|
||||
@TEMzPayload("WiNt", TEMzPayload.EXTERNAL_JSON)
|
||||
private val wirings: HashMap<BlockAddress, SortedArrayList<WiringNode>>
|
||||
|
||||
@TEMzPayload("CtYP", TEMzPayload.INT48_INT_PAIR)
|
||||
val conduitTypes: HashMap<BlockAddress, Int> // 1 bit = 1 conduit (pipe/wire) type
|
||||
@TEMzPayload("CfL", TEMzPayload.INT48_FLOAT_PAIR)
|
||||
val conduitFills: Array<HashMap<BlockAddress, Float>>
|
||||
val conduitFills0: HashMap<BlockAddress, Float> // size of liquid packet on the block
|
||||
get() = conduitFills[0]
|
||||
val conduitFills1: HashMap<BlockAddress, Float> // size of gas packet on the block
|
||||
get() = conduitFills[1]
|
||||
|
||||
// Built from the above data; used by hypothetical updater //
|
||||
|
||||
private val wiringNodes = SortedArrayList<WiringNode>()
|
||||
/**
|
||||
* Used by the renderer. When wirings are updated, `wirings` and this properties must be synchronised.
|
||||
*/
|
||||
private val wiringBlocks: HashMap<BlockAddress, Int>
|
||||
|
||||
//public World physWorld = new World( new Vec2(0, -Terrarum.game.gravitationalAccel) );
|
||||
//physics
|
||||
@@ -119,13 +114,13 @@ open class GameWorld {
|
||||
layerTerrainLowBits = PairedMapLayer(width, height)
|
||||
layerWallLowBits = PairedMapLayer(width, height)
|
||||
|
||||
wallDamages = HashMap<BlockAddress, Float>()
|
||||
terrainDamages = HashMap<BlockAddress, Float>()
|
||||
fluidTypes = HashMap<BlockAddress, FluidType>()
|
||||
fluidFills = HashMap<BlockAddress, Float>()
|
||||
wallDamages = HashMap()
|
||||
terrainDamages = HashMap()
|
||||
fluidTypes = HashMap()
|
||||
fluidFills = HashMap()
|
||||
|
||||
conduitTypes = HashMap<BlockAddress, Int>()
|
||||
conduitFills = Array(16) { HashMap<BlockAddress, Float>() }
|
||||
wiringBlocks = HashMap()
|
||||
wirings = HashMap()
|
||||
|
||||
// temperature layer: 2x2 is one cell
|
||||
//layerThermal = MapLayerHalfFloat(width, height, averageTemperature)
|
||||
@@ -153,8 +148,8 @@ open class GameWorld {
|
||||
fluidTypes = layerData.fluidTypes
|
||||
fluidFills = layerData.fluidFills
|
||||
|
||||
conduitTypes = HashMap<BlockAddress, Int>()
|
||||
conduitFills = Array(16) { HashMap<BlockAddress, Float>() }
|
||||
wiringBlocks = HashMap()
|
||||
wirings = HashMap()
|
||||
|
||||
spawnX = layerData.spawnX
|
||||
spawnY = layerData.spawnY
|
||||
@@ -215,8 +210,8 @@ open class GameWorld {
|
||||
terrain * PairedMapLayer.RANGE + terrainDamage
|
||||
}
|
||||
|
||||
fun getWires(x: Int, y: Int): Int {
|
||||
return conduitTypes.getOrDefault(LandUtil.getBlockAddr(this, x, y), 0)
|
||||
fun getWiringBlocks(x: Int, y: Int): Int {
|
||||
return wiringBlocks.getOrDefault(LandUtil.getBlockAddr(this, x, y), 0)
|
||||
}
|
||||
|
||||
fun getWallLowBits(x: Int, y: Int): Int? {
|
||||
@@ -296,25 +291,31 @@ open class GameWorld {
|
||||
Terrarum.ingame?.queueWireChangedEvent(oldWire, tile.toUint(), LandUtil.getBlockAddr(this, x, y))
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Overrides entire bits with given value. DO NOT USE THIS if you don't know what this means, you'll want to use setWire().
|
||||
* Besides, this function won't fire WireChangedEvent
|
||||
*/
|
||||
fun setWires(x: Int, y: Int, wireBits: Int) {
|
||||
val (x, y) = coerceXY(x, y)
|
||||
conduitTypes[LandUtil.getBlockAddr(this, x, y)] = wireBits
|
||||
fun getAllConduitsFrom(x: Int, y: Int): SortedArrayList<WiringNode>? {
|
||||
return wirings.get(LandUtil.getBlockAddr(this, x, y))
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets single bit for given tile. YOU'LL WANT TO USE THIS instead of setWires()
|
||||
* @param selectedWire wire-bit to modify, must be power of two
|
||||
* @param conduitTypeBit defined in net.torvald.terrarum.blockproperties.Wire, always power-of-two
|
||||
*/
|
||||
fun setWire(x: Int, y: Int, selectedWire: Int, bitToSet: Boolean) {
|
||||
val oldWireBits = getWires(x, y)
|
||||
val oldStatus = getWires(x, y) or selectedWire != 0
|
||||
if (oldStatus != bitToSet) {
|
||||
setWires(x, y, (oldWireBits and selectedWire.inv()) or (selectedWire * oldStatus.toInt()))
|
||||
Terrarum.ingame?.queueWireChangedEvent(selectedWire * oldStatus.toInt(), selectedWire * bitToSet.toInt(), LandUtil.getBlockAddr(this, x, y))
|
||||
fun getConduitByTypeFrom(x: Int, y: Int, conduitTypeBit: Int): WiringNode? {
|
||||
val conduits = getAllConduitsFrom(x, y)
|
||||
return conduits?.searchFor(conduitTypeBit) { it.typeBitMask }
|
||||
}
|
||||
|
||||
fun addNewConduitTo(x: Int, y: Int, node: WiringNode) {
|
||||
val blockAddr = LandUtil.getBlockAddr(this, x, y)
|
||||
|
||||
// check for existing type of conduit
|
||||
// if there's no duplicate...
|
||||
if (getWiringBlocks(x, y) and node.typeBitMask == 0) {
|
||||
// store as-is
|
||||
wirings.getOrPut(blockAddr) { SortedArrayList() }.add(node)
|
||||
// synchronise wiringBlocks
|
||||
wiringBlocks[blockAddr] = (wiringBlocks[blockAddr] ?: 0) or node.typeBitMask
|
||||
}
|
||||
else {
|
||||
TODO("need overwriting policy for existing conduit node")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,7 +327,7 @@ open class GameWorld {
|
||||
return getTileFromWall(x, y)
|
||||
}
|
||||
else if (mode == WIRE) {
|
||||
return getWires(x, y)
|
||||
return getWiringBlocks(x, y)
|
||||
}
|
||||
else
|
||||
throw IllegalArgumentException("illegal mode input: " + mode.toString())
|
||||
@@ -487,7 +488,7 @@ open class GameWorld {
|
||||
override fun toString() = "Fluid type: ${type.value}, amount: $amount"
|
||||
}
|
||||
|
||||
private data class WiringNode(
|
||||
data class WiringNode(
|
||||
val position: BlockAddress,
|
||||
/** One defined in WireCodex, always power of two */
|
||||
val typeBitMask: Int,
|
||||
@@ -540,6 +541,9 @@ inline class FluidType(val value: Int) {
|
||||
*/
|
||||
annotation class TEMzPayload(val payloadName: String, val arg: Int) {
|
||||
companion object {
|
||||
const val EXTERNAL_JAVAPROPERTIES = -3
|
||||
const val EXTERNAL_CSV = -2
|
||||
const val EXTERNAL_JSON = -1
|
||||
const val EIGHT_MSB = 0
|
||||
const val FOUR_LSB = 1
|
||||
const val INT48_FLOAT_PAIR = 2
|
||||
|
||||
@@ -94,7 +94,7 @@ class EntryPoint : ModuleEntryPoint() {
|
||||
this.inventoryCategory == Category.WALL &&
|
||||
this.dynamicID - ItemCodex.ITEM_WALLS.start == ingame.world.getTileFromWall(Terrarum.mouseTileX, Terrarum.mouseTileY) ||
|
||||
this.inventoryCategory == Category.WIRE &&
|
||||
1.shl(this.dynamicID - ItemCodex.ITEM_WIRES.start) and (ingame.world.getWires(Terrarum.mouseTileX, Terrarum.mouseTileY) ?: 0) != 0
|
||||
1.shl(this.dynamicID - ItemCodex.ITEM_WIRES.start) and (ingame.world.getWiringBlocks(Terrarum.mouseTileX, Terrarum.mouseTileY) ?: 0) != 0
|
||||
)
|
||||
return false
|
||||
|
||||
|
||||
@@ -394,7 +394,9 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
|
||||
override fun worldPrimaryClickStart(delta: Float) {
|
||||
val itemOnGrip = actorNowPlaying?.inventory?.itemEquipped?.get(GameItem.EquipPosition.HAND_GRIP)
|
||||
ItemCodex[itemOnGrip]?.startPrimaryUse(delta)
|
||||
val consumptionSuccessful = ItemCodex[itemOnGrip]?.startPrimaryUse(delta) ?: false
|
||||
if (consumptionSuccessful)
|
||||
actorNowPlaying?.inventory?.consumeItem(ItemCodex[itemOnGrip]!!)
|
||||
}
|
||||
|
||||
override fun worldPrimaryClickEnd(delta: Float) {
|
||||
@@ -404,7 +406,9 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
|
||||
override fun worldSecondaryClickStart(delta: Float) {
|
||||
val itemOnGrip = actorNowPlaying?.inventory?.itemEquipped?.get(GameItem.EquipPosition.HAND_GRIP)
|
||||
ItemCodex[itemOnGrip]?.startSecondaryUse(delta)
|
||||
val consumptionSuccessful = ItemCodex[itemOnGrip]?.startSecondaryUse(delta) ?: false
|
||||
if (consumptionSuccessful)
|
||||
actorNowPlaying?.inventory?.consumeItem(ItemCodex[itemOnGrip]!!)
|
||||
}
|
||||
|
||||
override fun worldSecondaryClickEnd(delta: Float) {
|
||||
|
||||
@@ -177,7 +177,9 @@ class ActorInventory(@Transient val actor: Pocketed, var maxCapacity: Int, var c
|
||||
false
|
||||
|
||||
|
||||
fun consumeItem(actor: Actor, item: GameItem) {
|
||||
fun consumeItem(item: GameItem) {
|
||||
val actor = this.actor as Actor
|
||||
|
||||
if (item.stackable && !item.isDynamic) {
|
||||
remove(item, 1)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameactors
|
||||
|
||||
import net.torvald.terrarum.AppLoader
|
||||
import net.torvald.terrarum.gameactors.Actor
|
||||
import net.torvald.terrarum.itemproperties.GameItem
|
||||
import net.torvald.terrarum.itemproperties.ItemCodex
|
||||
import net.torvald.terrarum.itemproperties.ItemID
|
||||
@@ -79,15 +78,4 @@ interface Pocketed {
|
||||
fun hasItem(item: GameItem) = inventory.contains(item.dynamicID)
|
||||
fun hasItem(id: Int) = inventory.contains(id)
|
||||
|
||||
|
||||
fun consumePrimary(item: GameItem) {
|
||||
if (item.startPrimaryUse(AppLoader.UPDATE_RATE.toFloat())) {
|
||||
inventory.consumeItem(this as Actor, item) // consume on successful
|
||||
}
|
||||
}
|
||||
|
||||
fun consumeSecondary(item: GameItem) {
|
||||
if (item.startSecondaryUse(AppLoader.UPDATE_RATE.toFloat()))
|
||||
inventory.consumeItem(this as Actor, item) // consume on successful
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,9 @@ class WirePieceSignalWire(override val originalID: ItemID) : GameItem() {
|
||||
}
|
||||
|
||||
override fun startPrimaryUse(delta: Float): Boolean {
|
||||
return super.startPrimaryUse(delta)
|
||||
println("Wire!")
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun effectWhenEquipped(delta: Float) {
|
||||
|
||||
@@ -263,12 +263,13 @@ internal object BlocksDrawer {
|
||||
* Turns bitmask-with-single-bit-set into its bit index. The LSB is counted as 1, and thus the index starts at one.
|
||||
* @return 0 -> null, 1 -> 0, 2 -> 1, 4 -> 2, 8 -> 3, 16 -> 4, ...
|
||||
*/
|
||||
private fun Int.toBitOrd(): Int? =
|
||||
if (this > 0 && !FastMath.isPowerOfTwo(this)) throw IllegalArgumentException("value must be power of two: $this")
|
||||
else {
|
||||
val k = FastMath.intLog2(this, -1)
|
||||
if (k == -1) null else k
|
||||
}
|
||||
private fun Int.toBitOrd(): Int? {
|
||||
//if (this > 0 && !FastMath.isPowerOfTwo(this)) throw IllegalArgumentException("value must be power of two: $this")
|
||||
//else {
|
||||
val k = FastMath.intLog2(this, -1)
|
||||
return if (k == -1) null else k
|
||||
//}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes to buffer. Actual draw code must be called after this operation.
|
||||
@@ -305,7 +306,7 @@ internal object BlocksDrawer {
|
||||
val thisTile = when (mode) {
|
||||
WALL -> world.getTileFromWall(x, y)
|
||||
TERRAIN -> world.getTileFromTerrain(x, y)
|
||||
WIRE -> world.getWires(x, y).and(wireBit).toBitOrd()
|
||||
WIRE -> world.getWiringBlocks(x, y).and(wireBit).toBitOrd()
|
||||
FLUID -> world.getFluid(x, y).type.abs()
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
|
||||
@@ -66,21 +66,25 @@ class SortedArrayList<T: Comparable<T>>(initialSize: Int = 10) {
|
||||
return false // key not found
|
||||
}
|
||||
|
||||
/** Searches the element using given predicate instead of the element itself. Returns index in the array where desired
|
||||
/** Searches the element using given predicate instead of the element itself. Returns index in the array where desired, null when there is no such element.
|
||||
* 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? {
|
||||
* (e.g. search the Actor by its ID rather than the actor instance)
|
||||
*
|
||||
* @param searchQuery what exactly are we looking for?
|
||||
* @param searchHow and where or how can it be found?
|
||||
*/
|
||||
fun <R: Comparable<R>> searchForIndex(searchQuery: R, searchHow: (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))
|
||||
val midVal = searchHow(get(mid))
|
||||
|
||||
if (key > midVal)
|
||||
if (searchQuery > midVal)
|
||||
low = mid + 1
|
||||
else if (key < midVal)
|
||||
else if (searchQuery < midVal)
|
||||
high = mid - 1
|
||||
else
|
||||
return mid // key found
|
||||
@@ -88,9 +92,13 @@ class SortedArrayList<T: Comparable<T>>(initialSize: Int = 10) {
|
||||
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))
|
||||
/** Searches the element using given predicate instead of the element itself. Returns the element desired, null when there is no such element.
|
||||
* (e.g. search the Actor by its ID rather than the actor instance)
|
||||
*
|
||||
* @param searchQuery what exactly are we looking for?
|
||||
* @param searchHow and where or how can it be found?
|
||||
*/
|
||||
fun <R: Comparable<R>> searchFor(searchQuery: R, searchHow: (T) -> R): T? = getOrNull(searchForIndex(searchQuery, searchHow))
|
||||
|
||||
fun iterator() = arrayList.iterator()
|
||||
fun forEach(action: (T) -> Unit) = arrayList.forEach(action)
|
||||
|
||||
Reference in New Issue
Block a user