jtulach@374: package org.apidesign.openfixed; jtulach@374: jtulach@374: import java.util.HashSet; jtulach@374: import java.util.List; jtulach@374: import java.util.Set; jtulach@374: import java.util.concurrent.CopyOnWriteArrayList; jtulach@374: import java.util.concurrent.Executor; jtulach@374: import java.util.concurrent.Executors; jtulach@395: import org.apidesign.openfixed.Calculator.EventSupport; jtulach@374: jtulach@374: /** jtulach@374: * jtulach@374: * @author Jaroslav Tulach jtulach@374: */ jtulach@374: final class PostEventSupport implements EventSupport, Runnable { jtulach@374: private final List listeners = new CopyOnWriteArrayList(); jtulach@374: private final List deliverables = new CopyOnWriteArrayList(); jtulach@374: private static final Executor EXEC = Executors.newSingleThreadExecutor(); jtulach@374: jtulach@374: PostEventSupport() { jtulach@374: } jtulach@374: jtulach@374: @Override jtulach@374: public void fireModificationEvent(ModificationEvent ev) { jtulach@374: synchronized (deliverables) { jtulach@374: final Deliverable d = new Deliverable(ev, listeners.toArray(new ModificationListener[0])); jtulach@374: deliverables.add(d); jtulach@374: EXEC.execute(this); jtulach@374: } jtulach@374: } jtulach@374: jtulach@374: @Override jtulach@374: public void add(ModificationListener l) { jtulach@374: listeners.add(l); jtulach@374: } jtulach@374: jtulach@374: @Override jtulach@374: public void remove(ModificationListener l) { jtulach@374: listeners.remove(l); jtulach@374: } jtulach@374: jtulach@374: @Override jtulach@374: public void run() { jtulach@374: Deliverable[] pending; jtulach@374: synchronized (deliverables) { jtulach@374: if (deliverables.isEmpty()) { jtulach@374: return; jtulach@374: } jtulach@374: pending = deliverables.toArray(new Deliverable[0]); jtulach@374: deliverables.clear(); jtulach@374: } jtulach@375: // BEGIN: openfixed.postimpl jtulach@374: Calculator calc = null; jtulach@375: Set notify; jtulach@375: notify = new HashSet(); jtulach@374: int pendingCount = pending.length; jtulach@374: for (Deliverable d : pending) { jtulach@374: calc = (Calculator)d.ev.getSource(); jtulach@374: d.ev.pending = --pendingCount; jtulach@374: d.ev.posts = notify; jtulach@374: for (ModificationListener l : d.listeners) { jtulach@374: l.modification(d.ev); jtulach@374: } jtulach@374: d.ev.posts = null; jtulach@374: } jtulach@374: for (PostModificationListener pml : notify) { jtulach@374: pml.postProcess(new PostModificationEvent(calc)); jtulach@374: } jtulach@375: // END: openfixed.postimpl jtulach@374: } jtulach@374: jtulach@374: private static class Deliverable { jtulach@374: final ModificationEvent ev; jtulach@374: final ModificationListener[] listeners; jtulach@374: jtulach@374: public Deliverable(ModificationEvent ev, ModificationListener[] listeners) { jtulach@374: this.ev = ev; jtulach@374: this.listeners = listeners; jtulach@374: } jtulach@374: } jtulach@374: }