Add read-after-write for DeviceBase property writers
This commit is contained in:
parent
a51510606f
commit
a337daee93
@ -87,7 +87,7 @@ public abstract class DeviceBase<D : Device>(
|
|||||||
/**
|
/**
|
||||||
* Update logical property state and notify listeners
|
* 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]) {
|
if (value != logicalState[propertyName]) {
|
||||||
stateLock.withLock {
|
stateLock.withLock {
|
||||||
logicalState[propertyName] = value
|
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) {
|
protected suspend fun <T> propertyChanged(spec: DevicePropertySpec<D, T>, value: T) {
|
||||||
updateLogical(spec.name, spec.converter.objectToMeta(value))
|
propertyChanged(spec.name, spec.converter.objectToMeta(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,7 +112,7 @@ public abstract class DeviceBase<D : Device>(
|
|||||||
override suspend fun readProperty(propertyName: String): Meta {
|
override suspend fun readProperty(propertyName: String): Meta {
|
||||||
val spec = properties[propertyName] ?: error("Property with name $propertyName not found")
|
val spec = properties[propertyName] ?: error("Property with name $propertyName not found")
|
||||||
val meta = spec.readMeta(self) ?: error("Failed to read property $propertyName")
|
val meta = spec.readMeta(self) ?: error("Failed to read property $propertyName")
|
||||||
updateLogical(propertyName, meta)
|
propertyChanged(propertyName, meta)
|
||||||
return meta
|
return meta
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ public abstract class DeviceBase<D : Device>(
|
|||||||
public suspend fun readPropertyOrNull(propertyName: String): Meta? {
|
public suspend fun readPropertyOrNull(propertyName: String): Meta? {
|
||||||
val spec = properties[propertyName] ?: return null
|
val spec = properties[propertyName] ?: return null
|
||||||
val meta = spec.readMeta(self) ?: return null
|
val meta = spec.readMeta(self) ?: return null
|
||||||
updateLogical(propertyName, meta)
|
propertyChanged(propertyName, meta)
|
||||||
return meta
|
return meta
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,13 +137,18 @@ public abstract class DeviceBase<D : Device>(
|
|||||||
override suspend fun writeProperty(propertyName: String, value: Meta): Unit {
|
override suspend fun writeProperty(propertyName: String, value: Meta): Unit {
|
||||||
when (val property = properties[propertyName]) {
|
when (val property = properties[propertyName]) {
|
||||||
null -> {
|
null -> {
|
||||||
//If there is a physical property with a given name, invalidate logical property and write physical one
|
//If there are no physical properties with given name, write a logical one.
|
||||||
updateLogical(propertyName, value)
|
propertyChanged(propertyName, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
is WritableDevicePropertySpec -> {
|
is WritableDevicePropertySpec -> {
|
||||||
|
//if there is a writeable property with a given name, invalidate logical and write physical
|
||||||
invalidate(propertyName)
|
invalidate(propertyName)
|
||||||
property.writeMeta(self, value)
|
property.writeMeta(self, value)
|
||||||
|
// perform read after writing if the writer did not set the value
|
||||||
|
if (logicalState[propertyName] == null) {
|
||||||
|
readPropertyOrNull(propertyName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
|
@ -22,7 +22,7 @@ public val MetaConverter.Companion.unit: MetaConverter<Unit> get() = UnitMetaCon
|
|||||||
|
|
||||||
@OptIn(InternalDeviceAPI::class)
|
@OptIn(InternalDeviceAPI::class)
|
||||||
public abstract class DeviceSpec<D : Device> {
|
public abstract class DeviceSpec<D : Device> {
|
||||||
//initializing meta property for everyone
|
//initializing the metadata property for everyone
|
||||||
private val _properties = hashMapOf<String, DevicePropertySpec<D, *>>(
|
private val _properties = hashMapOf<String, DevicePropertySpec<D, *>>(
|
||||||
DeviceMetaPropertySpec.name to DeviceMetaPropertySpec
|
DeviceMetaPropertySpec.name to DeviceMetaPropertySpec
|
||||||
)
|
)
|
||||||
|
@ -49,16 +49,16 @@ class MksPdr900Device(context: Context, meta: Meta) : DeviceBySpec<MksPdr900Devi
|
|||||||
if (powerOnValue) {
|
if (powerOnValue) {
|
||||||
val ans = talk("FP!ON")
|
val ans = talk("FP!ON")
|
||||||
if (ans == "ON") {
|
if (ans == "ON") {
|
||||||
updateLogical(powerOn, true)
|
propertyChanged(powerOn, true)
|
||||||
} else {
|
} else {
|
||||||
updateLogical(error, "Failed to set power state")
|
propertyChanged(error, "Failed to set power state")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val ans = talk("FP!OFF")
|
val ans = talk("FP!OFF")
|
||||||
if (ans == "OFF") {
|
if (ans == "OFF") {
|
||||||
updateLogical(powerOn, false)
|
propertyChanged(powerOn, false)
|
||||||
} else {
|
} 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)
|
invalidate(error)
|
||||||
return if (answer.isNullOrEmpty()) {
|
return if (answer.isNullOrEmpty()) {
|
||||||
// updateState(PortSensor.CONNECTED_STATE, false)
|
// updateState(PortSensor.CONNECTED_STATE, false)
|
||||||
updateLogical(error, "No connection")
|
propertyChanged(error, "No connection")
|
||||||
null
|
null
|
||||||
} else {
|
} else {
|
||||||
val res = answer.toDouble()
|
val res = answer.toDouble()
|
||||||
if (res <= 0) {
|
if (res <= 0) {
|
||||||
updateLogical(powerOn, false)
|
propertyChanged(powerOn, false)
|
||||||
updateLogical(error, "No power")
|
propertyChanged(error, "No power")
|
||||||
null
|
null
|
||||||
} else {
|
} else {
|
||||||
res
|
res
|
||||||
|
@ -172,7 +172,7 @@ class PiMotionMasterDevice(
|
|||||||
//Update port
|
//Update port
|
||||||
//address = portSpec.node
|
//address = portSpec.node
|
||||||
port = portFactory(portSpec, context)
|
port = portFactory(portSpec, context)
|
||||||
updateLogical(connected, true)
|
propertyChanged(connected, true)
|
||||||
// connector.open()
|
// connector.open()
|
||||||
//Initialize axes
|
//Initialize axes
|
||||||
val idn = read(identity)
|
val idn = read(identity)
|
||||||
@ -196,7 +196,7 @@ class PiMotionMasterDevice(
|
|||||||
it.close()
|
it.close()
|
||||||
}
|
}
|
||||||
port = null
|
port = null
|
||||||
updateLogical(connected, false)
|
propertyChanged(connected, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user