[WIP] working on constructor
This commit is contained in:
parent
a66e411848
commit
673a7c89a6
@ -1,35 +0,0 @@
|
|||||||
package space.kscience.controls.constructor
|
|
||||||
|
|
||||||
import space.kscience.controls.api.Device
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A binding that is used to describe device functionality
|
|
||||||
*/
|
|
||||||
public sealed interface Binding
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A binding that exposes device property as read-only state
|
|
||||||
*/
|
|
||||||
public class PropertyBinding<T>(
|
|
||||||
public val device: Device,
|
|
||||||
public val propertyName: String,
|
|
||||||
public val state: DeviceState<T>,
|
|
||||||
) : Binding
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A binding for independent state like a timer
|
|
||||||
*/
|
|
||||||
public class StateBinding<T>(
|
|
||||||
public val state: DeviceState<T>
|
|
||||||
) : Binding
|
|
||||||
|
|
||||||
public class ActionBinding(
|
|
||||||
public val reads: Collection<DeviceState<*>>,
|
|
||||||
public val writes: Collection<DeviceState<*>>
|
|
||||||
): Binding
|
|
||||||
|
|
||||||
|
|
||||||
public interface BindingsContainer{
|
|
||||||
public val bindings: List<Binding>
|
|
||||||
public fun registerBinding(binding: Binding)
|
|
||||||
}
|
|
@ -5,12 +5,10 @@ import kotlinx.coroutines.flow.launchIn
|
|||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import space.kscience.controls.api.Device
|
import space.kscience.controls.api.Device
|
||||||
import space.kscience.controls.api.PropertyDescriptor
|
import space.kscience.controls.api.PropertyDescriptor
|
||||||
import space.kscience.controls.manager.ClockManager
|
|
||||||
import space.kscience.controls.spec.DevicePropertySpec
|
import space.kscience.controls.spec.DevicePropertySpec
|
||||||
import space.kscience.controls.spec.MutableDevicePropertySpec
|
import space.kscience.controls.spec.MutableDevicePropertySpec
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.Factory
|
import space.kscience.dataforge.context.Factory
|
||||||
import space.kscience.dataforge.context.request
|
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.meta.MetaConverter
|
import space.kscience.dataforge.meta.MetaConverter
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
@ -26,25 +24,19 @@ import kotlin.time.Duration
|
|||||||
public abstract class DeviceConstructor(
|
public abstract class DeviceConstructor(
|
||||||
context: Context,
|
context: Context,
|
||||||
meta: Meta = Meta.EMPTY,
|
meta: Meta = Meta.EMPTY,
|
||||||
) : DeviceGroup(context, meta), BindingsContainer {
|
) : DeviceGroup(context, meta), StateContainer {
|
||||||
private val _bindings: MutableList<Binding> = mutableListOf()
|
private val _stateDescriptors: MutableList<StateDescriptor> = mutableListOf()
|
||||||
override val bindings: List<Binding> get() = _bindings
|
override val stateDescriptors: List<StateDescriptor> get() = _stateDescriptors
|
||||||
|
|
||||||
override fun registerBinding(binding: Binding) {
|
override fun registerState(stateDescriptor: StateDescriptor) {
|
||||||
_bindings.add(binding)
|
_stateDescriptors.add(stateDescriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun registerProperty(descriptor: PropertyDescriptor, state: DeviceState<*>) {
|
override fun registerProperty(descriptor: PropertyDescriptor, state: DeviceState<*>) {
|
||||||
super.registerProperty(descriptor, state)
|
super.registerProperty(descriptor, state)
|
||||||
registerBinding(PropertyBinding(this, descriptor.name, state))
|
registerState(PropertyStateDescriptor(this, descriptor.name, state))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create and register a timer. Timer is not counted as a device property.
|
|
||||||
*/
|
|
||||||
public fun timer(tick: Duration): TimerState = TimerState(context.request(ClockManager), tick)
|
|
||||||
.also { registerBinding(StateBinding(it)) }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bind an action to a [DeviceState]. [onChange] block is performed on each state change
|
* Bind an action to a [DeviceState]. [onChange] block is performed on each state change
|
||||||
*
|
*
|
||||||
@ -55,7 +47,7 @@ public abstract class DeviceConstructor(
|
|||||||
reads: Collection<DeviceState<*>>,
|
reads: Collection<DeviceState<*>>,
|
||||||
onChange: suspend (T) -> Unit,
|
onChange: suspend (T) -> Unit,
|
||||||
): Job = valueFlow.onEach(onChange).launchIn(this@DeviceConstructor).also {
|
): Job = valueFlow.onEach(onChange).launchIn(this@DeviceConstructor).also {
|
||||||
registerBinding(ActionBinding(setOf(this, *reads.toTypedArray()), setOf(*writes)))
|
registerState(ConnectionStateDescriptor(setOf(this, *reads.toTypedArray()), setOf(*writes)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,4 +163,4 @@ public fun <T, D : Device> DeviceConstructor.deviceProperty(
|
|||||||
property: MutableDevicePropertySpec<D, T>,
|
property: MutableDevicePropertySpec<D, T>,
|
||||||
initialValue: T,
|
initialValue: T,
|
||||||
): PropertyDelegateProvider<DeviceConstructor, ReadOnlyProperty<DeviceConstructor, MutableDeviceState<T>>> =
|
): PropertyDelegateProvider<DeviceConstructor, ReadOnlyProperty<DeviceConstructor, MutableDeviceState<T>>> =
|
||||||
property(device.mutablePropertyAsState(property, initialValue))
|
property(device.mutablePropertyAsState(property, initialValue))
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package space.kscience.controls.constructor
|
package space.kscience.controls.constructor
|
||||||
|
|
||||||
public abstract class DeviceModel : BindingsContainer {
|
import space.kscience.dataforge.context.Context
|
||||||
|
|
||||||
private val _bindings: MutableList<Binding> = mutableListOf()
|
public abstract class DeviceModel(override val context: Context) : StateContainer {
|
||||||
|
|
||||||
override val bindings: List<Binding> get() = _bindings
|
private val _stateDescriptors: MutableList<StateDescriptor> = mutableListOf()
|
||||||
|
|
||||||
override fun registerBinding(binding: Binding) {
|
override val stateDescriptors: List<StateDescriptor> get() = _stateDescriptors
|
||||||
_bindings.add(binding)
|
|
||||||
|
override fun registerState(stateDescriptor: StateDescriptor) {
|
||||||
|
_stateDescriptors.add(stateDescriptor)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
package space.kscience.controls.constructor
|
||||||
|
|
||||||
|
import space.kscience.controls.api.Device
|
||||||
|
import space.kscience.controls.manager.ClockManager
|
||||||
|
import space.kscience.dataforge.context.ContextAware
|
||||||
|
import space.kscience.dataforge.context.request
|
||||||
|
import space.kscience.dataforge.meta.MetaConverter
|
||||||
|
import kotlin.time.Duration
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A binding that is used to describe device functionality
|
||||||
|
*/
|
||||||
|
public sealed interface StateDescriptor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A binding that exposes device property as read-only state
|
||||||
|
*/
|
||||||
|
public class PropertyStateDescriptor<T>(
|
||||||
|
public val device: Device,
|
||||||
|
public val propertyName: String,
|
||||||
|
public val state: DeviceState<T>,
|
||||||
|
) : StateDescriptor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A binding for independent state like a timer
|
||||||
|
*/
|
||||||
|
public class StateBinding<T>(
|
||||||
|
public val state: DeviceState<T>,
|
||||||
|
) : StateDescriptor
|
||||||
|
|
||||||
|
public class ConnectionStateDescriptor(
|
||||||
|
public val reads: Collection<DeviceState<*>>,
|
||||||
|
public val writes: Collection<DeviceState<*>>,
|
||||||
|
) : StateDescriptor
|
||||||
|
|
||||||
|
|
||||||
|
public interface StateContainer : ContextAware {
|
||||||
|
public val stateDescriptors: List<StateDescriptor>
|
||||||
|
public fun registerState(stateDescriptor: StateDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a [state] in this container. The state is not registered as a device property if [this] is a [DeviceConstructor]
|
||||||
|
*/
|
||||||
|
public fun <T, D : DeviceState<T>> StateContainer.state(state: D): D {
|
||||||
|
registerState(StateBinding(state))
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a register a [MutableDeviceState] with a given [converter]
|
||||||
|
*/
|
||||||
|
public fun <T> StateContainer.state(converter: MetaConverter<T>, initialValue: T): MutableDeviceState<T> = state(
|
||||||
|
DeviceState.internal(converter, initialValue)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a register a mutable [Double] state
|
||||||
|
*/
|
||||||
|
public fun StateContainer.doubleState(initialValue: Double): MutableDeviceState<Double> = state(
|
||||||
|
MetaConverter.double, initialValue
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a register a mutable [String] state
|
||||||
|
*/
|
||||||
|
public fun StateContainer.stringState(initialValue: String): MutableDeviceState<String> = state(
|
||||||
|
MetaConverter.string, initialValue
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and register a timer state.
|
||||||
|
*/
|
||||||
|
public fun StateContainer.timer(tick: Duration): TimerState = state(TimerState(context.request(ClockManager), tick))
|
@ -51,9 +51,9 @@ public class DoubleInRangeState(
|
|||||||
/**
|
/**
|
||||||
* Create and register a [DoubleInRangeState]
|
* Create and register a [DoubleInRangeState]
|
||||||
*/
|
*/
|
||||||
public fun BindingsContainer.doubleInRangeState(
|
public fun StateContainer.doubleInRangeState(
|
||||||
initialValue: Double,
|
initialValue: Double,
|
||||||
range: ClosedFloatingPointRange<Double>,
|
range: ClosedFloatingPointRange<Double>,
|
||||||
): DoubleInRangeState = DoubleInRangeState(initialValue, range).also {
|
): DoubleInRangeState = DoubleInRangeState(initialValue, range).also {
|
||||||
registerBinding(StateBinding(it))
|
registerState(StateBinding(it))
|
||||||
}
|
}
|
@ -12,7 +12,7 @@ kscience {
|
|||||||
useKtor()
|
useKtor()
|
||||||
useSerialization()
|
useSerialization()
|
||||||
useContextReceivers()
|
useContextReceivers()
|
||||||
dependencies {
|
commonMain {
|
||||||
api(projects.controlsCore)
|
api(projects.controlsCore)
|
||||||
api(projects.controlsConstructor)
|
api(projects.controlsConstructor)
|
||||||
api(libs.visionforge.plotly)
|
api(libs.visionforge.plotly)
|
||||||
|
Loading…
Reference in New Issue
Block a user