Search in sources :

Example 1 with TreeConsumer

use of com.intellij.ide.util.treeView.TreeRunnable.TreeConsumer in project intellij-community by JetBrains.

the class AbstractTreeUi method queueBackgroundUpdate.

private boolean queueBackgroundUpdate(@NotNull final UpdateInfo updateInfo, @NotNull final DefaultMutableTreeNode node) {
    assertIsDispatchThread();
    final Object oldElementFromDescriptor = getElementFromDescriptor(updateInfo.getDescriptor());
    UpdateInfo loaded = getLoadedInBackground(oldElementFromDescriptor);
    if (loaded != null) {
        loaded.apply(updateInfo);
        return false;
    }
    addToLoadedInBackground(oldElementFromDescriptor, updateInfo);
    maybeSetBusyAndScheduleWaiterForReady(true, oldElementFromDescriptor);
    if (!isNodeBeingBuilt(node)) {
        LoadingNode loadingNode = new LoadingNode(getLoadingNodeText());
        myTreeModel.insertNodeInto(loadingNode, node, node.getChildCount());
    }
    removeFromUnbuilt(node);
    final Ref<LoadedChildren> children = new Ref<>();
    final Ref<Object> elementFromDescriptor = new Ref<>();
    final DefaultMutableTreeNode[] nodeToProcessActions = new DefaultMutableTreeNode[1];
    final TreeConsumer<Void> finalizeRunnable = new TreeConsumer<Void>("AbstractTreeUi.queueBackgroundUpdate: finalize") {

        @Override
        public void perform() {
            invokeLaterIfNeeded(false, new TreeRunnable("AbstractTreeUi.queueBackgroundUpdate: finalize later") {

                @Override
                public void perform() {
                    if (isReleased())
                        return;
                    removeLoading(node, false);
                    removeFromLoadedInBackground(elementFromDescriptor.get());
                    removeFromLoadedInBackground(oldElementFromDescriptor);
                    if (nodeToProcessActions[0] != null) {
                        processNodeActionsIfReady(nodeToProcessActions[0]);
                    }
                }
            });
        }
    };
    Runnable buildRunnable = new TreeRunnable("AbstractTreeUi.queueBackgroundUpdate: build") {

        @Override
        public void perform() {
            if (updateInfo.getPass().isExpired()) {
                finalizeRunnable.run();
                return;
            }
            if (!updateInfo.isDescriptorIsUpToDate()) {
                update(updateInfo.getDescriptor(), true);
            }
            if (!updateInfo.isUpdateChildren()) {
                nodeToProcessActions[0] = node;
                return;
            }
            Object element = getElementFromDescriptor(updateInfo.getDescriptor());
            if (element == null) {
                removeFromLoadedInBackground(oldElementFromDescriptor);
                finalizeRunnable.run();
                return;
            }
            elementFromDescriptor.set(element);
            Object[] loadedElements = getChildrenFor(element);
            final LoadedChildren loaded = new LoadedChildren(loadedElements);
            for (final Object each : loadedElements) {
                NodeDescriptor existingDesc = getDescriptorFrom(getNodeForElement(each, true));
                final NodeDescriptor eachChildDescriptor = isValid(existingDesc) ? existingDesc : getTreeStructure().createDescriptor(each, updateInfo.getDescriptor());
                execute(new TreeRunnable("AbstractTreeUi.queueBackgroundUpdate") {

                    @Override
                    public void perform() {
                        Promise<Boolean> promise = update(eachChildDescriptor, true);
                        LOG.assertTrue(promise instanceof Getter);
                        //noinspection unchecked
                        loaded.putDescriptor(each, eachChildDescriptor, ((Getter<Boolean>) promise).get());
                    }
                });
            }
            children.set(loaded);
        }

        @NotNull
        @NonNls
        @Override
        public String toString() {
            return "runnable=" + oldElementFromDescriptor;
        }
    };
    Runnable updateRunnable = new TreeRunnable("AbstractTreeUi.queueBackgroundUpdate: update") {

        @Override
        public void perform() {
            if (updateInfo.getPass().isExpired()) {
                finalizeRunnable.run();
                return;
            }
            if (children.get() == null) {
                finalizeRunnable.run();
                return;
            }
            if (isRerunNeeded(updateInfo.getPass())) {
                removeFromLoadedInBackground(elementFromDescriptor.get());
                getUpdater().requeue(updateInfo.getPass());
                return;
            }
            removeFromLoadedInBackground(elementFromDescriptor.get());
            if (myUnbuiltNodes.contains(node)) {
                Pair<Boolean, LoadedChildren> unbuilt = processUnbuilt(node, updateInfo.getDescriptor(), updateInfo.getPass(), isExpanded(node, updateInfo.isWasExpanded()), children.get());
                if (unbuilt.getFirst()) {
                    nodeToProcessActions[0] = node;
                    return;
                }
            }
            ActionCallback callback = updateNodeChildren(node, updateInfo.getPass(), children.get(), true, updateInfo.isCanSmartExpand(), updateInfo.isForceUpdate(), true, true);
            callback.doWhenDone(new TreeRunnable("AbstractTreeUi.queueBackgroundUpdate: on done updateNodeChildren") {

                @Override
                public void perform() {
                    if (isRerunNeeded(updateInfo.getPass())) {
                        getUpdater().requeue(updateInfo.getPass());
                        return;
                    }
                    Object element = elementFromDescriptor.get();
                    if (element != null) {
                        removeLoading(node, false);
                        nodeToProcessActions[0] = node;
                    }
                }
            });
        }
    };
    queueToBackground(buildRunnable, updateRunnable).done(finalizeRunnable).rejected(new TreeConsumer<Throwable>("AbstractTreeUi.queueBackgroundUpdate: on rejected") {

        @Override
        public void perform() {
            updateInfo.getPass().expire();
        }
    });
    return true;
}
Also used : LoadingNode(com.intellij.ui.LoadingNode) TreeConsumer(com.intellij.ide.util.treeView.TreeRunnable.TreeConsumer) AsyncPromise(org.jetbrains.concurrency.AsyncPromise) Promise(org.jetbrains.concurrency.Promise) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Aggregations

TreeConsumer (com.intellij.ide.util.treeView.TreeRunnable.TreeConsumer)1 LoadingNode (com.intellij.ui.LoadingNode)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 AsyncPromise (org.jetbrains.concurrency.AsyncPromise)1 Promise (org.jetbrains.concurrency.Promise)1