com.dragome.forms.bindings.client.value.AbstractReducingValueModel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dragome-form-bindings Show documentation
Show all versions of dragome-form-bindings Show documentation
Dragome SDK module: form bindings
package com.dragome.forms.bindings.client.value;
import java.util.List;
import com.dragome.forms.bindings.client.function.Reduce;
/**
* Created by IntelliJ IDEA.
* User: andrew
* Date: May 9, 2010
* Time: 10:10:37 AM
* To change this template use File | Settings | File Templates.
*/
public abstract class AbstractReducingValueModel extends AbstractValueModel
{
protected Reduce function;
private T computedValue= null;
private boolean ignoreChanges= false;
public AbstractReducingValueModel(Reduce function)
{
if (function == null)
{
throw new NullPointerException("function is null");
}
this.function= function;
}
public Reduce getFunction()
{
return function;
}
public void setFunction(Reduce function)
{
if (function == null)
{
throw new NullPointerException("function is null");
}
this.function= function;
// we use tryRecompute so we only recompute if we're not ignoring
// changes for now.
tryRecompute();
}
protected void tryRecompute()
{
if (!ignoreChanges)
{
recompute();
}
}
protected void recompute()
{
T old= computedValue;
computedValue= computeValue();
fireValueChangeEvent(old, computedValue);
}
T computeValue()
{
return function.compute(prepareValues());
}
protected abstract List prepareValues();
public T getValue()
{
return computedValue;
}
protected boolean isIgnoreChanges()
{
return ignoreChanges;
}
protected void setIgnoreChanges(boolean ignoreChanges)
{
this.ignoreChanges= ignoreChanges;
}
/**
* Delays re-computation of the result until after the specified runnable
* has been completed. This method is re-entrant.
*
* @param r the runnable to run.
*/
public void recomputeAfterRunning(Runnable r)
{
boolean oldValue= isIgnoreChanges();
try
{
setIgnoreChanges(true);
r.run();
}
finally
{
setIgnoreChanges(oldValue);
// we could have been called in a re-entrant mode so we only
// try and recompute.
tryRecompute();
}
}
}