1 11 package org.eclipse.jface.internal.databinding.provisional.observable.value; 12 13 import org.eclipse.jface.internal.databinding.provisional.observable.IChangeListener; 14 import org.eclipse.jface.internal.databinding.provisional.observable.IObservable; 15 import org.eclipse.jface.internal.databinding.provisional.observable.IStaleListener; 16 import org.eclipse.jface.internal.databinding.provisional.observable.ObservableTracker; 17 18 25 public abstract class ComputedValue extends AbstractObservableValue { 26 27 private boolean dirty = true; 28 29 private boolean stale = false; 30 31 private Object cachedValue = null; 32 33 38 private IObservable[] dependencies = new IObservable[0]; 39 40 43 public ComputedValue() { 44 this(Object .class); 45 } 46 47 50 public ComputedValue(Object valueType) { 51 this.valueType = valueType; 52 } 53 54 75 private class PrivateInterface implements Runnable , IChangeListener, 76 IStaleListener { 77 public void run() { 78 cachedValue = calculate(); 79 } 80 81 public void handleStale(IObservable source) { 82 if (!dirty && !stale) { 83 stale = true; 84 fireStale(); 85 } 86 } 87 88 public void handleChange(IObservable source) { 89 makeDirty(); 90 } 91 } 92 93 private PrivateInterface privateInterface = new PrivateInterface(); 94 95 private Object valueType; 96 97 public final Object doGetValue() { 98 if (dirty) { 99 IObservable[] newDependencies = ObservableTracker.runAndMonitor( 104 privateInterface, privateInterface, null); 105 106 stale = false; 107 for (int i = 0; i < newDependencies.length; i++) { 108 IObservable observable = newDependencies[i]; 109 if (observable.isStale()) { 111 stale = true; 112 } else { 113 observable.addStaleListener(privateInterface); 114 } 115 } 116 117 dependencies = newDependencies; 118 119 dirty = false; 120 } 121 122 return cachedValue; 123 } 124 125 130 protected abstract Object calculate(); 131 132 protected final void makeDirty() { 133 if (!dirty) { 134 dirty = true; 135 136 for (int i = 0; i < dependencies.length; i++) { 138 IObservable observable = dependencies[i]; 139 140 observable.removeChangeListener(privateInterface); 141 observable.removeStaleListener(privateInterface); 142 } 143 144 final Object oldValue = cachedValue; 146 fireValueChange(new ValueDiff() { 149 150 public Object getOldValue() { 151 return oldValue; 152 } 153 154 public Object getNewValue() { 155 return getValue(); 156 } 157 }); 158 } 159 } 160 161 public boolean isStale() { 162 getValue(); 164 return stale; 165 } 166 167 public Object getValueType() { 168 return valueType; 169 } 170 } 171 | Popular Tags |