Skip to content

Commit 2ea697c

Browse files
authored
Merge pull request #1223 from ably/feature/liveobjects-kotlin-implementation
[AIT-934] feat(liveobjects): `LiveObjects` implementation to new path-based API (Kotlin)
2 parents 39e8d09 + b8c16e1 commit 2ea697c

25 files changed

Lines changed: 2541 additions & 19 deletions

android/proguard.txt

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,28 @@
11
-keep public class io.ably.lib.transport.WebSocketTransport$Factory {*;}
22
-keep class io.ably.lib.types.** {*;}
3-
-keep class io.ably.lib.objects.*LiveObjectsPlugin {*;}
4-
-keep class io.ably.lib.objects.serialization.*Serializer {*;}
5-
-keep class io.ably.lib.objects.ObjectsJsonSerializer {*;}
3+
4+
# LiveObjects implementations are resolved at runtime via Class.forName(...) +
5+
# getDeclaredConstructor(...).newInstance(...) against hard-coded class-name strings
6+
# (see LiveObjectsPlugin.Factory, ObjectSerializer.Holder, LiveCounter#create and
7+
# LiveMap#create). R8 must not rename or strip these classes or their reflectively
8+
# invoked constructors.
9+
-keep class io.ably.lib.liveobjects.DefaultLiveObjectsPlugin { <init>(...); }
10+
-keep class io.ably.lib.liveobjects.serialization.DefaultObjectsSerializer { <init>(...); }
11+
-keep class io.ably.lib.liveobjects.value.livecounter.DefaultLiveCounter { <init>(...); }
12+
-keep class io.ably.lib.liveobjects.value.livemap.DefaultLiveMap { <init>(...); }
13+
14+
# ObjectJsonSerializer and WireObjectDataJsonSerializer are instantiated reflectively
15+
# by Gson via @JsonAdapter annotations (on ProtocolMessage and WireObjectData
16+
# respectively); keep their no-arg constructors.
17+
-keep class io.ably.lib.liveobjects.serialization.ObjectJsonSerializer { <init>(...); }
18+
-keep class io.ably.lib.liveobjects.serialization.WireObjectDataJsonSerializer { <init>(...); }
19+
20+
# The Wire* object model is (de)serialized to/from JSON by Gson via field-name
21+
# reflection (DefaultObjectsSerializer -> JsonSerialization.gson.fromJson/toJsonTree).
22+
# R8 must not rename or strip these fields or JSON transport silently breaks. Mirrors
23+
# the io.ably.lib.types.** rule above. (The MessagePack path uses explicit string keys
24+
# and is unaffected.)
25+
-keep class io.ably.lib.liveobjects.message.** { *; }
626

727
-keep class org.msgpack.core.** {*;}
828
-keepclasseswithmembers class io.ably.lib.rest.Auth** {*;}

lib/src/main/java/io/ably/lib/liveobjects/message/ObjectsMapEntry.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/**
66
* Represents the value at a given key in a {@code LiveMap} object.
77
*
8-
* <p>Spec: ME1
8+
* <p>Spec: OME1
99
*/
1010
public interface ObjectsMapEntry {
1111

lib/src/main/java/io/ably/lib/liveobjects/value/LiveCounter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*/
2424
public abstract class LiveCounter {
2525

26-
private static final String IMPLEMENTATION_CLASS = "io.ably.lib.liveobjects.value.DefaultLiveCounter";
26+
private static final String IMPLEMENTATION_CLASS = "io.ably.lib.liveobjects.value.livecounter.DefaultLiveCounter";
2727

2828
/**
2929
* Extended by the LiveObjects implementation; not intended for

lib/src/main/java/io/ably/lib/liveobjects/value/LiveMap.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*/
2727
public abstract class LiveMap {
2828

29-
private static final String IMPLEMENTATION_CLASS = "io.ably.lib.liveobjects.value.DefaultLiveMap";
29+
private static final String IMPLEMENTATION_CLASS = "io.ably.lib.liveobjects.value.livemap.DefaultLiveMap";
3030

3131
/**
3232
* Extended by the LiveObjects implementation; not intended for
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package io.ably.lib.liveobjects
2+
3+
import io.ably.lib.liveobjects.adapter.AblyClientAdapter
4+
import io.ably.lib.realtime.ChannelState
5+
import io.ably.lib.types.ProtocolMessage
6+
import java.util.concurrent.ConcurrentHashMap
7+
8+
public class DefaultLiveObjectsPlugin(private val adapter: AblyClientAdapter) : LiveObjectsPlugin {
9+
10+
private val objects = ConcurrentHashMap<String, DefaultRealtimeObject>()
11+
12+
override fun getInstance(channelName: String): RealtimeObject {
13+
return objects.getOrPut(channelName) { DefaultRealtimeObject(channelName, adapter) }
14+
}
15+
16+
override fun handle(msg: ProtocolMessage) {
17+
val channelName = msg.channel
18+
objects[channelName]?.handle(msg)
19+
}
20+
21+
override fun handleStateChange(channelName: String, state: ChannelState, hasObjects: Boolean) {
22+
objects[channelName]?.handleStateChange(state, hasObjects)
23+
}
24+
25+
override fun dispose(channelName: String) {
26+
objects.remove(channelName)
27+
?.dispose(clientError("Channel has been released using channels.release()"))
28+
}
29+
30+
override fun dispose() {
31+
objects.values.forEach {
32+
it.dispose(clientError("AblyClient has been closed using client.close()"))
33+
}
34+
objects.clear()
35+
}
36+
}

0 commit comments

Comments
 (0)