
commonMain.dk.cachet.carp.common.application.sampling.BatteryAwareSampling.kt Maven / Gradle / Ivy
package dk.cachet.carp.common.application.sampling
import dk.cachet.carp.common.application.data.DataTypeMetaData
import dk.cachet.carp.common.application.devices.DeviceDescriptor
import kotlinx.serialization.Serializable
import kotlin.reflect.KClass
/**
* A sampling scheme which changes based on how much battery the device has left.
*/
abstract class BatteryAwareSamplingScheme<
TConfig : SamplingConfiguration,
TBuilder : SamplingConfigurationBuilder
>(
dataType: DataTypeMetaData,
/**
* The builder to construct [SamplingConfiguration]s when overriding configurations for different battery levels.
*/
private val builder: () -> TBuilder,
/**
* The default sampling configuration to use when there is plenty of battery left.
*/
private val normal: TConfig,
/**
* The default sampling configuration to use when the battery is low.
*/
private val low: TConfig? = null,
/**
* The default sampling configuration to use when the battery is critically low.
* By default, sampling should be disabled at this point.
*/
private val critical: TConfig? = null
) : DataTypeSamplingScheme>( dataType )
{
private val configurationKlass: KClass = normal::class
override fun createSamplingConfigurationBuilder(): BatteryAwareSamplingConfigurationBuilder =
BatteryAwareSamplingConfigurationBuilder( builder, normal, low, critical )
override fun isValid( configuration: SamplingConfiguration ): Boolean
{
if ( configuration !is BatteryAwareSamplingConfiguration<*> ) return false
// Verify whether battery-level-specific configurations are the expected type.
val correctTypes =
configurationKlass.isInstance( configuration.normal ) && // Normal configuration cannot be null.
( configuration.low == null || configurationKlass.isInstance( configuration.low ) ) &&
( configuration.critical == null || configurationKlass.isInstance( configuration.critical ) )
if ( !correctTypes ) return false
// Verify whether constraints for the battery-level-specific configurations are met.
@Suppress( "UNCHECKED_CAST" )
return isValidBatteryLevelConfiguration( configuration.normal as TConfig ) &&
( configuration.low == null || isValidBatteryLevelConfiguration( configuration.low as TConfig ) ) &&
( configuration.critical == null || isValidBatteryLevelConfiguration( configuration.critical as TConfig ) )
}
/**
* Determines whether the [configuration] assigned to a specific battery level in a [BatteryAwareSamplingConfiguration]
* is valid for the constraints defined in this sampling scheme.
*/
abstract fun isValidBatteryLevelConfiguration( configuration: TConfig ): Boolean
}
/**
* A sampling configuration which changes based on how much battery the device has left.
*/
@Serializable
data class BatteryAwareSamplingConfiguration(
/**
* The sampling configuration to use when there is plenty of battery left.
*/
val normal: TConfig,
/**
* The sampling configuration to use when the battery is low.
*/
val low: TConfig? = null,
/**
* The sampling configuration to use when the battery is critically low.
*/
val critical: TConfig? = null
) : SamplingConfiguration
/**
* A helper class to configure and construct immutable [BatteryAwareSamplingConfiguration] classes
* as part of setting up a [DeviceDescriptor].
*/
class BatteryAwareSamplingConfigurationBuilder<
TConfig : SamplingConfiguration,
TBuilder : SamplingConfigurationBuilder
>(
private val createBuilder: () -> TBuilder,
private var normal: TConfig,
private var low: TConfig?,
private var critical: TConfig?
) : SamplingConfigurationBuilder>
{
/**
* The sampling configuration to use when there is plenty of battery left.
*/
fun batteryNormal( builder: TBuilder.() -> Unit ) =
createConfiguration( builder ).let { normal = it }
/**
* The sampling configuration to use when the battery is low.
*/
fun batteryLow( builder: TBuilder.() -> Unit ) =
createConfiguration( builder ).let { low = it }
/**
* The sampling configuration to use when the battery is critically low.
*/
fun batteryCritical( builder: TBuilder.() -> Unit ) =
createConfiguration( builder ).let { critical = it }
/**
* Apply the same sampling configuration for all battery levels: normal, low, and critical.
*/
fun allBatteryLevels( builder: TBuilder.() -> Unit ) =
createConfiguration( builder ).let {
normal = it
low = it
critical = it
}
private fun createConfiguration( builder: TBuilder.() -> Unit ) =
createBuilder().apply( builder ).build()
override fun build(): BatteryAwareSamplingConfiguration =
BatteryAwareSamplingConfiguration( normal, low, critical )
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy