Add read-after-write for DeviceBase property writers

This commit is contained in:
Alexander Nozik 2023-09-24 13:21:01 +03:00
parent a51510606f
commit a337daee93
4 changed files with 23 additions and 18 deletions

View File

@ -87,7 +87,7 @@ public abstract class DeviceBase<D : Device>(
/**
* Update logical property state and notify listeners
*/
protected suspend fun updateLogical(propertyName: String, value: Meta?) {
protected suspend fun propertyChanged(propertyName: String, value: Meta?) {
if (value != logicalState[propertyName]) {
stateLock.withLock {
logicalState[propertyName] = value
@ -99,10 +99,10 @@ public abstract class DeviceBase<D : Device>(
}
/**
* Update logical state using given [spec] and its convertor
* Notify the device that a property with [spec] value is changed
*/
public suspend fun <T> updateLogical(spec: DevicePropertySpec<D, T>, value: T) {
updateLogical(spec.name, spec.converter.objectToMeta(value))
protected suspend fun <T> propertyChanged(spec: DevicePropertySpec<D, T>, value: T) {
propertyChanged(spec.name, spec.converter.objectToMeta(value))
}
/**
@ -112,7 +112,7 @@ public abstract class DeviceBase<D : Device>(
override suspend fun readProperty(propertyName: String): Meta {
val spec = properties[propertyName] ?: error("Property with name $propertyName not found")
val meta = spec.readMeta(self) ?: error("Failed to read property $propertyName")
updateLogical(propertyName, meta)
propertyChanged(propertyName, meta)
return meta
}
@ -122,7 +122,7 @@ public abstract class DeviceBase<D : Device>(
public suspend fun readPropertyOrNull(propertyName: String): Meta? {
val spec = properties[propertyName] ?: return null
val meta = spec.readMeta(self) ?: return null
updateLogical(propertyName, meta)
propertyChanged(propertyName, meta)
return meta
}
@ -137,13 +137,18 @@ public abstract class DeviceBase<D : Device>(
override suspend fun writeProperty(propertyName: String, value: Meta): Unit {
when (val property = properties[propertyName]) {
null -> {
//If there is a physical property with a given name, invalidate logical property and write physical one
updateLogical(propertyName, value)
//If there are no physical properties with given name, write a logical one.
propertyChanged(propertyName, value)
}
is WritableDevicePropertySpec -> {
//if there is a writeable property with a given name, invalidate logical and write physical
invalidate(propertyName)
property.writeMeta(self, value)
// perform read after writing if the writer did not set the value
if (logicalState[propertyName] == null) {
readPropertyOrNull(propertyName)
}
}
else -> {

View File

@ -22,7 +22,7 @@ public val MetaConverter.Companion.unit: MetaConverter<Unit> get() = UnitMetaCon
@OptIn(InternalDeviceAPI::class)
public abstract class DeviceSpec<D : Device> {
//initializing meta property for everyone
//initializing the metadata property for everyone
private val _properties = hashMapOf<String, DevicePropertySpec<D, *>>(
DeviceMetaPropertySpec.name to DeviceMetaPropertySpec
)

View File

@ -49,16 +49,16 @@ class MksPdr900Device(context: Context, meta: Meta) : DeviceBySpec<MksPdr900Devi
if (powerOnValue) {
val ans = talk("FP!ON")
if (ans == "ON") {
updateLogical(powerOn, true)
propertyChanged(powerOn, true)
} else {
updateLogical(error, "Failed to set power state")
propertyChanged(error, "Failed to set power state")
}
} else {
val ans = talk("FP!OFF")
if (ans == "OFF") {
updateLogical(powerOn, false)
propertyChanged(powerOn, false)
} else {
updateLogical(error, "Failed to set power state")
propertyChanged(error, "Failed to set power state")
}
}
}
@ -68,13 +68,13 @@ class MksPdr900Device(context: Context, meta: Meta) : DeviceBySpec<MksPdr900Devi
invalidate(error)
return if (answer.isNullOrEmpty()) {
// updateState(PortSensor.CONNECTED_STATE, false)
updateLogical(error, "No connection")
propertyChanged(error, "No connection")
null
} else {
val res = answer.toDouble()
if (res <= 0) {
updateLogical(powerOn, false)
updateLogical(error, "No power")
propertyChanged(powerOn, false)
propertyChanged(error, "No power")
null
} else {
res

View File

@ -172,7 +172,7 @@ class PiMotionMasterDevice(
//Update port
//address = portSpec.node
port = portFactory(portSpec, context)
updateLogical(connected, true)
propertyChanged(connected, true)
// connector.open()
//Initialize axes
val idn = read(identity)
@ -196,7 +196,7 @@ class PiMotionMasterDevice(
it.close()
}
port = null
updateLogical(connected, false)
propertyChanged(connected, false)
}