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

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()
}