]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/UpdateListener.java
Fixed memory leaks of SCL module listening systems
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / module / repository / UpdateListener.java
index 7320758e48f6a2c1f6f1208db93b90c1b4fb4c96..4e3ad119d77bc5a686577e00090bea4b177a6305 100644 (file)
@@ -1,5 +1,41 @@
 package org.simantics.scl.compiler.module.repository;
 
-public interface UpdateListener {
-    void notifyAboutUpdate();
+import gnu.trove.set.hash.THashSet;
+
+/**
+ * Listener that is notified about changes in modules and their dependencies. It is possible
+ * to listen multiple different modules with one listener. When a change happens, the listener
+ * automatically stops listening any other changes. The idea is that the client then asks all modules
+ * again using the listener as a parameter.
+ */
+public abstract class UpdateListener {
+    private final THashSet<Observable> observables = new THashSet<Observable>();  
+    
+    public interface Observable {
+        void removeListener(UpdateListener listener);
+    }
+    
+    public abstract void notifyAboutUpdate();
+    
+    /**
+     * Registers an observable to the listener. The client code should never
+     * call this method. It is needed so that it is possible to implement
+     * {@link #stopListening}.
+     */
+    public void addObservable(Observable observable) {
+        synchronized(observables) {
+            observables.add(observable);
+        }
+    }
+
+    /**
+     * Stops listening changes. 
+     */
+    public void stopListening() {
+        synchronized(observables) {
+            for(Observable observable : observables)
+                observable.removeListener(this);
+            observables.clear();
+        }
+    }
 }