package im.actor.runtime.mvvm;
import com.google.j2objc.annotations.ObjectiveCName;
import java.util.ArrayList;
/**
* Bindable MVVM Value. Used in UI data binding
*
* @param <T> type of value
*/
public abstract class Value<T> {
private ArrayList<ValueChangedListener<T>> listeners = new ArrayList<>();
private String name;
/**
* Default constructor of value
*
* @param name name of Value
*/
public Value(String name) {
this.name = name;
}
/**
* Get current value
*
* @return the value
*/
@ObjectiveCName("get")
public abstract T get();
/**
* Getting Name of Value
* Useful for debugging current bindings and notifications
*
* @return name of value
*/
public String getName() {
return name;
}
/**
* Subscribe to value updates
*
* @param listener update listener
*/
@ObjectiveCName("subscribeWithListener:")
public void subscribe(ValueChangedListener<T> listener) {
subscribe(listener, true);
}
/**
* Subscribe to value updates
*
* @param listener update listener
* @param notify perform notify about current value
*/
@ObjectiveCName("subscribeWithListener:notify:")
public void subscribe(ValueChangedListener<T> listener, boolean notify) {
// im.actor.runtime.Runtime.checkMainThread();
if (listeners.contains(listener)) {
return;
}
listeners.add(listener);
if (notify) {
listener.onChanged(get(), this);
}
}
/**
* Remove subscription for updates
*
* @param listener update listener
*/
@ObjectiveCName("unsubscribeWithListener:")
public void unsubscribe(ValueChangedListener<T> listener) {
// im.actor.runtime.Runtime.checkMainThread();
listeners.remove(listener);
}
/**
* Performing notification to subscribers
*
* @param value new value
*/
protected void notify(final T value) {
im.actor.runtime.Runtime.postToMainThread(() -> notifyInMainThread(value));
}
/**
* Performing notification to subscribers if we know that we are on mainthread
* Useful for chainging updates from chain of values
*
* @param value new value
*/
protected void notifyInMainThread(final T value) {
for (ValueChangedListener<T> listener : listeners) {
listener.onChanged(value, Value.this);
}
}
}