]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/hints/AbstractHintObservable.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.utils.datastructures / src / org / simantics / utils / datastructures / hints / AbstractHintObservable.java
index b2f32ace91a26ba924bea833f9a36d537ff6938a..aacadc1a6a5671ac292c0a592abee0a690ff20ee 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-/*\r
- *\r
- * @author Toni Kalajainen\r
- */\r
-package org.simantics.utils.datastructures.hints;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-\r
-import java.lang.reflect.Method;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
-import org.simantics.utils.threads.Executable;\r
-import org.simantics.utils.threads.IThreadWorkQueue;\r
-import org.simantics.utils.threads.SyncListenerList;\r
-import org.simantics.utils.threads.ThreadUtils;\r
-\r
-/**\r
- * TODO Optimize class queries.\r
- * \r
- * @author Toni Kalajainen\r
- */\r
-public abstract class AbstractHintObservable implements IHintObservable {\r
-\r
-       /** Global listeners */\r
-       protected SyncListenerList<IHintListener> listeners = \r
-               new SyncListenerList<IHintListener>(IHintListener.class);\r
-       \r
-       /** Key specific listeners */\r
-       protected Map<Key, SyncListenerList<IHintListener>> keyListeners =\r
-               new THashMap<Key, SyncListenerList<IHintListener>>(2);  \r
-       \r
-       private final static SyncListenerList<IHintListener> EMPTY_LIST = \r
-               new SyncListenerList<IHintListener>(IHintListener.class);\r
-       private final static Runnable NO_ACTION = new Runnable() {\r
-               @Override\r
-               public void run() {\r
-               }};\r
-       \r
-\r
-       private synchronized SyncListenerList<IHintListener> getOrCreateKeyListeners(Key key)\r
-       {\r
-               SyncListenerList<IHintListener> result = keyListeners.get(key);\r
-               if (result==null) {\r
-                       result = new SyncListenerList<IHintListener>(IHintListener.class);\r
-                       keyListeners.put(key, result);\r
-               }\r
-               return result;\r
-       }\r
-       \r
-       protected synchronized SyncListenerList<IHintListener> getListenerList(Key forKey)\r
-       {\r
-               return keyListeners.get(forKey);\r
-       }\r
-       \r
-       private static Method hintChanged = SyncListenerList.getMethod(IHintListener.class, "hintChanged");\r
-       private static Method hintRemoved = SyncListenerList.getMethod(IHintListener.class, "hintRemoved");\r
-\r
-       protected void fireKeyChanged(IHintObservable sender, Key key, Object oldValue, Object newValue)\r
-       {                               \r
-               createFireKeyChangedRunnable(sender, key, oldValue, newValue).run();\r
-       }\r
-       \r
-       protected synchronized Executable[] getFireKeyChangedExecutables(IHintObservable sender, Key key, Object oldValue, Object newValue)\r
-       {\r
-               if (listeners.isEmpty() && keyListeners.isEmpty()) return Executable.EMPTY_ARRAY;\r
-               List<Executable> list = new ArrayList<Executable>();\r
-               addFireKeyChangedExecutables(list, sender, key, oldValue, newValue);\r
-               return list.toArray(new Executable[list.size()]);\r
-       }\r
-       \r
-       protected synchronized Runnable createFireKeyChangedRunnable(final IHintObservable sender, final Key key, final Object oldValue, final Object newValue)\r
-       {\r
-               SyncListenerList<IHintListener> l1 = listeners;\r
-               SyncListenerList<IHintListener> l2 = keyListeners.get(key);\r
-               if (l2==null) l2 = EMPTY_LIST;\r
-               if (l1.isEmpty() && l2.isEmpty()) return NO_ACTION;\r
-               if (!l1.executableInCurrentThread() || !l2.executableInCurrentThread()) {\r
-                       final Executable e[] = getFireKeyChangedExecutables(sender, key, oldValue, newValue); \r
-                       return new Runnable() {\r
-                               @Override\r
-                               public void run() {\r
-                                       ThreadUtils.multiSyncExec(e);\r
-                               }};\r
-               } else {\r
-                       final Map<IThreadWorkQueue, IHintListener[]> list1 = l1.getSnapshot(); \r
-                       final Map<IThreadWorkQueue, IHintListener[]> list2 = l2.getSnapshot();\r
-                       return new Runnable() {\r
-                               @Override\r
-                               public void run() {\r
-                                       if (list1!=null)\r
-                                       for (IHintListener[] ll : list1.values())\r
-                                               for (IHintListener l : ll)\r
-                                                       l.hintChanged(sender, key, oldValue, newValue);\r
-                                       if (list2!=null)\r
-                                       for (IHintListener[] ll : list2.values())\r
-                                               for (IHintListener l : ll)\r
-                                                       l.hintChanged(sender, key, oldValue, newValue);                                 \r
-                               }\r
-                       };                      \r
-               }\r
-       }\r
-\r
-       protected synchronized void addFireKeyChangedExecutables(Collection<Executable> list, IHintObservable sender, Key key, Object oldValue, Object newValue)\r
-       {\r
-               // Add Key specific listeners\r
-               Object[] args = {sender, key, oldValue, newValue};\r
-               SyncListenerList<IHintListener> keyListeners = getListenerList(key);\r
-               if (keyListeners!=null) \r
-                       keyListeners.addExecutables(list, hintChanged, args);\r
-               // Add generic listeners\r
-               listeners.addExecutables(list, hintChanged, args);\r
-       }\r
-       \r
-       protected void fireKeyRemoved(IHintObservable sender, Key key, Object oldValue)\r
-       {               \r
-               createFireKeyRemovedRunnable(sender, key, oldValue).run();\r
-       }\r
-       \r
-       protected synchronized Executable[] getFireKeyRemovedExecutables(IHintObservable sender, Key key, Object oldValue)\r
-       {\r
-               List<Executable> list = new ArrayList<Executable>();\r
-               addFireKeyRemovedExecutables(list, sender, key, oldValue);\r
-               return list.toArray(new Executable[list.size()]);\r
-       }\r
-       \r
-       protected synchronized Runnable createFireKeyRemovedRunnable(final IHintObservable sender, final Key key, final Object oldValue)\r
-       {\r
-               SyncListenerList<IHintListener> l1 = listeners;\r
-               SyncListenerList<IHintListener> l2 = keyListeners.get(key);\r
-               if (l2==null) l2 = EMPTY_LIST;\r
-               if (l1.isEmpty() && l2.isEmpty()) return NO_ACTION;\r
-               if (!l1.executableInCurrentThread() || !l2.executableInCurrentThread()) {\r
-                       final Executable e[] = getFireKeyRemovedExecutables(sender, key, oldValue); \r
-                       return new Runnable() {\r
-                               @Override\r
-                               public void run() {\r
-                                       ThreadUtils.multiSyncExec(e);\r
-                               }};\r
-               } else {                        \r
-                       final Map<IThreadWorkQueue, IHintListener[]> list1 = l1.getSnapshot(); \r
-                       final Map<IThreadWorkQueue, IHintListener[]> list2 = l2.getSnapshot();\r
-                       return new Runnable() {\r
-                               @Override\r
-                               public void run() {\r
-                                       for (IHintListener[] ll : list1.values())\r
-                                               for (IHintListener l : ll)\r
-                                                       l.hintRemoved(sender, key, oldValue);                                   \r
-                                       for (IHintListener[] ll : list2.values())\r
-                                               for (IHintListener l : ll)\r
-                                                       l.hintRemoved(sender, key, oldValue);                                   \r
-                               }\r
-                       };                      \r
-               }\r
-       }\r
-       \r
-       protected synchronized void addFireKeyRemovedExecutables(Collection<Executable> list, IHintObservable sender, Key key, Object oldValue)\r
-       {\r
-               // Add Key specific listeners\r
-               Object[] args = {sender, key, oldValue};\r
-               SyncListenerList<IHintListener> keyListeners = getListenerList(key);\r
-               if (keyListeners!=null) \r
-                       keyListeners.addExecutables(list, hintRemoved, args);\r
-               // Add generic listeners\r
-               listeners.addExecutables(list, hintRemoved, args);\r
-       }\r
-\r
-       protected void fireKeyChanged(Key key, Object oldValue, Object newValue)\r
-       {\r
-               fireKeyChanged(this, key, oldValue, newValue);\r
-       }\r
-       \r
-       protected void fireKeyRemoved(Key key, Object oldValue)\r
-       {\r
-               fireKeyRemoved(this, key, oldValue);\r
-       }\r
-       \r
-       public synchronized boolean hasListeners() \r
-       {\r
-               return !listeners.isEmpty() || !keyListeners.isEmpty();\r
-       }\r
-\r
-       public void addHintListener(IHintListener listener) {\r
-               listeners.add(listener);\r
-       }\r
-\r
-       public void addKeyHintListener(Key key, IHintListener listener) {\r
-               getOrCreateKeyListeners(key).add(listener);\r
-       }\r
-\r
-       public void removeHintListener(IHintListener listener) {\r
-               listeners.remove(listener);\r
-       }\r
-\r
-       public synchronized void removeKeyHintListener(Key key, IHintListener listener) {\r
-               SyncListenerList<IHintListener> list = keyListeners.get(key);\r
-               if (list==null) return;\r
-               list.remove(listener);\r
-               if (list.isEmpty()) keyListeners.remove(key);           \r
-       }\r
-               \r
-       /**\r
-        * Adds hint listener, which gets events for all hint changes\r
-        * \r
-        * @param listener\r
-        */\r
-       public void addHintListener(IThreadWorkQueue threadAccess, IHintListener listener)\r
-       {\r
-               listeners.add(threadAccess, listener);\r
-       }\r
-       \r
-       /**\r
-        * Removes hint listener\r
-        * \r
-        * @param listener\r
-        */\r
-       public void removeHintListener(IThreadWorkQueue threadAccess, IHintListener listener)\r
-       {\r
-               listeners.remove(threadAccess, listener);\r
-       }\r
-       \r
-       /**\r
-        * Adds hint listener for a specific key\r
-        * @param key\r
-        * @param listener\r
-        */\r
-       public void addKeyHintListener(IThreadWorkQueue threadAccess, Key key, IHintListener listener)\r
-       {\r
-               getOrCreateKeyListeners(key).add(threadAccess, listener);               \r
-       }\r
-       \r
-       /**\r
-        * Removes hint listener\r
-        * @param key\r
-        * @param listener\r
-        */\r
-       public void removeKeyHintListener(IThreadWorkQueue threadAccess, Key key, IHintListener listener)\r
-       {\r
-               SyncListenerList<IHintListener> list = keyListeners.get(key);\r
-               if (list==null) return;\r
-               list.remove(threadAccess, listener);\r
-               if (list.isEmpty()) keyListeners.remove(key);           \r
-       }\r
-               \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+/*
+ *
+ * @author Toni Kalajainen
+ */
+package org.simantics.utils.datastructures.hints;
+
+import gnu.trove.map.hash.THashMap;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+import org.simantics.utils.threads.Executable;
+import org.simantics.utils.threads.IThreadWorkQueue;
+import org.simantics.utils.threads.SyncListenerList;
+import org.simantics.utils.threads.ThreadUtils;
+
+/**
+ * TODO Optimize class queries.
+ * 
+ * @author Toni Kalajainen
+ */
+public abstract class AbstractHintObservable implements IHintObservable {
+
+       /** Global listeners */
+       protected SyncListenerList<IHintListener> listeners = 
+               new SyncListenerList<IHintListener>(IHintListener.class);
+       
+       /** Key specific listeners */
+       protected Map<Key, SyncListenerList<IHintListener>> keyListeners =
+               new THashMap<Key, SyncListenerList<IHintListener>>(2);  
+       
+       private final static SyncListenerList<IHintListener> EMPTY_LIST = 
+               new SyncListenerList<IHintListener>(IHintListener.class);
+       private final static Runnable NO_ACTION = new Runnable() {
+               @Override
+               public void run() {
+               }};
+       
+
+       private synchronized SyncListenerList<IHintListener> getOrCreateKeyListeners(Key key)
+       {
+               SyncListenerList<IHintListener> result = keyListeners.get(key);
+               if (result==null) {
+                       result = new SyncListenerList<IHintListener>(IHintListener.class);
+                       keyListeners.put(key, result);
+               }
+               return result;
+       }
+       
+       protected synchronized SyncListenerList<IHintListener> getListenerList(Key forKey)
+       {
+               return keyListeners.get(forKey);
+       }
+       
+       private static Method hintChanged = SyncListenerList.getMethod(IHintListener.class, "hintChanged");
+       private static Method hintRemoved = SyncListenerList.getMethod(IHintListener.class, "hintRemoved");
+
+       protected void fireKeyChanged(IHintObservable sender, Key key, Object oldValue, Object newValue)
+       {                               
+               createFireKeyChangedRunnable(sender, key, oldValue, newValue).run();
+       }
+       
+       protected synchronized Executable[] getFireKeyChangedExecutables(IHintObservable sender, Key key, Object oldValue, Object newValue)
+       {
+               if (listeners.isEmpty() && keyListeners.isEmpty()) return Executable.EMPTY_ARRAY;
+               List<Executable> list = new ArrayList<Executable>();
+               addFireKeyChangedExecutables(list, sender, key, oldValue, newValue);
+               return list.toArray(new Executable[list.size()]);
+       }
+       
+       protected synchronized Runnable createFireKeyChangedRunnable(final IHintObservable sender, final Key key, final Object oldValue, final Object newValue)
+       {
+               SyncListenerList<IHintListener> l1 = listeners;
+               SyncListenerList<IHintListener> l2 = keyListeners.get(key);
+               if (l2==null) l2 = EMPTY_LIST;
+               if (l1.isEmpty() && l2.isEmpty()) return NO_ACTION;
+               if (!l1.executableInCurrentThread() || !l2.executableInCurrentThread()) {
+                       final Executable e[] = getFireKeyChangedExecutables(sender, key, oldValue, newValue); 
+                       return new Runnable() {
+                               @Override
+                               public void run() {
+                                       ThreadUtils.multiSyncExec(e);
+                               }};
+               } else {
+                       final Map<IThreadWorkQueue, IHintListener[]> list1 = l1.getSnapshot(); 
+                       final Map<IThreadWorkQueue, IHintListener[]> list2 = l2.getSnapshot();
+                       return new Runnable() {
+                               @Override
+                               public void run() {
+                                       if (list1!=null)
+                                       for (IHintListener[] ll : list1.values())
+                                               for (IHintListener l : ll)
+                                                       l.hintChanged(sender, key, oldValue, newValue);
+                                       if (list2!=null)
+                                       for (IHintListener[] ll : list2.values())
+                                               for (IHintListener l : ll)
+                                                       l.hintChanged(sender, key, oldValue, newValue);                                 
+                               }
+                       };                      
+               }
+       }
+
+       protected synchronized void addFireKeyChangedExecutables(Collection<Executable> list, IHintObservable sender, Key key, Object oldValue, Object newValue)
+       {
+               // Add Key specific listeners
+               Object[] args = {sender, key, oldValue, newValue};
+               SyncListenerList<IHintListener> keyListeners = getListenerList(key);
+               if (keyListeners!=null) 
+                       keyListeners.addExecutables(list, hintChanged, args);
+               // Add generic listeners
+               listeners.addExecutables(list, hintChanged, args);
+       }
+       
+       protected void fireKeyRemoved(IHintObservable sender, Key key, Object oldValue)
+       {               
+               createFireKeyRemovedRunnable(sender, key, oldValue).run();
+       }
+       
+       protected synchronized Executable[] getFireKeyRemovedExecutables(IHintObservable sender, Key key, Object oldValue)
+       {
+               List<Executable> list = new ArrayList<Executable>();
+               addFireKeyRemovedExecutables(list, sender, key, oldValue);
+               return list.toArray(new Executable[list.size()]);
+       }
+       
+       protected synchronized Runnable createFireKeyRemovedRunnable(final IHintObservable sender, final Key key, final Object oldValue)
+       {
+               SyncListenerList<IHintListener> l1 = listeners;
+               SyncListenerList<IHintListener> l2 = keyListeners.get(key);
+               if (l2==null) l2 = EMPTY_LIST;
+               if (l1.isEmpty() && l2.isEmpty()) return NO_ACTION;
+               if (!l1.executableInCurrentThread() || !l2.executableInCurrentThread()) {
+                       final Executable e[] = getFireKeyRemovedExecutables(sender, key, oldValue); 
+                       return new Runnable() {
+                               @Override
+                               public void run() {
+                                       ThreadUtils.multiSyncExec(e);
+                               }};
+               } else {                        
+                       final Map<IThreadWorkQueue, IHintListener[]> list1 = l1.getSnapshot(); 
+                       final Map<IThreadWorkQueue, IHintListener[]> list2 = l2.getSnapshot();
+                       return new Runnable() {
+                               @Override
+                               public void run() {
+                                       for (IHintListener[] ll : list1.values())
+                                               for (IHintListener l : ll)
+                                                       l.hintRemoved(sender, key, oldValue);                                   
+                                       for (IHintListener[] ll : list2.values())
+                                               for (IHintListener l : ll)
+                                                       l.hintRemoved(sender, key, oldValue);                                   
+                               }
+                       };                      
+               }
+       }
+       
+       protected synchronized void addFireKeyRemovedExecutables(Collection<Executable> list, IHintObservable sender, Key key, Object oldValue)
+       {
+               // Add Key specific listeners
+               Object[] args = {sender, key, oldValue};
+               SyncListenerList<IHintListener> keyListeners = getListenerList(key);
+               if (keyListeners!=null) 
+                       keyListeners.addExecutables(list, hintRemoved, args);
+               // Add generic listeners
+               listeners.addExecutables(list, hintRemoved, args);
+       }
+
+       protected void fireKeyChanged(Key key, Object oldValue, Object newValue)
+       {
+               fireKeyChanged(this, key, oldValue, newValue);
+       }
+       
+       protected void fireKeyRemoved(Key key, Object oldValue)
+       {
+               fireKeyRemoved(this, key, oldValue);
+       }
+       
+       public synchronized boolean hasListeners() 
+       {
+               return !listeners.isEmpty() || !keyListeners.isEmpty();
+       }
+
+       public void addHintListener(IHintListener listener) {
+               listeners.add(listener);
+       }
+
+       public void addKeyHintListener(Key key, IHintListener listener) {
+               getOrCreateKeyListeners(key).add(listener);
+       }
+
+       public void removeHintListener(IHintListener listener) {
+               listeners.remove(listener);
+       }
+
+       public synchronized void removeKeyHintListener(Key key, IHintListener listener) {
+               SyncListenerList<IHintListener> list = keyListeners.get(key);
+               if (list==null) return;
+               list.remove(listener);
+               if (list.isEmpty()) keyListeners.remove(key);           
+       }
+               
+       /**
+        * Adds hint listener, which gets events for all hint changes
+        * 
+        * @param listener
+        */
+       public void addHintListener(IThreadWorkQueue threadAccess, IHintListener listener)
+       {
+               listeners.add(threadAccess, listener);
+       }
+       
+       /**
+        * Removes hint listener
+        * 
+        * @param listener
+        */
+       public void removeHintListener(IThreadWorkQueue threadAccess, IHintListener listener)
+       {
+               listeners.remove(threadAccess, listener);
+       }
+       
+       /**
+        * Adds hint listener for a specific key
+        * @param key
+        * @param listener
+        */
+       public void addKeyHintListener(IThreadWorkQueue threadAccess, Key key, IHintListener listener)
+       {
+               getOrCreateKeyListeners(key).add(threadAccess, listener);               
+       }
+       
+       /**
+        * Removes hint listener
+        * @param key
+        * @param listener
+        */
+       public void removeKeyHintListener(IThreadWorkQueue threadAccess, Key key, IHintListener listener)
+       {
+               SyncListenerList<IHintListener> list = keyListeners.get(key);
+               if (list==null) return;
+               list.remove(threadAccess, listener);
+               if (list.isEmpty()) keyListeners.remove(key);           
+       }
+               
+}