Skip to content

Commit

Permalink
Fixed issues with floating points and async database writing
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasDoubleU committed May 19, 2017
1 parent 34e0898 commit 2b80578
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import com.doubleu.kotlintrader.data.OrtWaren
import com.doubleu.kotlintrader.data.Schiffe
import com.doubleu.kotlintrader.data.Storage
import com.doubleu.kotlintrader.database.Entity
import com.doubleu.kotlintrader.extensions.limitDecimals
import com.doubleu.kotlintrader.extensions.random
import com.doubleu.kotlintrader.model.Schiff
import com.doubleu.kotlintrader.util.FxDialogs
import javafx.scene.control.Alert
import javafx.scene.control.ButtonType
import javafx.scene.control.Dialog
import javafx.scene.control.ProgressIndicator
import tornadofx.*
import java.math.BigDecimal
import java.util.concurrent.ThreadLocalRandom
Expand All @@ -24,7 +25,7 @@ class MasterController : Controller() {
with(it) {
val verbrauchAbs = menge.toDouble() * verbrauch
val prodAbs = menge.toDouble() * (produktion + 1)
menge = BigDecimal((menge.toDouble() + prodAbs - verbrauchAbs).limitDecimals(2))
menge = BigDecimal((menge.toDouble() + prodAbs - verbrauchAbs).toInt())
preis = BigDecimal(random(ware.basispreis / 2, ware.basispreis * 2))
}
}
Expand Down Expand Up @@ -53,14 +54,20 @@ class MasterController : Controller() {
* Resets all Entities that are currently loaded
*/
fun resetGame() {
val info = Alert(Alert.AlertType.INFORMATION, "Setze Werte auf ihren Standard zurueck")
info.show()
Storage.all().forEach {
it.asSequence()
.filter { it is Entity<out Entity<*>> }
.forEach { (it as Entity<out Entity<*>>).reset() }
val infoDialog = Dialog<Any>()
infoDialog.dialogPane.content = ProgressIndicator()
infoDialog.contentText = "Setze Werte auf ihren Standard zurueck..."
infoDialog.show()
runAsync {
Storage.all().forEach {
it.asSequence()
.filter { it is Entity<out Entity<*>> }
.forEach { (it as Entity<out Entity<*>>).reset() }
}
} ui {
infoDialog.dialogPane.buttonTypes.addAll(ButtonType.CANCEL)
infoDialog.hide()
FxDialogs.showInformation("Die Werte wurden auf ihren Standard zurueckgesetzt")
}
info.hide()
FxDialogs.showInformation("Die Werte wurden auf ihren Standard zurueckgesetzt")
}
}
9 changes: 8 additions & 1 deletion src/main/kotlin/com/doubleu/kotlintrader/data/Storage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,13 @@ sealed class Storage<T : Entity<T>>(val supplier: () -> List<T>) {

override fun call() {
loading.set(true)
tasks.add(this)
// TODO Sometimes this throws weird IOOBs
try {
tasks.add(this)
} catch(e: Exception) {
System.err.println("${e::class.simpleName}: " +
"That weird error on Task adding happened again..")
}
items.clear()
_items.addAll(func.invoke())
// Retrieve the items eagerly
Expand All @@ -129,6 +135,7 @@ sealed class Storage<T : Entity<T>>(val supplier: () -> List<T>) {
} finally {
loading.set(false)
try {
// TODO Sometimes this throws weird IIOBs
tasks.remove(this)
} catch (e: Exception) {
System.err.println("${e::class.simpleName}: " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,14 @@ object Database {
* Executes the given [sql] as a statement on the database
*/
fun execute(sql: String): Boolean {
if (!connected.get() || connection?.isClosed ?: true) {
System.err.println("Ignoring SQL: $sql - no database connection")
return false
}
return connection?.let {
val statement = it.createStatement()
statement.closeOnCompletion()
return statement.execute(sql)
} ?: throw RuntimeException("No database connection")
} ?: return false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ abstract class Entity<T>(open val id: Long,
* Returns a [Delegate][PropertyDelegate] to the given [property].
*/
protected fun <V : Any> delegate(property: KProperty<V>, default: V): PropertyDelegate<T, V> {
defaultsMap.put(property, default)
defaultsMap.putIfAbsent(property, default)
val delegate = PropertyDelegate(this, property)
delegateMap[property] = delegate
return delegate
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.doubleu.kotlintrader.delegates

import com.doubleu.kotlintrader.database.Entity
import com.doubleu.kotlintrader.util.FxDialogs
import javafx.beans.property.Property
import javafx.beans.property.SimpleObjectProperty
import tornadofx.*
Expand All @@ -23,14 +22,18 @@ abstract class DatabaseDelegate<X> {
}

override fun set(newValue: X) {
task {
process(newValue)
} success {
super.set(newValue)
} fail {
FxDialogs.showException("Failed to write $newValue in $clazz", it)
super.set(newValue)
}
process(newValue)
super.set(newValue)
// Async has to be smarter than that.
// Let's keep it synchronized till we get there
// task {
// process(newValue)
// } success {
// super.set(newValue)
// } fail {
// FxDialogs.showException("Failed to write $newValue in $clazz", it)
// super.set(newValue)
// }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.doubleu.kotlintrader.delegates

import com.doubleu.kotlintrader.database.Database
import com.doubleu.kotlintrader.database.Entity
import com.doubleu.kotlintrader.extensions.limitDecimals
import kotlin.reflect.KProperty

/**
Expand All @@ -19,5 +20,11 @@ class PropertyDelegate<T, V>(val entity: Entity<T>, val field: KProperty<V>) : D
return dbValue
}

override fun process(value: V) = Database.setProperty(entity, field, value)
override fun process(value: V) {
when (value) {
is Double -> Database.setProperty(entity, field, value.toInt())
is Float -> Database.setProperty(entity, field, value.toInt())
else -> Database.setProperty(entity, field, value)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ fun <T> ObservableValue<T>.onChangeWithOld(op: (T, T) -> Unit) = apply { addList
private val nf = NumberFormat.getInstance(Locale.ENGLISH).apply { isGroupingUsed = false }

fun Number.limitDecimals(places: Number) = nf.apply {
// TODO not rounding properly
minimumFractionDigits = places.toInt()
maximumFractionDigits = places.toInt()
}.format(this.toDouble()).toDouble()

fun random(from: Number, to: Number) = ThreadLocalRandom.current().nextDouble(from.toDouble(), to.toDouble()).limitDecimals(2)
fun random(from: Number, to: Number) = ThreadLocalRandom.current().nextInt(from.toInt(), to.toInt())
6 changes: 3 additions & 3 deletions src/main/kotlin/com/doubleu/kotlintrader/model/Ort.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ class Ort(override val id: Long) : Entity<Ort>(id) {
var name: String by delegate(this::name, "-1")
val nameProperty = property(this::name)

var kapazitaet: Double by delegate(this::kapazitaet, random(100, 1000))
var kapazitaet: Double by delegate(this::kapazitaet, random(100, 1000).toDouble())
val kapazitaetProperty = property(this::kapazitaet)

var x: Int by delegate(this::x, random(1, 2000).toInt())
var x: Int by delegate(this::x, random(1, 2000))
val xProperty = property(this::x)

var y: Int by delegate(this::y, random(1, 2000).toInt())
var y: Int by delegate(this::y, random(1, 2000))
val yProperty = property(this::y)

/**
Expand Down
10 changes: 5 additions & 5 deletions src/main/kotlin/com/doubleu/kotlintrader/model/Ort_has_Ware.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ class Ort_has_Ware(val ware_id: Long, val ort_id: Long) : RefEntity<Ort_has_Ware
val ortProperty = property(this::ort)
val ortName = ort.name

var kapazitaet: Int by delegate(this::kapazitaet, random(100, 1000).toInt())
var kapazitaet: Int by delegate(this::kapazitaet, random(100, 1000))
val kapazitaetProperty = property(this::kapazitaet)

var menge: BigDecimal by delegate(this::menge, BigDecimal(random(99, random(100, 1000)).toInt()))
var menge: BigDecimal by delegate(this::menge, BigDecimal(random(99, random(100, 1000))))
val mengeProperty = property(this::menge)

var preis: BigDecimal by delegate(this::preis,
BigDecimal(random(ware.basispreis / 3, ware.basispreis * 3).limitDecimals(2)))
BigDecimal(random(ware.basispreis / 3, ware.basispreis * 3)))
val preisProperty = property(this::preis)

var produktion: Double by delegate(this::produktion, random(0, 1).limitDecimals(2))
var produktion: Double by delegate(this::produktion, random(0, 1).toDouble())
val produktionProperty = property(this::produktion)

var verbrauch: Double by delegate(this::verbrauch, random(0, 1).limitDecimals(2))
var verbrauch: Double by delegate(this::verbrauch, random(0, 1).toDouble())
val verbrauchProperty = property(this::verbrauch)

override fun model(property: ObjectProperty<Ort_has_Ware?>) = Model(property)
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/com/doubleu/kotlintrader/model/Schiff.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Schiff(override val id: Long) : Entity<Schiff>(id) {
var tonnage: Int by delegate(this::tonnage, 1000)
val tonnageProperty = property(this::tonnage)

var wert: Double by delegate(this::wert, random(100, 10000))
var wert: Double by delegate(this::wert, random(100, 10000).toDouble())
val wertProperty = property(this::wert)

var fahrkosten: Float by delegate(this::fahrkosten, random(1, 10).toFloat())
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/com/doubleu/kotlintrader/model/Ware.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Ware(override val id: Long) : Entity<Ware>(id) {
var name: String by delegate(this::name, "-1")
val nameProperty = property(this::name)

var basispreis: Double by delegate(this::basispreis, random(10, 200).limitDecimals(2))
var basispreis: Double by delegate(this::basispreis, random(10, 200).toDouble())
val basispreisDouble = property(this::basispreis)

/**
Expand Down

0 comments on commit 2b80578

Please sign in to comment.