samples/openfixed/src/org/apidesign/openfixed/PostEventSupport.java
author Jaroslav Tulach <jtulach@netbeans.org>
Sun, 20 Mar 2011 18:52:47 +0100
changeset 374 35da2d439e3d
child 375 3abae898011d
permissions -rw-r--r--
Calculator and various ways to deliver changes in its counter to listeners
     1 package org.apidesign.openfixed;
     2 
     3 import java.util.HashSet;
     4 import java.util.List;
     5 import java.util.Set;
     6 import java.util.concurrent.CopyOnWriteArrayList;
     7 import java.util.concurrent.Executor;
     8 import java.util.concurrent.Executors;
     9 
    10 /**
    11  *
    12  * @author Jaroslav Tulach <jtulach@netbeans.org>
    13  */
    14 final class PostEventSupport implements EventSupport, Runnable {
    15     private final List<ModificationListener> listeners = new CopyOnWriteArrayList<ModificationListener>();
    16     private final List<Deliverable> deliverables = new CopyOnWriteArrayList<Deliverable>();
    17     private static final Executor EXEC = Executors.newSingleThreadExecutor();
    18     
    19     PostEventSupport() {
    20     }
    21 
    22     @Override
    23     public void fireModificationEvent(ModificationEvent ev) {
    24         synchronized (deliverables) {
    25             final Deliverable d = new Deliverable(ev, listeners.toArray(new ModificationListener[0]));
    26             deliverables.add(d);
    27             EXEC.execute(this);
    28         }
    29     }
    30 
    31     @Override
    32     public void add(ModificationListener l) {
    33         listeners.add(l);
    34     }
    35 
    36     @Override
    37     public void remove(ModificationListener l) {
    38         listeners.remove(l);
    39     }
    40 
    41     @Override
    42     public void run() {
    43         Deliverable[] pending;
    44         synchronized (deliverables) {
    45             if (deliverables.isEmpty()) {
    46                 return;
    47             }
    48             pending = deliverables.toArray(new Deliverable[0]);
    49             deliverables.clear();
    50         }
    51         Calculator calc = null;
    52         Set<PostModificationListener> notify = new HashSet<PostModificationListener>();
    53         int pendingCount = pending.length;
    54         for (Deliverable d : pending) {
    55             calc = (Calculator)d.ev.getSource();
    56             d.ev.pending = --pendingCount;
    57             d.ev.posts = notify;
    58             for (ModificationListener l : d.listeners) {
    59                 l.modification(d.ev);
    60             }
    61             d.ev.posts = null;
    62         }
    63         
    64         for (PostModificationListener pml : notify) {
    65             pml.postProcess(new PostModificationEvent(calc));
    66         }
    67     }
    68     
    69     private static class Deliverable {
    70         final ModificationEvent ev;
    71         final ModificationListener[] listeners;
    72 
    73         public Deliverable(ModificationEvent ev, ModificationListener[] listeners) {
    74             this.ev = ev;
    75             this.listeners = listeners;
    76         }
    77     }
    78 }