]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/UpdateListener.java
Fixes to thread safety problems in SCL compiler
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / module / repository / UpdateListener.java
1 package org.simantics.scl.compiler.module.repository;
2
3 import gnu.trove.set.hash.THashSet;
4
5 /**
6  * Listener that is notified about changes in modules and their dependencies. It is possible
7  * to listen multiple different modules with one listener. When a change happens, the listener
8  * automatically stops listening any other changes. The idea is that the client then asks all modules
9  * again using the listener as a parameter.
10  */
11 public abstract class UpdateListener {
12     private final THashSet<Observable> observables = new THashSet<Observable>();  
13     
14     public interface Observable {
15         void removeListener(UpdateListener listener);
16     }
17     
18     public abstract void notifyAboutUpdate();
19     
20     /**
21      * Registers an observable to the listener. The client code should never
22      * call this method. It is needed so that it is possible to implement
23      * {@link #stopListening}.
24      */
25     public void addObservable(Observable observable) {
26         synchronized(observables) {
27             observables.add(observable);
28         }
29     }
30
31     /**
32      * Stops listening changes. Returns true, if the listener was listening something. 
33      */
34     public boolean stopListening() {
35         synchronized(observables) {
36             if(observables.isEmpty())
37                 return false;
38             for(Observable observable : observables)
39                 observable.removeListener(this);
40             observables.clear();
41             return true;
42         }
43     }
44 }