Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFSnapshot.java')
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFSnapshot.java353
1 files changed, 353 insertions, 0 deletions
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFSnapshot.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFSnapshot.java
new file mode 100644
index 000000000..6963716ec
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFSnapshot.java
@@ -0,0 +1,353 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others.
+ * 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.tm.tcf.protocol.Protocol;
+
+/**
+ * TCFSnapshot is used to create snapshots of debug views presentation data.
+ * Such snapshots are used to implement various view update policies.
+ */
+class TCFSnapshot {
+
+ private final IPresentationContext ctx;
+
+ private final HashMap<TCFNode,PresentationData> cache = new HashMap<TCFNode,PresentationData>();
+
+ private final String[] columns;
+ private final RGB rgb_stalled = new RGB(128, 128, 128);
+
+ private boolean ignore_bg_color = true;
+
+ private class PresentationData implements IChildrenCountUpdate, IChildrenUpdate, ILabelUpdate, Runnable {
+
+ IViewerUpdate update;
+ Runnable done;
+ boolean canceled;
+ IStatus status;
+
+ String[] label;
+ FontData[] font_data;
+ ImageDescriptor[] image_desc;
+ RGB[] fg_color;
+ RGB[] bg_color;
+ boolean label_done;
+
+ TCFNode[] children;
+ boolean children_done;
+
+ boolean stalled;
+
+ private final ArrayList<Runnable> waiting_list = new ArrayList<Runnable>();
+
+ public IPresentationContext getPresentationContext() {
+ return ctx;
+ }
+
+ public Object getElement() {
+ return update.getElement();
+ }
+
+ public TreePath getElementPath() {
+ return update.getElementPath();
+ }
+
+ public Object getViewerInput() {
+ return update.getViewerInput();
+ }
+
+ public void setStatus(IStatus status) {
+ this.status = status;
+ }
+
+ public IStatus getStatus() {
+ return status;
+ }
+
+ public void done() {
+ assert false;
+ }
+
+ public void cancel() {
+ canceled = true;
+ }
+
+ public boolean isCanceled() {
+ return canceled;
+ }
+
+ public String[] getColumnIds() {
+ return columns;
+ }
+
+ public void setLabel(String text, int col) {
+ if (!label_done) {
+ if (label == null) {
+ int cnt = columns == null ? 1 : columns.length;
+ label = new String[cnt];
+ }
+ label[col] = text;
+ }
+ else {
+ if (col >= label.length) stalled = true;
+ else if (label[col] != text) {
+ if (label[col] == null || text == null || !text.equals(label[col])) {
+ stalled = true;
+ }
+ }
+ }
+ }
+
+ public void setFontData(FontData fnt, int col) {
+ if (!label_done) {
+ if (font_data == null) {
+ int cnt = columns == null ? 1 : columns.length;
+ font_data = new FontData[cnt];
+ }
+ font_data[col] = fnt;
+ }
+ }
+
+ public void setImageDescriptor(ImageDescriptor image, int col) {
+ if (!label_done) {
+ if (image_desc == null) {
+ int cnt = columns == null ? 1 : columns.length;
+ image_desc = new ImageDescriptor[cnt];
+ }
+ image_desc[col] = image;
+ }
+ }
+
+ public void setForeground(RGB rgb, int col) {
+ if (!label_done) {
+ if (fg_color == null) {
+ int cnt = columns == null ? 1 : columns.length;
+ fg_color = new RGB[cnt];
+ }
+ fg_color[col] = rgb;
+ }
+ }
+
+ public void setBackground(RGB rgb, int col) {
+ if (!label_done) {
+ if (bg_color == null) {
+ int cnt = columns == null ? 1 : columns.length;
+ bg_color = new RGB[cnt];
+ }
+ bg_color[col] = rgb;
+ }
+ }
+
+ public int getOffset() {
+ return 0;
+ }
+
+ public int getLength() {
+ return children.length;
+ }
+
+ public void setChild(Object child, int offset) {
+ if (!children_done) {
+ children[offset] = (TCFNode)child;
+ }
+ }
+
+ public void setChildCount(int cnt) {
+ if (!children_done) {
+ children = new TCFNode[cnt];
+ }
+ }
+
+ public void run() {
+ Runnable d = done;
+ update = null;
+ done = null;
+ for (Runnable r : waiting_list) Protocol.invokeLater(r);
+ waiting_list.clear();
+ d.run();
+ }
+ }
+
+ private PresentationData data;
+
+ TCFSnapshot(IPresentationContext ctx) {
+ this.ctx = ctx;
+ columns = ctx.getColumns();
+ }
+
+ void dispose() {
+ for (PresentationData d : cache.values()) {
+ for (Runnable r : d.waiting_list) Protocol.invokeLater(r);
+ }
+ cache.clear();
+ }
+
+ /**
+ * Retrieve children count for a presentation context.
+ * The method is always called on TCF dispatch thread.
+ * @param update - children count update request.
+ * @param node - debug model node.
+ * @param done - client call back interface, during data waiting it is
+ * called every time new portion of data becomes available.
+ * @return false if waiting data retrieval, true if all done.
+ */
+ public boolean getData(IChildrenCountUpdate update, TCFNode node, Runnable done) {
+ if (!getChildren(update, node, done)) return false;
+ update.setChildCount(data.children.length);
+ return true;
+ }
+
+ /**
+ * Retrieve children for a presentation context.
+ * The method is always called on TCF dispatch thread.
+ * @param update - children update request.
+ * @param node - debug model node.
+ * @param done - client call back interface, during data waiting it is
+ * called every time new portion of data becomes available.
+ * @return false if waiting data retrieval, true if all done.
+ */
+ public boolean getData(IChildrenUpdate update, TCFNode node, Runnable done) {
+ if (!getChildren(update, node, done)) return false;
+ int offset = 0;
+ int r_offset = update.getOffset();
+ int r_length = update.getLength();
+ for (TCFNode n : data.children) {
+ if (offset >= r_offset && offset < r_offset + r_length) {
+ update.setChild(n, offset);
+ }
+ offset++;
+ }
+ return true;
+ }
+
+ /**
+ * Check if the node has children in a presentation context.
+ * The method is always called on TCF dispatch thread.
+ * @param update - "has children" update request.
+ * @param node - debug model node.
+ * @param done - client call back interface, during data waiting it is
+ * called every time new portion of data becomes available.
+ * @return false if waiting data retrieval, true if all done.
+ */
+ public boolean getData(IHasChildrenUpdate update, TCFNode node, Runnable done) {
+ if (!getChildren(update, node, done)) return false;
+ update.setHasChilren(data.children.length > 0);
+ return true;
+ }
+
+ /**
+ * Retrieve node label for a presentation context.
+ * The method is always called on TCF dispatch thread.
+ * @param update - label update request.
+ * @param node - debug model node.
+ * @param done - client call back interface, during data waiting it is
+ * called every time new portion of data becomes available.
+ * @return false if waiting data retrieval, true if all done.
+ */
+ public boolean getData(ILabelUpdate update, TCFNode node, Runnable done) {
+ if (!getLabel(update, node, done)) return false;
+ String[] ids_update = update.getColumnIds();
+ String[] ids_data = columns;
+ if (ids_update != ids_data && !Arrays.equals(ids_update, ids_data)) {
+ int n = ids_update == null ? 1 : ids_update.length;
+ for (int i = 0; i < n; i++) update.setBackground(rgb_stalled, i);
+ }
+ else {
+ if (data.label != null) {
+ for (int i = 0; i < data.label.length; i++) {
+ if (data.label[i] != null) update.setLabel(data.label[i], i);
+ }
+ }
+ if (data.font_data != null) {
+ for (int i = 0; i < data.font_data.length; i++) {
+ if (data.font_data[i] != null) update.setFontData(data.font_data[i], i);
+ }
+ }
+ if (data.image_desc != null) {
+ for (int i = 0; i < data.image_desc.length; i++) {
+ if (data.image_desc[i] != null) update.setImageDescriptor(data.image_desc[i], i);
+ }
+ }
+ if (data.stalled) {
+ int n = ids_update == null ? 1 : ids_update.length;
+ for (int i = 0; i < n; i++) update.setForeground(rgb_stalled, i);
+ }
+ else {
+ if (data.fg_color != null) {
+ for (int i = 0; i < data.fg_color.length; i++) {
+ if (data.fg_color[i] != null) update.setForeground(data.fg_color[i], i);
+ }
+ }
+ }
+ if (!ignore_bg_color && data.bg_color != null) {
+ for (int i = 0; i < data.bg_color.length; i++) {
+ if (data.bg_color[i] != null) update.setBackground(data.bg_color[i], i);
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean getChildren(IViewerUpdate update, TCFNode node, Runnable done) {
+ data = cache.get(node);
+ if (data == null) cache.put(node, data = new PresentationData());
+ assert data.update != update;
+ if (data.children_done) return true;
+ if (data.update != null) {
+ data.waiting_list.add(done);
+ return false;
+ }
+ data.update = update;
+ data.done = done;
+ if (data.children == null) {
+ if (!node.getData((IChildrenCountUpdate)data, data)) return false;
+ assert data.children != null;
+ }
+ if (!node.getData((IChildrenUpdate)data, data)) return false;
+ data.children_done = true;
+ data.update = null;
+ data.done = null;
+ return true;
+ }
+
+ private boolean getLabel(IViewerUpdate update, TCFNode node, Runnable done) {
+ data = cache.get(node);
+ if (data == null) cache.put(node, data = new PresentationData());
+ assert data.update != update;
+ if (data.label_done && data.stalled) return true;
+ if (data.update != null) {
+ data.waiting_list.add(done);
+ return false;
+ }
+ data.update = update;
+ data.done = done;
+ if (!node.getData((ILabelUpdate)data, data)) return false;
+ data.label_done = true;
+ data.update = null;
+ data.done = null;
+ return true;
+ }
+}

Back to the top