Skip to content

Commit 8d08678

Browse files
committed
Add direct property cache write ability
1 parent 4c7acc6 commit 8d08678

File tree

4 files changed

+42
-12
lines changed
  • controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor
  • controls-core/src/commonMain/kotlin/space/kscience/controls
  • controls-magix/src/commonMain/kotlin/space/kscience/controls/client

4 files changed

+42
-12
lines changed

controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/DeviceGroup.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import space.kscience.controls.api.LifecycleState.*
77
import space.kscience.controls.manager.DeviceManager
88
import space.kscience.controls.manager.install
99
import space.kscience.controls.spec.DevicePropertySpec
10+
import space.kscience.controls.spec.InternalDeviceAPI
1011
import space.kscience.controls.time.clock
1112
import space.kscience.dataforge.context.*
1213
import space.kscience.dataforge.meta.Laminate
@@ -151,9 +152,10 @@ public open class DeviceGroup(
151152
properties[propertyName.parseAsName()]?.valueAsMeta
152153
?: error("Property with name $propertyName not found")
153154

154-
override fun getProperty(propertyName: String): Meta? = properties[propertyName.parseAsName()]?.valueAsMeta
155+
override fun getCachedProperty(propertyName: String): Meta? = properties[propertyName.parseAsName()]?.valueAsMeta
155156

156-
override suspend fun invalidate(propertyName: String) {
157+
@InternalDeviceAPI
158+
override fun setCachedProperty(propertyName: String, value: Meta?) {
157159
//does nothing for this implementation
158160
}
159161

@@ -199,9 +201,7 @@ public open class DeviceGroup(
199201

200202
override val clock: Clock = context.clock
201203

202-
public companion object {
203-
204-
}
204+
public companion object
205205
}
206206

207207
public fun <T> DeviceGroup.registerAsProperty(propertySpec: DevicePropertySpec<*, T>, state: DeviceState<T>) {

controls-core/src/commonMain/kotlin/space/kscience/controls/api/Device.kt

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import kotlinx.coroutines.Job
55
import kotlinx.coroutines.cancel
66
import kotlinx.coroutines.flow.*
77
import space.kscience.controls.api.Device.Companion.DEVICE_TARGET
8+
import space.kscience.controls.spec.InternalDeviceAPI
89
import space.kscience.dataforge.context.ContextAware
910
import space.kscience.dataforge.context.info
1011
import space.kscience.dataforge.context.logger
@@ -100,21 +101,31 @@ public interface CachingDevice : Device {
100101
/**
101102
* Immediately (without waiting) get the cached (logical) state of property or return null if it is invalid
102103
*/
103-
public fun getProperty(propertyName: String): Meta?
104+
public fun getCachedProperty(propertyName: String): Meta?
105+
106+
/**
107+
* Immediately (without waiting) set the cached (logical) state of a property to a specific value
108+
* or remove cached value (if [value] is null).
109+
*
110+
* This method is not thread-safe and should be used with care. Preferably only for internal APIs
111+
*/
112+
@InternalDeviceAPI
113+
public fun setCachedProperty(propertyName: String, value: Meta?)
104114

105115
/**
106116
* Invalidate property (set logical state to invalid).
107117
*
108118
* This message is suspended to provide lock-free local property changes (they require coroutine context).
109119
*/
110-
public suspend fun invalidate(propertyName: String)
120+
@OptIn(InternalDeviceAPI::class)
121+
public suspend fun invalidate(propertyName: String): Unit = setCachedProperty(propertyName, null)
111122
}
112123

113124
/**
114125
* Get the logical state of property or suspend to read the physical value.
115126
*/
116127
public suspend fun Device.getOrReadProperty(propertyName: String): Meta = if (this is CachingDevice) {
117-
getProperty(propertyName) ?: readProperty(propertyName)
128+
getCachedProperty(propertyName) ?: readProperty(propertyName)
118129
} else {
119130
readProperty(propertyName)
120131
}
@@ -125,7 +136,7 @@ public suspend fun Device.getOrReadProperty(propertyName: String): Meta = if (th
125136
*/
126137
public fun CachingDevice.getAllProperties(): Meta = Meta {
127138
for (descriptor in propertyDescriptors) {
128-
set(descriptor.name.parseAsName(), getProperty(descriptor.name))
139+
set(descriptor.name.parseAsName(), getCachedProperty(descriptor.name))
129140
}
130141
}
131142

controls-core/src/commonMain/kotlin/space/kscience/controls/spec/DeviceBase.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,16 @@ public abstract class DeviceBase<D : Device>(
151151
return meta
152152
}
153153

154-
override fun getProperty(propertyName: String): Meta? = logicalState[propertyName]
154+
override fun getCachedProperty(propertyName: String): Meta? = logicalState[propertyName]
155+
156+
@InternalDeviceAPI
157+
override fun setCachedProperty(propertyName: String, value: Meta?) {
158+
if (value == null) {
159+
logicalState.remove(propertyName)
160+
} else {
161+
logicalState[propertyName] = value
162+
}
163+
}
155164

156165
override suspend fun invalidate(propertyName: String) {
157166
stateLock.withLock {

controls-magix/src/commonMain/kotlin/space/kscience/controls/client/DeviceClient.kt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import kotlinx.coroutines.sync.withLock
1111
import space.kscience.controls.api.*
1212
import space.kscience.controls.manager.DeviceManager
1313
import space.kscience.controls.spec.DevicePropertySpec
14+
import space.kscience.controls.spec.InternalDeviceAPI
1415
import space.kscience.controls.spec.name
1516
import space.kscience.controls.time.clock
1617
import space.kscience.dataforge.context.Context
@@ -76,7 +77,16 @@ public class DeviceClient internal constructor(
7677
}.value
7778
}
7879

79-
override fun getProperty(propertyName: String): Meta? = propertyCache[propertyName]
80+
override fun getCachedProperty(propertyName: String): Meta? = propertyCache[propertyName]
81+
82+
@InternalDeviceAPI
83+
override fun setCachedProperty(propertyName: String, value: Meta?) {
84+
if (value == null) {
85+
propertyCache.remove(propertyName)
86+
} else {
87+
propertyCache[propertyName] = value
88+
}
89+
}
8090

8191
override suspend fun invalidate(propertyName: String) {
8292
mutex.withLock {
@@ -138,7 +148,7 @@ public suspend fun MagixEndpoint.remoteDevice(
138148
.map { it.second }
139149
.filter {
140150
it.sourceDevice == null || it.sourceDevice == deviceName
141-
}.shareIn(context, SharingStarted.Lazily,10)
151+
}.shareIn(context, SharingStarted.Lazily, 10)
142152

143153
val deferredDescriptorMessage = CompletableDeferred<DescriptionMessage>()
144154

0 commit comments

Comments
 (0)