package app.furmeet.events.system.helper.observables

open class Observable<T : Any?> {
    @Volatile
    private var _changed: Boolean? = null
    @Volatile
    private var _observers: MutableList<Observer<T>>? = null

    private var changed: Boolean
        get() = _changed != true
        set(v) {
            _changed = v
        }
    private val observers: MutableList<Observer<T>>
        get() {
            if (_observers == null)
                _observers = mutableListOf()
            return _observers!!
        }

    protected fun setChanged() {
        changed = true
    }

    protected fun clearChanged() {
        changed = false
    }

    fun countObservers() = observers.size
    fun addObserver(observer: Observer<T>) = observers.add(observer)
    fun deleteObserver(observer: Observer<T>) = observers.remove(observer)
    fun deleteObservers() = observers.removeAll { true }
    open fun hasChanged() = changed
    fun notifyObservers() = notifyObservers(null)
    fun notifyObservers(arg: T?) {
        // Don't do anything async here or you might lose data
        if (hasChanged()) {
            clearChanged()
            observers.forEach {
                it.update(this, arg)
            }
        }
    }
}