Refactor unit objects

This commit is contained in:
Sad Ellie 2023-09-15 09:51:17 +03:00
parent ef08a31dff
commit 66f1c965d7
9 changed files with 248 additions and 126 deletions

View File

@ -32,6 +32,17 @@ interface AbstractUnit {
val isFavorite: Boolean
val pairId: String?
val counter: Int
fun clone(
id: String = this.id,
basicUnit: BigDecimal = this.basicUnit,
group: UnitGroup = this.group,
displayName: Int = this.displayName,
shortName: Int = this.shortName,
isFavorite: Boolean = this.isFavorite,
pairId: String? = this.pairId,
counter: Int = this.counter,
): AbstractUnit
}
fun Sequence<AbstractUnit>.filterByLev(stringA: String, context: Context): Sequence<AbstractUnit> {

View File

@ -53,4 +53,24 @@ data class FuelBackward(
else -> BigDecimal.ZERO
}
}
override fun clone(
id: String,
basicUnit: BigDecimal,
group: UnitGroup,
displayName: Int,
shortName: Int,
isFavorite: Boolean,
pairId: String?,
counter: Int,
): FuelBackward = copy(
id = id,
basicUnit = basicUnit,
group = group,
displayName = displayName,
shortName = shortName,
isFavorite = isFavorite,
pairId = pairId,
counter = counter,
)
}

View File

@ -52,4 +52,24 @@ data class FuelForward(
else -> BigDecimal.ZERO
}
}
override fun clone(
id: String,
basicUnit: BigDecimal,
group: UnitGroup,
displayName: Int,
shortName: Int,
isFavorite: Boolean,
pairId: String?,
counter: Int,
): FuelForward = copy(
id = id,
basicUnit = basicUnit,
group = group,
displayName = displayName,
shortName = shortName,
isFavorite = isFavorite,
pairId = pairId,
counter = counter,
)
}

View File

@ -43,4 +43,24 @@ data class NormalUnit(
.multiply(value)
.div(unitTo.basicUnit)
}
override fun clone(
id: String,
basicUnit: BigDecimal,
group: UnitGroup,
displayName: Int,
shortName: Int,
isFavorite: Boolean,
pairId: String?,
counter: Int,
): NormalUnit = copy(
id = id,
basicUnit = basicUnit,
group = group,
displayName = displayName,
shortName = shortName,
isFavorite = isFavorite,
pairId = pairId,
counter = counter,
)
}

View File

@ -34,4 +34,24 @@ data class NumberBaseUnit(
fun convert(toBase: NumberBaseUnit, input: String): String {
return input.toBigInteger(basicUnit.intValueExact()).toString(toBase.basicUnit.intValueExact())
}
override fun clone(
id: String,
basicUnit: BigDecimal,
group: UnitGroup,
displayName: Int,
shortName: Int,
isFavorite: Boolean,
pairId: String?,
counter: Int,
): NumberBaseUnit = copy(
id = id,
basicUnit = basicUnit,
group = group,
displayName = displayName,
shortName = shortName,
isFavorite = isFavorite,
pairId = pairId,
counter = counter,
)
}

View File

@ -41,4 +41,24 @@ data class ReverseUnit(
.div(this.basicUnit)
.multiply(value)
}
override fun clone(
id: String,
basicUnit: BigDecimal,
group: UnitGroup,
displayName: Int,
shortName: Int,
isFavorite: Boolean,
pairId: String?,
counter: Int,
): ReverseUnit = copy(
id = id,
basicUnit = basicUnit,
group = group,
displayName = displayName,
shortName = shortName,
isFavorite = isFavorite,
pairId = pairId,
counter = counter,
)
}

View File

@ -0,0 +1,56 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.model.unit
import com.sadellie.unitto.data.model.UnitGroup
import java.math.BigDecimal
data class TemperatureUnit(
override val id: String,
override val basicUnit: BigDecimal,
override val group: UnitGroup,
override val displayName: Int,
override val shortName: Int,
override val isFavorite: Boolean = false,
override val pairId: String? = null,
override val counter: Int = 0,
val customConvert: (unitTo: DefaultUnit, value: BigDecimal) -> BigDecimal
): DefaultUnit {
override fun convert(unitTo: DefaultUnit, value: BigDecimal): BigDecimal = customConvert(unitTo, value)
override fun clone(
id: String,
basicUnit: BigDecimal,
group: UnitGroup,
displayName: Int,
shortName: Int,
isFavorite: Boolean,
pairId: String?,
counter: Int,
): TemperatureUnit = copy(
id = id,
basicUnit = basicUnit,
group = group,
displayName = displayName,
shortName = shortName,
isFavorite = isFavorite,
pairId = pairId,
counter = counter,
)
}

View File

@ -27,10 +27,6 @@ import com.sadellie.unitto.data.database.UnitsEntity
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.UnitsListSorting
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.FuelBackward
import com.sadellie.unitto.data.model.unit.FuelForward
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.model.unit.NumberBaseUnit
import com.sadellie.unitto.data.model.unit.ReverseUnit
import com.sadellie.unitto.data.model.unit.filterByLev
import com.sadellie.unitto.data.units.collections.accelerationCollection
@ -113,40 +109,13 @@ class UnitsRepository @Inject constructor(
.mapLatest { basedList ->
basedList.forEach { based ->
// Have to use a copy so that composable can detect changes
val updatedUnit = when (val foundUnit = getById(based.unitId)) {
is NormalUnit -> foundUnit.copy(
val updatedUnit = getById(based.unitId)
.clone(
isFavorite = based.isFavorite,
counter = based.frequency,
pairId = based.pairedUnitId
)
is NumberBaseUnit -> foundUnit.copy(
isFavorite = based.isFavorite,
counter = based.frequency,
pairId = based.pairedUnitId
)
is ReverseUnit -> foundUnit.copy(
isFavorite = based.isFavorite,
counter = based.frequency,
pairId = based.pairedUnitId
)
is FuelForward -> foundUnit.copy(
isFavorite = based.isFavorite,
counter = based.frequency,
pairId = based.pairedUnitId
)
is FuelBackward -> foundUnit.copy(
isFavorite = based.isFavorite,
counter = based.frequency,
pairId = based.pairedUnitId
)
else -> return@forEach
}
myUnits.update { units ->
units.replace(updatedUnit) { it.id == updatedUnit.id }
}

View File

@ -22,102 +22,88 @@ import com.sadellie.unitto.core.base.MAX_PRECISION
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.DefaultUnit
import com.sadellie.unitto.data.model.unit.TemperatureUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
import java.math.RoundingMode
internal val temperatureCollection: List<AbstractUnit> by lazy {
listOf(Celsius, Fahrenheit, Kelvin)
}
private data object Celsius : DefaultUnit {
override val id: String = MyUnitIDS.celsius
override val basicUnit: BigDecimal = BigDecimal.ONE
override val group: UnitGroup = UnitGroup.TEMPERATURE
override val displayName: Int = R.string.celsius
override val shortName: Int = R.string.celsius_short
override val isFavorite: Boolean = false
override val pairId: String? = null
override val counter: Int = 0
override fun convert(unitTo: DefaultUnit, value: BigDecimal): BigDecimal {
return when (unitTo.id) {
MyUnitIDS.fahrenheit -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.times(BigDecimal.valueOf(1.8))
.plus(BigDecimal(32))
}
MyUnitIDS.kelvin -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.plus(BigDecimal.valueOf(273.15))
}
else -> value
}
}
}
private data object Fahrenheit : DefaultUnit {
override val id: String = MyUnitIDS.fahrenheit
override val basicUnit: BigDecimal = BigDecimal.ONE
override val group: UnitGroup = UnitGroup.TEMPERATURE
override val displayName: Int = R.string.fahrenheit
override val shortName: Int = R.string.fahrenheit_short
override val isFavorite: Boolean = false
override val pairId: String? = null
override val counter: Int = 0
override fun convert(unitTo: DefaultUnit, value: BigDecimal): BigDecimal {
return when (unitTo.id) {
MyUnitIDS.celsius -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal(32))
.times(BigDecimal(5))
.div(BigDecimal(9))
}
MyUnitIDS.kelvin -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal(32))
.times(BigDecimal(5))
.div(BigDecimal(9))
.add(BigDecimal.valueOf(273.15))
}
else -> value
}
}
}
private data object Kelvin : DefaultUnit {
override val id: String = MyUnitIDS.kelvin
override val basicUnit: BigDecimal = BigDecimal.ONE
override val group: UnitGroup = UnitGroup.TEMPERATURE
override val displayName: Int = R.string.kelvin
override val shortName: Int = R.string.kelvin_short
override val isFavorite: Boolean = false
override val pairId: String? = null
override val counter: Int = 0
override fun convert(unitTo: DefaultUnit, value: BigDecimal): BigDecimal {
return when (unitTo.id) {
MyUnitIDS.celsius -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal(273.15))
}
MyUnitIDS.fahrenheit -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal.valueOf(273.15))
.times(BigDecimal.valueOf(1.8))
.plus(BigDecimal(32))
}
else -> value
}
}
listOf(
TemperatureUnit(
id = MyUnitIDS.celsius,
basicUnit = BigDecimal.ONE,
group = UnitGroup.TEMPERATURE,
displayName = R.string.celsius,
shortName = R.string.celsius_short,
customConvert = { unitTo, value ->
when (unitTo.id) {
MyUnitIDS.fahrenheit -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.times(BigDecimal.valueOf(1.8))
.plus(BigDecimal(32))
}
MyUnitIDS.kelvin -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.plus(BigDecimal.valueOf(273.15))
}
else -> value
}
}
),
TemperatureUnit(
id = MyUnitIDS.fahrenheit,
basicUnit = BigDecimal.ONE,
group = UnitGroup.TEMPERATURE,
displayName = R.string.fahrenheit,
shortName = R.string.fahrenheit_short,
customConvert = { unitTo, value ->
when (unitTo.id) {
MyUnitIDS.celsius -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal(32))
.times(BigDecimal(5))
.div(BigDecimal(9))
}
MyUnitIDS.kelvin -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal(32))
.times(BigDecimal(5))
.div(BigDecimal(9))
.add(BigDecimal.valueOf(273.15))
}
else -> value
}
}
),
TemperatureUnit(
id = MyUnitIDS.kelvin,
basicUnit = BigDecimal.ONE,
group = UnitGroup.TEMPERATURE,
displayName = R.string.kelvin,
shortName = R.string.kelvin_short,
customConvert = { unitTo, value ->
when (unitTo.id) {
MyUnitIDS.celsius -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal(273.15))
}
MyUnitIDS.fahrenheit -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal.valueOf(273.15))
.times(BigDecimal.valueOf(1.8))
.plus(BigDecimal(32))
}
else -> value
}
}
),
)
}