Update actions signatures to avoid unnecessary nulls

This commit is contained in:
Alexander Nozik 2023-05-25 09:51:27 +03:00
parent b7be570271
commit 25d7fe0a8e
4 changed files with 23 additions and 15 deletions

View File

@ -25,9 +25,9 @@ private suspend fun <D : Device, T> DevicePropertySpec<D, T>.readMeta(device: D)
private suspend fun <D : Device, I, O> DeviceActionSpec<D, I, O>.executeWithMeta(
device: D,
item: Meta?,
item: Meta,
): Meta? {
val arg = item?.let { inputConverter.metaToObject(item) }
val arg: I = inputConverter.metaToObject(item) ?: error("Failed to convert $item with $inputConverter")
val res = execute(device, arg)
return res?.let { outputConverter.objectToMeta(res) }
}
@ -146,7 +146,7 @@ public abstract class DeviceBase<D : Device>(
override suspend fun execute(actionName: String, argument: Meta?): Meta? {
val spec = actions[actionName] ?: error("Action with name $actionName not found")
return spec.executeWithMeta(self, argument)
return spec.executeWithMeta(self, argument ?: Meta.EMPTY)
}
}

View File

@ -66,7 +66,7 @@ public interface DeviceActionSpec<in D : Device, I, O> {
/**
* Execute action on a device
*/
public suspend fun execute(device: D, input: I?): O?
public suspend fun execute(device: D, input: I): O
}
/**
@ -137,5 +137,8 @@ public suspend fun <D : Device> D.invalidate(propertySpec: DevicePropertySpec<D,
/**
* Execute the action with name according to [actionSpec]
*/
public suspend fun <I, O, D : Device> D.execute(actionSpec: DeviceActionSpec<D, I, O>, input: I? = null): O? =
public suspend fun <I, O, D : Device> D.execute(actionSpec: DeviceActionSpec<D, I, O>, input: I): O =
actionSpec.execute(this, input)
public suspend fun <O, D : Device> D.execute(actionSpec: DeviceActionSpec<D, Unit, O>): O =
actionSpec.execute(this, Unit)

View File

@ -12,6 +12,13 @@ import kotlin.reflect.KMutableProperty1
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty1
public object UnitMetaConverter: MetaConverter<Unit>{
override fun metaToObject(meta: Meta): Unit = Unit
override fun objectToMeta(obj: Unit): Meta = Meta.EMPTY
}
public val MetaConverter.Companion.unit: MetaConverter<Unit> get() = UnitMetaConverter
@OptIn(InternalDeviceAPI::class)
public abstract class DeviceSpec<D : Device> {
@ -165,7 +172,7 @@ public abstract class DeviceSpec<D : Device> {
outputConverter: MetaConverter<O>,
descriptorBuilder: ActionDescriptor.() -> Unit = {},
name: String? = null,
execute: suspend D.(I?) -> O?,
execute: suspend D.(I) -> O,
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DeviceActionSpec<D, I, O>>> =
PropertyDelegateProvider { _: DeviceSpec<D>, property ->
val actionName = name ?: property.name
@ -175,7 +182,7 @@ public abstract class DeviceSpec<D : Device> {
override val inputConverter: MetaConverter<I> = inputConverter
override val outputConverter: MetaConverter<O> = outputConverter
override suspend fun execute(device: D, input: I?): O? = withContext(device.coroutineContext) {
override suspend fun execute(device: D, input: I): O = withContext(device.coroutineContext) {
device.execute(input)
}
}
@ -191,7 +198,7 @@ public abstract class DeviceSpec<D : Device> {
public fun metaAction(
descriptorBuilder: ActionDescriptor.() -> Unit = {},
name: String? = null,
execute: suspend D.(Meta?) -> Meta?,
execute: suspend D.(Meta) -> Meta,
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DeviceActionSpec<D, Meta, Meta>>> =
action(
MetaConverter.Companion.meta,
@ -209,15 +216,14 @@ public abstract class DeviceSpec<D : Device> {
descriptorBuilder: ActionDescriptor.() -> Unit = {},
name: String? = null,
execute: suspend D.() -> Unit,
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DeviceActionSpec<D, Meta, Meta>>> =
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DeviceActionSpec<D, Unit, Unit>>> =
action(
MetaConverter.Companion.meta,
MetaConverter.Companion.meta,
MetaConverter.Companion.unit,
MetaConverter.Companion.unit,
descriptorBuilder,
name
) {
execute()
null
}
}

View File

@ -68,11 +68,10 @@ class DemoDevice(context: Context, meta: Meta) : DeviceBySpec<IDemoDevice>(Compa
}
val resetScale by action(MetaConverter.meta, MetaConverter.meta) {
val resetScale by unitAction {
write(timeScale, 5000.0)
write(sinScale, 1.0)
write(cosScale, 1.0)
null
}
override suspend fun IDemoDevice.onOpen() {