Index: editor/tools/plugins/com.xored.glance.ui/src/com/xored/glance/ui/controls/tree/UnknownTreeVisitor.java |
=================================================================== |
--- editor/tools/plugins/com.xored.glance.ui/src/com/xored/glance/ui/controls/tree/UnknownTreeVisitor.java (revision 0) |
+++ editor/tools/plugins/com.xored.glance.ui/src/com/xored/glance/ui/controls/tree/UnknownTreeVisitor.java (revision 0) |
@@ -0,0 +1,76 @@ |
+/******************************************************************************* |
+ * Copyright (c) 2012 xored software, Inc. 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: |
+ * xored software, Inc. - initial API and implementation (Yuri Strot) |
+ ******************************************************************************/ |
+package com.xored.glance.ui.controls.tree; |
+ |
+import java.util.ArrayList; |
+import java.util.Arrays; |
+import java.util.List; |
+ |
+import org.eclipse.core.runtime.IProgressMonitor; |
+import org.eclipse.core.runtime.SubProgressMonitor; |
+ |
+public abstract class UnknownTreeVisitor { |
+ |
+ public void visit(IProgressMonitor monitor) { |
+ monitor.beginTask("Tree indexing", 100); |
+ try { |
+ Object[] roots = getRoots(); |
+ monitor.worked(1); |
+ breadthVisit(roots, monitor, 1); |
+ } finally { |
+ monitor.done(); |
+ } |
+ } |
+ |
+ protected abstract Object[] getRoots(); |
+ |
+ protected abstract Object[] getChildren(Object element); |
+ |
+ private void breadthVisit(Object[] elements, IProgressMonitor monitor, int level) { |
+ List<Object> next = new ArrayList<Object>(); |
+ for (Object element : elements) { |
+ if (monitor.isCanceled()) |
+ return; |
+ next.addAll(Arrays.asList(getChildren(element))); |
+ } |
+ if (monitor.isCanceled()) |
+ return; |
+ int work = (int) Math.pow(2, level); |
+ monitor.worked(work); |
+ int totalWork = 2 * work - 1; |
+ int size = next.size(); |
+ if (size == 0) |
+ return; |
+ int remains = 100 - totalWork; |
+ if (remains > size) { |
+ breadthVisit(next.toArray(), monitor, level + 1); |
+ } else { |
+ SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, remains); |
+ try { |
+ subMonitor.beginTask("", size); |
+ for (Object element : next) { |
+ depthVisit(element, monitor, level + 1); |
+ subMonitor.worked(1); |
+ } |
+ } finally { |
+ subMonitor.done(); |
+ } |
+ } |
+ } |
+ |
+ private void depthVisit(Object element, IProgressMonitor monitor, int level) { |
+ if (level > 4) { |
+ return; |
+ } |
+ for (Object child : getChildren(element)) { |
+ if (monitor.isCanceled()) |
+ return; |
+ depthVisit(child, monitor, level + 1); |
+ } |
+ } |
+ |
+} |