2010-12-15 Francois Chouinard <fchouinard@gmail.com> Fix for Bug332590
authorFrancois Chouinard <fchouinard@gmail.com>
Wed, 15 Dec 2010 19:34:50 +0000 (19:34 +0000)
committerFrancois Chouinard <fchouinard@gmail.com>
Wed, 15 Dec 2010 19:34:50 +0000 (19:34 +0000)
* src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsTable.java:
* src/org/eclipse/linuxtools/tmf/ui/widgets/TmfVirtualTable.java:

org.eclipse.linuxtools.tmf.ui/ChangeLog
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsTable.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/TmfVirtualTable.java

index 92cd93f6c658b17ef00a98515ec7a3385f633e91..66bd8968759bbd3c091db0af18c4da9221f6b142 100644 (file)
@@ -1,3 +1,8 @@
+2010-12-15  Francois Chouinard  <fchouinard@gmail.com>
+
+       * src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsTable.java: 
+       * src/org/eclipse/linuxtools/tmf/ui/widgets/TmfVirtualTable.java: 
+
 2010-11-25  Francois Chouinard  <fchouinard@gmail.com>
 
        * src/org/eclipse/linuxtools/tmf/ui/viewers/timeAnalysis/widgets/TmfTimeStatesCtrl.java (drawItemDataBurst): Fixed the threading issue on the shared vector
index 4be1298154d67e8aa90a1b87752c1e15e9bce32d..624ce0a0eb3ed9b3014f04c53825a665d54ae3b2 100644 (file)
 \r
 package org.eclipse.linuxtools.tmf.ui.viewers.events;\r
 \r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.core.runtime.jobs.Job;\r
 import org.eclipse.linuxtools.tmf.component.ITmfDataProvider;\r
 import org.eclipse.linuxtools.tmf.component.TmfComponent;\r
 import org.eclipse.linuxtools.tmf.event.TmfEvent;\r
@@ -27,6 +31,7 @@ import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler;
 import org.eclipse.linuxtools.tmf.signal.TmfTimeSynchSignal;\r
 import org.eclipse.linuxtools.tmf.signal.TmfTraceUpdatedSignal;\r
 import org.eclipse.linuxtools.tmf.trace.ITmfTrace;\r
+import org.eclipse.linuxtools.tmf.ui.TmfUiPlugin;\r
 import org.eclipse.linuxtools.tmf.ui.widgets.ColumnData;\r
 import org.eclipse.linuxtools.tmf.ui.widgets.TmfVirtualTable;\r
 import org.eclipse.swt.SWT;\r
@@ -122,13 +127,12 @@ public class TmfEventsTable extends TmfComponent {
         fTable.addListener(SWT.SetData, new Listener() {\r
 \r
             @Override\r
-                       @SuppressWarnings("unchecked")\r
                        public void handleEvent(Event event) {\r
 \r
                 final TableItem item = (TableItem) event.item;\r
                 final int index = fTable.indexOf(item);\r
 \r
-                // Note: this works because handleEvent() is called once for each row, in sequence  \r
+                // If available, return the cached data  \r
                 if ((index >= fCacheStartIndex) && (index < fCacheEndIndex)) {\r
                     int i = index - fCacheStartIndex;\r
                     item.setText(extractItemFields(fCache[i]));\r
@@ -136,36 +140,8 @@ public class TmfEventsTable extends TmfComponent {
                     return;\r
                 }\r
 \r
-                fCacheStartIndex = index;\r
-                fCacheEndIndex = index;\r
-\r
-                TmfDataRequest<TmfEvent> request = new TmfDataRequest<TmfEvent>(TmfEvent.class, index, fCacheSize) {\r
-                       private int count = 0;\r
-\r
-                       @Override\r
-                    public void handleData(TmfEvent event) {\r
-                               super.handleData(event);\r
-                        if (event != null) {\r
-                            fCache[count++] = event.clone();\r
-                            fCacheEndIndex++;\r
-                        }\r
-                    }\r
-\r
-                };\r
-\r
-                ((ITmfDataProvider<TmfEvent>) fTrace).sendRequest(request);\r
-                try {\r
-                    request.waitForCompletion();\r
-                } catch (InterruptedException e) {\r
-                    e.printStackTrace();\r
-                }\r
-                \r
-                if (fCache[0] != null && fCacheStartIndex == index) {\r
-                    item.setText(extractItemFields(fCache[0]));\r
-                    item.setData(new TmfTimestamp(fCache[0].getTimestamp()));\r
-                    packColumns();\r
-                }\r
-                \r
+                // Else, fill the cache asynchronously (and off the UI thread)\r
+                populateCache(index);\r
             }\r
         });\r
 \r
@@ -361,4 +337,89 @@ public class TmfEventsTable extends TmfComponent {
        }\r
        }\r
 \r
+    // ------------------------------------------------------------------------\r
+    // Event cache population\r
+    // ------------------------------------------------------------------------\r
+    \r
+    // The event fetching job\r
+    private Job job;\r
+\r
+    private synchronized void populateCache(final int index) {\r
+\r
+        /* Check if the current job will fetch the requested event:\r
+         * 1. The job must exist\r
+         * 2. It must be running (i.e. not completed)\r
+         * 3. The requested index must be within the cache range\r
+         * \r
+         * If the job meets these conditions, we simply exit.\r
+         * Otherwise, we create a new job but we might have to cancel\r
+         * an existing job for an obsolete range.\r
+         */\r
+        if (job != null) {\r
+            if (job.getState() != Job.NONE) {\r
+                if (index >= fCacheStartIndex && index < (fCacheStartIndex + fCacheSize)) {\r
+                    return;\r
+                }\r
+                // The new index is out of the requested range\r
+                // Kill the job and start a new one\r
+                job.cancel();\r
+            }\r
+        }\r
+        \r
+        fCacheStartIndex = index;\r
+        fCacheEndIndex   = index;\r
+\r
+        job = new Job("Fetching Events") { //$NON-NLS-1$\r
+            @Override\r
+            @SuppressWarnings("unchecked")\r
+            protected IStatus run(final IProgressMonitor monitor) {\r
+\r
+                TmfDataRequest<TmfEvent> request = new TmfDataRequest<TmfEvent>(TmfEvent.class, index, fCacheSize) {\r
+                    private int count = 0;\r
+                    @Override\r
+                    public void handleData(TmfEvent event) {\r
+                        // If the job is canceled, cancel the request so waitForCompletion() will unlock\r
+                        if (monitor.isCanceled()) {\r
+                            cancel();\r
+                            return;\r
+                        }\r
+                        super.handleData(event);\r
+                        if (event != null) {\r
+                            fCache[count++] = event.clone();\r
+                            fCacheEndIndex++;   // TODO: Need to protect this??\r
+                        }\r
+                    }\r
+                };\r
+\r
+                ((ITmfDataProvider<TmfEvent>) fTrace).sendRequest(request);\r
+                try {\r
+                    request.waitForCompletion();\r
+                } catch (InterruptedException e) {\r
+                    e.printStackTrace();\r
+                }\r
+\r
+                // Event cache is now updated. Perform update on the UI thread\r
+                if (!fTable.isDisposed() && !monitor.isCanceled()) {\r
+                    fTable.getDisplay().asyncExec(new Runnable() {\r
+                        @Override\r
+                        public void run() {\r
+                            if (!fTable.isDisposed()) {\r
+                                fTable.refresh();\r
+                            }\r
+                        }\r
+                    });\r
+                }\r
+                \r
+                // Flag the UI thread that the cache is ready\r
+                if (monitor.isCanceled()) {\r
+                    return new Status(IStatus.CANCEL, TmfUiPlugin.PLUGIN_ID, "Canceled"); //$NON-NLS-1$\r
+                }\r
+                else {\r
+                    return new Status(IStatus.OK, TmfUiPlugin.PLUGIN_ID, "Completed"); //$NON-NLS-1$\r
+                }\r
+            }\r
+        };\r
+        job.setPriority(Job.SHORT);\r
+        job.schedule();\r
+    }\r
 }\r
index cc92e6bb7eebfa33841cf04e49016c62d1790a2f..9d0bca31a9636a37d4b726f2b8b5135e44d18d11 100644 (file)
@@ -276,26 +276,33 @@ public class TmfVirtualTable extends Composite {
                                setDataItem(i, fTableItems[i]);
                        }
                }
-
-               fSlider.setSelection(fSelectedEventRank);
-               fTable.setSelection(fSelectedRow);
-               fTable.showSelection();
-               fSelectedItems[0] = fTable.getSelection()[0];
-
-        TmfTimestamp ts = (TmfTimestamp) fSelectedItems[0].getData();
-        TmfSignalManager.dispatchSignal(new TmfTimeSynchSignal(this, ts));
-       }
-
-       private void setDataItem(int index, TableItem item) {
-               if( index != -1) {
-                       Event event = new Event();
-                       event.item  = item;
-                       event.index = index + fTableTopEventRank;
-                       event.doit  = true;
-                       notifyListeners(SWT.SetData, event);
+               else {
+             notifyUpdatedSelection();
                }
        }
 
+    private void setDataItem(int index, TableItem item) {
+        if( index != -1) {
+            Event event = new Event();
+            event.item  = item;
+            event.index = index + fTableTopEventRank;
+            event.doit  = true;
+            notifyListeners(SWT.SetData, event);
+        }
+    }
+
+    public void notifyUpdatedSelection() {
+        fSlider.setSelection(fSelectedEventRank);
+        fTable.setSelection(fSelectedRow);
+        fTable.showSelection();
+        TableItem[] tableSelection = fTable.getSelection();
+        if (tableSelection.length > 0 && tableSelection[0] != null) {
+            fSelectedItems[0] = tableSelection[0];
+            TmfTimestamp ts = (TmfTimestamp) fSelectedItems[0].getData();
+            TmfSignalManager.dispatchSignal(new TmfTimeSynchSignal(this, ts));
+        }
+    }
+
        // ------------------------------------------------------------------------
        // Slider handling
        // ------------------------------------------------------------------------
@@ -437,6 +444,7 @@ public class TmfVirtualTable extends Composite {
        
        public void refresh() {
                refreshTable();
+               notifyUpdatedSelection();
        }
 
        public void setColumnHeaders(ColumnData columnData[]) {
This page took 0.02904 seconds and 5 git commands to generate.