-
Notifications
You must be signed in to change notification settings - Fork 368
/
SingletonModelStore.kt
77 lines (64 loc) · 2.48 KB
/
SingletonModelStore.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package com.onesignal.common.modeling
import com.onesignal.common.events.EventProducer
/**
* A singleton model store implementation that wraps a backing [ModelStore] to manage
* the single [Model] instance.
*/
open class SingletonModelStore<TModel>(
val store: ModelStore<TModel>,
) : ISingletonModelStore<TModel>, IModelStoreChangeHandler<TModel> where TModel : Model {
private val changeSubscription: EventProducer<ISingletonModelStoreChangeHandler<TModel>> = EventProducer()
private val singletonId: String = "-singleton-"
private val replaceLock = Any()
init {
store.subscribe(this)
}
override val model: TModel
get() {
synchronized(this) {
val model = store.get(singletonId)
if (model != null) {
return model
}
val createdModel = store.create() ?: throw Exception("Unable to initialize model from store $store")
createdModel.id = singletonId
store.add(createdModel)
return createdModel
}
}
override fun replace(
model: TModel,
tag: String,
) {
synchronized(replaceLock) {
val oldModel = this.store.create() ?: throw Exception("Unable to initialize model from store $store")
oldModel.initializeFromModel(singletonId, this.model)
val existingModel = this.model
existingModel.initializeFromModel(singletonId, model)
store.persist()
changeSubscription.fire { it.onModelReplaced(ModelReplacedArgs(oldModel, existingModel), tag) }
}
}
override fun subscribe(handler: ISingletonModelStoreChangeHandler<TModel>) = changeSubscription.subscribe(handler)
override fun unsubscribe(handler: ISingletonModelStoreChangeHandler<TModel>) = changeSubscription.unsubscribe(handler)
override val hasSubscribers: Boolean
get() = changeSubscription.hasSubscribers
override fun onModelAdded(
model: TModel,
tag: String,
) {
// singleton is assumed to always exist. It gets added transparently therefore no event.
}
override fun onModelUpdated(
args: ModelChangedArgs,
tag: String,
) {
changeSubscription.fire { it.onModelUpdated(args, tag) }
}
override fun onModelRemoved(
model: TModel,
tag: String,
) {
// singleton is assumed to always exist. It never gets removed therefore no event.
}
}