|
1 | 1 | package io.ably.lib.objects |
2 | 2 |
|
| 3 | +import io.ably.lib.realtime.ChannelState |
3 | 4 | import io.ably.lib.types.Callback |
4 | 5 | import io.ably.lib.types.ProtocolMessage |
5 | 6 | import io.ably.lib.util.Log |
@@ -95,9 +96,9 @@ internal class DefaultLiveObjects(private val channelName: String, internal val |
95 | 96 |
|
96 | 97 | /** |
97 | 98 | * Handles a ProtocolMessage containing proto action as `object` or `object_sync`. |
98 | | - * @spec RTL1 - Processes incoming object messages and object sync messages |
| 99 | + * @spec RTL1 - Processes incoming object messages and object sync messages |
99 | 100 | */ |
100 | | - fun handle(protocolMessage: ProtocolMessage) { |
| 101 | + internal fun handle(protocolMessage: ProtocolMessage) { |
101 | 102 | // RTL15b - Set channel serial for OBJECT messages |
102 | 103 | adapter.setChannelSerial(channelName, protocolMessage) |
103 | 104 |
|
@@ -141,6 +142,40 @@ internal class DefaultLiveObjects(private val channelName: String, internal val |
141 | 142 | } |
142 | 143 | } |
143 | 144 |
|
| 145 | + internal fun handleStateChange(state: ChannelState, hasObjects: Boolean) { |
| 146 | + sequentialScope.launch { |
| 147 | + when (state) { |
| 148 | + ChannelState.attached -> { |
| 149 | + Log.v(tag, "Objects.onAttached() channel=$channelName, hasObjects=$hasObjects") |
| 150 | + |
| 151 | + // RTO4a |
| 152 | + val fromInitializedState = this@DefaultLiveObjects.state == ObjectsState.INITIALIZED |
| 153 | + if (hasObjects || fromInitializedState) { |
| 154 | + // should always start a new sync sequence if we're in the initialized state, no matter the HAS_OBJECTS flag value. |
| 155 | + // this guarantees we emit both "syncing" -> "synced" events in that order. |
| 156 | + objectsManager.startNewSync(null) |
| 157 | + } |
| 158 | + |
| 159 | + // RTO4b |
| 160 | + if (!hasObjects) { |
| 161 | + // if no HAS_OBJECTS flag received on attach, we can end sync sequence immediately and treat it as no objects on a channel. |
| 162 | + // reset the objects pool to its initial state, and emit update events so subscribers to root object get notified about changes. |
| 163 | + objectsPool.resetToInitialPool(true) // RTO4b1, RTO4b2 |
| 164 | + objectsManager.clearSyncObjectsDataPool() // RTO4b3 |
| 165 | + objectsManager.clearBufferedObjectOperations() // RTO4b5 |
| 166 | + // defer the state change event until the next tick if we started a new sequence just now due to being in initialized state. |
| 167 | + // this allows any event listeners to process the start of the new sequence event that was emitted earlier during this event loop. |
| 168 | + objectsManager.endSync(fromInitializedState) // RTO4b4 |
| 169 | + } |
| 170 | + } |
| 171 | + |
| 172 | + else -> { |
| 173 | + // No action needed for other states |
| 174 | + } |
| 175 | + } |
| 176 | + } |
| 177 | + } |
| 178 | + |
144 | 179 | /** |
145 | 180 | * Changes the state and emits events. |
146 | 181 | * |
|
0 commit comments