You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
2.1 KiB
Kotlin
86 lines
2.1 KiB
Kotlin
package me.eater.threedom.utils
|
|
|
|
class ObservableSet<T>(private val onChange: (Changed<T>) -> Unit) : MutableSet<T> {
|
|
private val storage: MutableSet<T> = mutableSetOf()
|
|
|
|
data class Changed<T>(val action: Action, val elements: Set<T>, val set: ObservableSet<T>)
|
|
|
|
enum class Action {
|
|
Removed,
|
|
Added;
|
|
}
|
|
|
|
override fun add(element: T): Boolean {
|
|
if (storage.add(element)) {
|
|
onChange(Changed(Action.Added, setOf(element), this))
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
override fun addAll(elements: Collection<T>): Boolean {
|
|
val items = elements.filter(storage::add)
|
|
|
|
if (items.isEmpty()) {
|
|
return false
|
|
}
|
|
|
|
onChange(Changed(Action.Added, items.toSet(), this))
|
|
return true
|
|
}
|
|
|
|
override fun clear() {
|
|
if (this.isEmpty()) {
|
|
return
|
|
}
|
|
|
|
onChange(Changed(Action.Removed, storage, this))
|
|
storage.clear()
|
|
}
|
|
|
|
override fun iterator(): MutableIterator<T> = storage.iterator()
|
|
|
|
override fun remove(element: T): Boolean {
|
|
if (storage.remove(element)) {
|
|
onChange(Changed(Action.Removed, setOf(element), this))
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
override fun removeAll(elements: Collection<T>): Boolean {
|
|
val items = elements.filter(storage::remove)
|
|
|
|
if (items.isEmpty()) {
|
|
return false
|
|
}
|
|
|
|
onChange(Changed(Action.Removed, items.toSet(), this))
|
|
return true
|
|
}
|
|
|
|
override fun retainAll(elements: Collection<T>): Boolean {
|
|
val temp = mutableSetOf<T>()
|
|
for (item in storage) {
|
|
if (!elements.contains(item)) {
|
|
temp.add(item)
|
|
storage.remove(item)
|
|
}
|
|
}
|
|
|
|
onChange(Changed(Action.Removed, temp, this))
|
|
return temp.size > 0
|
|
}
|
|
|
|
override val size: Int
|
|
get() = storage.size
|
|
|
|
override fun contains(element: T) = storage.contains(element)
|
|
|
|
override fun containsAll(elements: Collection<T>) = storage.containsAll(elements)
|
|
|
|
override fun isEmpty(): Boolean = storage.isEmpty()
|
|
}
|