[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 space.kscience.controls.api.Device
|
||||
import space.kscience.controls.api.PropertyDescriptor
|
||||
import space.kscience.controls.manager.ClockManager
|
||||
import space.kscience.controls.spec.DevicePropertySpec
|
||||
import space.kscience.controls.spec.MutableDevicePropertySpec
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.Factory
|
||||
import space.kscience.dataforge.context.request
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.meta.MetaConverter
|
||||
import space.kscience.dataforge.names.Name
|
||||
@ -26,25 +24,19 @@ import kotlin.time.Duration
|
||||
public abstract class DeviceConstructor(
|
||||
context: Context,
|
||||
meta: Meta = Meta.EMPTY,
|
||||
) : DeviceGroup(context, meta), BindingsContainer {
|
||||
private val _bindings: MutableList<Binding> = mutableListOf()
|
||||
override val bindings: List<Binding> get() = _bindings
|
||||
) : DeviceGroup(context, meta), StateContainer {
|
||||
private val _stateDescriptors: MutableList<StateDescriptor> = mutableListOf()
|
||||
override val stateDescriptors: List<StateDescriptor> get() = _stateDescriptors
|
||||
|
||||
override fun registerBinding(binding: Binding) {
|
||||
_bindings.add(binding)
|
||||
override fun registerState(stateDescriptor: StateDescriptor) {
|
||||
_stateDescriptors.add(stateDescriptor)
|
||||
}
|
||||
|
||||
override fun registerProperty(descriptor: PropertyDescriptor, state: DeviceState<*>) {
|
||||
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
|
||||
*
|
||||
@ -55,7 +47,7 @@ public abstract class DeviceConstructor(
|
||||
reads: Collection<DeviceState<*>>,
|
||||
onChange: suspend (T) -> Unit,
|
||||
): Job = valueFlow.onEach(onChange).launchIn(this@DeviceConstructor).also {
|
||||
registerBinding(ActionBinding(setOf(this, *reads.toTypedArray()), setOf(*writes)))
|
||||
registerState(ConnectionStateDescriptor(setOf(this, *reads.toTypedArray()), setOf(*writes)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,14 @@
|
||||
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) {
|
||||
_bindings.add(binding)
|
||||
override val stateDescriptors: List<StateDescriptor> get() = _stateDescriptors
|
||||
|
||||
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]
|
||||
*/
|
||||
public fun BindingsContainer.doubleInRangeState(
|
||||
public fun StateContainer.doubleInRangeState(
|
||||
initialValue: Double,
|
||||
range: ClosedFloatingPointRange<Double>,
|
||||
): DoubleInRangeState = DoubleInRangeState(initialValue, range).also {
|
||||
registerBinding(StateBinding(it))
|
||||
registerState(StateBinding(it))
|
||||
}
|
@ -12,7 +12,7 @@ kscience {
|
||||
useKtor()
|
||||
useSerialization()
|
||||
useContextReceivers()
|
||||
dependencies {
|
||||
commonMain {
|
||||
api(projects.controlsCore)
|
||||
api(projects.controlsConstructor)
|
||||
api(libs.visionforge.plotly)
|
||||
|
Loading…
Reference in New Issue
Block a user