DeviceSpec
properties no explicitly pass property name to getters and setters
This commit is contained in:
parent
b539c2046a
commit
0c647cff30
@ -8,9 +8,7 @@ import space.kscience.dataforge.meta.Meta
|
|||||||
import space.kscience.dataforge.meta.transformations.MetaConverter
|
import space.kscience.dataforge.meta.transformations.MetaConverter
|
||||||
import kotlin.properties.PropertyDelegateProvider
|
import kotlin.properties.PropertyDelegateProvider
|
||||||
import kotlin.properties.ReadOnlyProperty
|
import kotlin.properties.ReadOnlyProperty
|
||||||
import kotlin.reflect.KMutableProperty1
|
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
import kotlin.reflect.KProperty1
|
|
||||||
|
|
||||||
public object UnitMetaConverter : MetaConverter<Unit> {
|
public object UnitMetaConverter : MetaConverter<Unit> {
|
||||||
override fun metaToObject(meta: Meta): Unit = Unit
|
override fun metaToObject(meta: Meta): Unit = Unit
|
||||||
@ -44,11 +42,11 @@ public abstract class DeviceSpec<D : Device> {
|
|||||||
return deviceProperty
|
return deviceProperty
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline fun <reified T> property(
|
public fun <T> property(
|
||||||
converter: MetaConverter<T>,
|
converter: MetaConverter<T>,
|
||||||
crossinline descriptorBuilder: PropertyDescriptor.() -> Unit = {},
|
descriptorBuilder: PropertyDescriptor.() -> Unit = {},
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
crossinline read: suspend D.(propertyName: String) -> T?,
|
read: suspend D.(propertyName: String) -> T?,
|
||||||
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DevicePropertySpec<D, T>>> =
|
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DevicePropertySpec<D, T>>> =
|
||||||
PropertyDelegateProvider { _: DeviceSpec<D>, property ->
|
PropertyDelegateProvider { _: DeviceSpec<D>, property ->
|
||||||
val propertyName = name ?: property.name
|
val propertyName = name ?: property.name
|
||||||
@ -56,7 +54,8 @@ public abstract class DeviceSpec<D : Device> {
|
|||||||
override val descriptor: PropertyDescriptor = PropertyDescriptor(propertyName).apply(descriptorBuilder)
|
override val descriptor: PropertyDescriptor = PropertyDescriptor(propertyName).apply(descriptorBuilder)
|
||||||
override val converter: MetaConverter<T> = converter
|
override val converter: MetaConverter<T> = converter
|
||||||
|
|
||||||
override suspend fun read(device: D): T? = withContext(device.coroutineContext) { device.read(propertyName) }
|
override suspend fun read(device: D): T? =
|
||||||
|
withContext(device.coroutineContext) { device.read(propertyName) }
|
||||||
}
|
}
|
||||||
registerProperty(deviceProperty)
|
registerProperty(deviceProperty)
|
||||||
ReadOnlyProperty<DeviceSpec<D>, DevicePropertySpec<D, T>> { _, _ ->
|
ReadOnlyProperty<DeviceSpec<D>, DevicePropertySpec<D, T>> { _, _ ->
|
||||||
@ -64,12 +63,12 @@ public abstract class DeviceSpec<D : Device> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline fun <reified T> mutableProperty(
|
public fun <T> mutableProperty(
|
||||||
converter: MetaConverter<T>,
|
converter: MetaConverter<T>,
|
||||||
crossinline descriptorBuilder: PropertyDescriptor.() -> Unit = {},
|
descriptorBuilder: PropertyDescriptor.() -> Unit = {},
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
crossinline read: suspend D.(propertyName: String) -> T?,
|
read: suspend D.(propertyName: String) -> T?,
|
||||||
crossinline write: suspend D.(propertyName: String, value: T) -> Unit,
|
write: suspend D.(propertyName: String, value: T) -> Unit,
|
||||||
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, MutableDevicePropertySpec<D, T>>> =
|
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, MutableDevicePropertySpec<D, T>>> =
|
||||||
PropertyDelegateProvider { _: DeviceSpec<D>, property: KProperty<*> ->
|
PropertyDelegateProvider { _: DeviceSpec<D>, property: KProperty<*> ->
|
||||||
val propertyName = name ?: property.name
|
val propertyName = name ?: property.name
|
||||||
@ -106,7 +105,7 @@ public abstract class DeviceSpec<D : Device> {
|
|||||||
name: String? = null,
|
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>, ReadOnlyProperty<DeviceSpec<D>, DeviceActionSpec<D, I, O>>> =
|
||||||
PropertyDelegateProvider { _: DeviceSpec<D>, property ->
|
PropertyDelegateProvider { _: DeviceSpec<D>, property: KProperty<*> ->
|
||||||
val actionName = name ?: property.name
|
val actionName = name ?: property.name
|
||||||
val deviceAction = object : DeviceActionSpec<D, I, O> {
|
val deviceAction = object : DeviceActionSpec<D, I, O> {
|
||||||
override val descriptor: ActionDescriptor = ActionDescriptor(actionName).apply(descriptorBuilder)
|
override val descriptor: ActionDescriptor = ActionDescriptor(actionName).apply(descriptorBuilder)
|
||||||
@ -124,10 +123,29 @@ public abstract class DeviceSpec<D : Device> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An action that takes no parameters and returns no values
|
||||||
|
*/
|
||||||
|
public fun <D : Device> DeviceSpec<D>.unitAction(
|
||||||
|
descriptorBuilder: ActionDescriptor.() -> Unit = {},
|
||||||
|
name: String? = null,
|
||||||
|
execute: suspend D.() -> Unit,
|
||||||
|
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DeviceActionSpec<D, Unit, Unit>>> =
|
||||||
|
action(
|
||||||
|
MetaConverter.Companion.unit,
|
||||||
|
MetaConverter.Companion.unit,
|
||||||
|
descriptorBuilder,
|
||||||
|
name
|
||||||
|
) {
|
||||||
|
execute()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An action that takes [Meta] and returns [Meta]. No conversions are done
|
* An action that takes [Meta] and returns [Meta]. No conversions are done
|
||||||
*/
|
*/
|
||||||
public fun metaAction(
|
public fun <D : Device> DeviceSpec<D>.metaAction(
|
||||||
descriptorBuilder: ActionDescriptor.() -> Unit = {},
|
descriptorBuilder: ActionDescriptor.() -> Unit = {},
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
execute: suspend D.(Meta) -> Meta,
|
execute: suspend D.(Meta) -> Meta,
|
||||||
@ -141,60 +159,3 @@ public abstract class DeviceSpec<D : Device> {
|
|||||||
execute(it)
|
execute(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* An action that takes no parameters and returns no values
|
|
||||||
*/
|
|
||||||
public fun unitAction(
|
|
||||||
descriptorBuilder: ActionDescriptor.() -> Unit = {},
|
|
||||||
name: String? = null,
|
|
||||||
execute: suspend D.() -> Unit,
|
|
||||||
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DeviceActionSpec<D, Unit, Unit>>> =
|
|
||||||
action(
|
|
||||||
MetaConverter.Companion.unit,
|
|
||||||
MetaConverter.Companion.unit,
|
|
||||||
descriptorBuilder,
|
|
||||||
name
|
|
||||||
) {
|
|
||||||
execute()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public inline fun <reified T, D : Device> DeviceSpec<D>.property(
|
|
||||||
converter: MetaConverter<T>,
|
|
||||||
readOnlyProperty: KProperty1<D, T>,
|
|
||||||
crossinline descriptorBuilder: PropertyDescriptor.() -> Unit = {},
|
|
||||||
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DevicePropertySpec<D, T>>> = property(
|
|
||||||
converter,
|
|
||||||
descriptorBuilder,
|
|
||||||
name = readOnlyProperty.name,
|
|
||||||
read = { readOnlyProperty.get(this) }
|
|
||||||
)
|
|
||||||
|
|
||||||
public inline fun <reified T, D : Device> DeviceSpec<D>.mutableProperty(
|
|
||||||
converter: MetaConverter<T>,
|
|
||||||
readWriteProperty: KMutableProperty1<D, T>,
|
|
||||||
crossinline descriptorBuilder: PropertyDescriptor.() -> Unit = {},
|
|
||||||
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, MutableDevicePropertySpec<D, T>>> =
|
|
||||||
mutableProperty(
|
|
||||||
converter,
|
|
||||||
descriptorBuilder,
|
|
||||||
readWriteProperty.name,
|
|
||||||
read = { _ -> readWriteProperty.get(this) },
|
|
||||||
write = { _, value: T -> readWriteProperty.set(this, value) }
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a mutable logical property (without a corresponding physical state) for a device
|
|
||||||
*/
|
|
||||||
public inline fun <reified T, D : DeviceBase<D>> DeviceSpec<D>.logicalProperty(
|
|
||||||
converter: MetaConverter<T>,
|
|
||||||
crossinline descriptorBuilder: PropertyDescriptor.() -> Unit = {},
|
|
||||||
name: String? = null,
|
|
||||||
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, MutableDevicePropertySpec<D, T>>> =
|
|
||||||
mutableProperty(
|
|
||||||
converter,
|
|
||||||
descriptorBuilder,
|
|
||||||
name,
|
|
||||||
read = { propertyName -> getProperty(propertyName)?.let(converter::metaToObject) },
|
|
||||||
write = { propertyName, value -> writeProperty(propertyName, converter.objectToMeta(value)) }
|
|
||||||
)
|
|
@ -8,6 +8,55 @@ import space.kscience.dataforge.meta.ValueType
|
|||||||
import space.kscience.dataforge.meta.transformations.MetaConverter
|
import space.kscience.dataforge.meta.transformations.MetaConverter
|
||||||
import kotlin.properties.PropertyDelegateProvider
|
import kotlin.properties.PropertyDelegateProvider
|
||||||
import kotlin.properties.ReadOnlyProperty
|
import kotlin.properties.ReadOnlyProperty
|
||||||
|
import kotlin.reflect.KMutableProperty1
|
||||||
|
import kotlin.reflect.KProperty1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A read-only device property that delegates reading to a device [KProperty1]
|
||||||
|
*/
|
||||||
|
public fun <T, D : Device> DeviceSpec<D>.property(
|
||||||
|
converter: MetaConverter<T>,
|
||||||
|
readOnlyProperty: KProperty1<D, T>,
|
||||||
|
descriptorBuilder: PropertyDescriptor.() -> Unit = {},
|
||||||
|
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DevicePropertySpec<D, T>>> = property(
|
||||||
|
converter,
|
||||||
|
descriptorBuilder,
|
||||||
|
name = readOnlyProperty.name,
|
||||||
|
read = { readOnlyProperty.get(this) }
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutable property that delegates reading and writing to a device [KMutableProperty1]
|
||||||
|
*/
|
||||||
|
public fun <T, D : Device> DeviceSpec<D>.mutableProperty(
|
||||||
|
converter: MetaConverter<T>,
|
||||||
|
readWriteProperty: KMutableProperty1<D, T>,
|
||||||
|
descriptorBuilder: PropertyDescriptor.() -> Unit = {},
|
||||||
|
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, MutableDevicePropertySpec<D, T>>> =
|
||||||
|
mutableProperty(
|
||||||
|
converter,
|
||||||
|
descriptorBuilder,
|
||||||
|
readWriteProperty.name,
|
||||||
|
read = { _ -> readWriteProperty.get(this) },
|
||||||
|
write = { _, value: T -> readWriteProperty.set(this, value) }
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a mutable logical property (without a corresponding physical state) for a device
|
||||||
|
*/
|
||||||
|
public fun <T, D : DeviceBase<D>> DeviceSpec<D>.logicalProperty(
|
||||||
|
converter: MetaConverter<T>,
|
||||||
|
descriptorBuilder: PropertyDescriptor.() -> Unit = {},
|
||||||
|
name: String? = null,
|
||||||
|
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, MutableDevicePropertySpec<D, T>>> =
|
||||||
|
mutableProperty(
|
||||||
|
converter,
|
||||||
|
descriptorBuilder,
|
||||||
|
name,
|
||||||
|
read = { propertyName -> getProperty(propertyName)?.let(converter::metaToObject) },
|
||||||
|
write = { propertyName, value -> writeProperty(propertyName, converter.objectToMeta(value)) }
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
//read only delegates
|
//read only delegates
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user