1.1 --- a/json/src/main/java/org/apidesign/html/json/spi/Observers.java Sat Aug 02 06:45:55 2014 +0200
1.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/Observers.java Sat Aug 02 07:01:20 2014 +0200
1.3 @@ -57,7 +57,8 @@
1.4 private final List<Watcher> watchers = new ArrayList<Watcher>();
1.5 private final List<Ref> observers = new ArrayList<Ref>();
1.6
1.7 - private Observers() {
1.8 + Observers() {
1.9 + assert Thread.holdsLock(GLOBAL);
1.10 }
1.11
1.12 static void beginComputing(Proto p, String name) {
1.13 @@ -78,41 +79,29 @@
1.14 }
1.15 }
1.16
1.17 - static Observers accessingValue(Proto p, Observers observers, String propName) {
1.18 + static void accessingValue(Proto p, String propName) {
1.19 synchronized (GLOBAL) {
1.20 verifyUnlocked(p);
1.21 for (Watcher w : GLOBAL) {
1.22 - if (observers == null) {
1.23 - observers = new Observers();
1.24 - }
1.25 - observers.add(w, new Ref(w, propName));
1.26 + Observers mine = p.observers(true);
1.27 + mine.add(w, new Ref(w, propName));
1.28 }
1.29 - return observers;
1.30 }
1.31 }
1.32
1.33 - static Observers finishComputing(Proto p, Observers mine) {
1.34 + static void finishComputing(Proto p) {
1.35 synchronized (GLOBAL) {
1.36 Watcher w = GLOBAL.pop();
1.37 if (w.proto != p) {
1.38 throw new IllegalStateException("Inconsistency: " + w.proto + " != " + p);
1.39 }
1.40 if (w.prop != null) {
1.41 - if (mine == null) {
1.42 - mine = new Observers();
1.43 - }
1.44 + Observers mine = p.observers(true);
1.45 mine.add(w);
1.46 }
1.47 - return mine;
1.48 }
1.49 }
1.50
1.51 - static Watcher computing(Proto proto, String prop) {
1.52 - proto.getClass();
1.53 - prop.getClass();
1.54 - return new Watcher(proto, prop);
1.55 - }
1.56 -
1.57 private static final class Ref extends WeakReference<Watcher> {
1.58 private final String prop;
1.59
1.60 @@ -126,7 +115,7 @@
1.61 if (w == null) {
1.62 return null;
1.63 }
1.64 - final Observers o = w.proto.observers();
1.65 + final Observers o = w.proto.observers(false);
1.66 if (o == null) {
1.67 return null;
1.68 }
1.69 @@ -165,10 +154,14 @@
1.70 watchers.add(w);
1.71 }
1.72
1.73 - final void valueHasMutated(String propName) {
1.74 + static final void valueHasMutated(Proto p, String propName) {
1.75 List<Watcher> mutated = new LinkedList<Watcher>();
1.76 synchronized (GLOBAL) {
1.77 - Iterator<Ref> it = observers.iterator();
1.78 + Observers mine = p.observers(false);
1.79 + if (mine == null) {
1.80 + return;
1.81 + }
1.82 + Iterator<Ref> it = mine.observers.iterator();
1.83 while (it.hasNext()) {
1.84 Ref ref = it.next();
1.85 if (ref.get() == null) {
1.86 @@ -183,12 +176,12 @@
1.87 }
1.88 }
1.89 }
1.90 - for (Watcher w : mutated) {
1.91 + for (Watcher w : mutated) {
1.92 w.proto.valueHasMutated(w.prop);
1.93 }
1.94 }
1.95
1.96 - void add(Watcher w, Ref r) {
1.97 + void add(Watcher w, Ref r) {
1.98 Thread.holdsLock(GLOBAL);
1.99 if (w == null) {
1.100 return;
2.1 --- a/json/src/main/java/org/apidesign/html/json/spi/Proto.java Sat Aug 02 06:45:55 2014 +0200
2.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/Proto.java Sat Aug 02 07:01:20 2014 +0200
2.3 @@ -98,7 +98,7 @@
2.4 }
2.5
2.6 public void accessValue(String propName) {
2.7 - observers = Observers.accessingValue(this, observers, propName);
2.8 + Observers.accessingValue(this, propName);
2.9 }
2.10
2.11 /** Verifies the model is not locked otherwise throws an exception.
2.12 @@ -112,7 +112,7 @@
2.13 * unlocked state by calling this method.
2.14 */
2.15 public void releaseLock() {
2.16 - observers = Observers.finishComputing(this, observers);
2.17 + Observers.finishComputing(this);
2.18 }
2.19
2.20 /** Whenever model changes a property. It should notify the
2.21 @@ -130,9 +130,7 @@
2.22 if (ko != null) {
2.23 ko.valueHasMutated(propName, null, null);
2.24 }
2.25 - if (observers != null) {
2.26 - observers.valueHasMutated(propName);
2.27 - }
2.28 + Observers.valueHasMutated(Proto.this, propName);
2.29 }
2.30 });
2.31 }
2.32 @@ -160,9 +158,7 @@
2.33 if (ko != null) {
2.34 ko.valueHasMutated(propName, oldValue, newValue);
2.35 }
2.36 - if (observers != null) {
2.37 - observers.valueHasMutated(propName);
2.38 - }
2.39 + Observers.valueHasMutated(Proto.this, propName);
2.40 }
2.41 });
2.42 }
2.43 @@ -454,7 +450,10 @@
2.44 type.onChange(obj, index);
2.45 }
2.46
2.47 - final Observers observers() {
2.48 + final Observers observers(boolean create) {
2.49 + if (create && observers == null) {
2.50 + observers = new Observers();
2.51 + }
2.52 return observers;
2.53 }
2.54