package com.arellomobile.mvp.viewstate;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import com.arellomobile.mvp.MvpView;
/**
* Date: 15.12.2015
* Time: 19:58
*
* @author Yuri Shmakov
*/
@SuppressWarnings("WeakerAccess")
public abstract class MvpViewState<View extends MvpView> {
protected ViewCommands<View> mViewCommands = new ViewCommands<>();
protected Set<View> mViews;
protected Set<View> mInRestoreState;
protected Map<View, Set<ViewCommand<View>>> mViewStates;
public MvpViewState() {
mViews = Collections.newSetFromMap(new WeakHashMap<View, Boolean>());
mInRestoreState = Collections.newSetFromMap(new WeakHashMap<View, Boolean>());
mViewStates = new WeakHashMap<>();
}
/**
* Apply saved state to attached view
*
* @param view mvp view to restore state
* @param currentState commands that was applied already
*/
protected void restoreState(View view, Set<ViewCommand<View>> currentState) {
if (mViewCommands.isEmpty()) {
return;
}
mViewCommands.reapply(view, currentState);
}
/**
* Attach view to view state and apply saves state
*
* @param view attachment
*/
public void attachView(View view) {
if (view == null) {
throw new IllegalArgumentException("Mvp view must be not null");
}
boolean isViewAdded = mViews.add(view);
if (!isViewAdded) {
return;
}
mInRestoreState.add(view);
Set<ViewCommand<View>> currentState = mViewStates.get(view);
currentState = currentState == null ? Collections.<ViewCommand<View>>emptySet() : currentState;
restoreState(view, currentState);
mViewStates.remove(view);
mInRestoreState.remove(view);
}
/**
* <p>Detach view from view state. After this moment view state save
* commands via
* {@link com.arellomobile.mvp.viewstate.strategy.StateStrategy#beforeApply(List, ViewCommand)}.</p>
*
* @param view target mvp view to detach
*/
public void detachView(View view) {
mViews.remove(view);
mInRestoreState.remove(view);
Set<ViewCommand<View>> currentState = Collections.newSetFromMap(new WeakHashMap<ViewCommand<View>, Boolean>());
currentState.addAll(mViewCommands.getCurrentState());
mViewStates.put(view, currentState);
}
public void destroyView(View view) {
mViewStates.remove(view);
}
/**
* @return views, attached to this view state instance
*/
public Set<View> getViews() {
return mViews;
}
/**
* Check if view is in restore state or not
*
* @param view view for check
* @return true if view state restore state to incoming view. false otherwise.
*/
public boolean isInRestoreState(View view) {
return mInRestoreState.contains(view);
}
}