blob: 4a9d11904140ba513f334bc49412ecd87db8fe5e [file] [log] [blame]
package com.intellij.xdebugger.impl.ui.tree.nodes;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.util.Alarm;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.frame.XFullValueEvaluator;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
public class HeadlessValueEvaluationCallback implements XFullValueEvaluator.XFullValueEvaluationCallback {
private final XValueNodeImpl myNode;
private volatile boolean myEvaluated;
private volatile boolean myCanceled;
private final Semaphore mySemaphore;
public HeadlessValueEvaluationCallback(@NotNull XValueNodeImpl node) {
myNode = node;
mySemaphore = new Semaphore();
mySemaphore.down();
}
public void startFetchingValue(@NotNull XFullValueEvaluator fullValueEvaluator) {
fullValueEvaluator.startEvaluation(this);
new Alarm().addRequest(new Runnable() {
@Override
public void run() {
showProgress();
}
}, 500);
}
@Override
public void evaluated(@NotNull String fullValue) {
evaluationComplete(fullValue);
}
@Override
public void evaluated(@NotNull String fullValue, @Nullable Font font) {
evaluated(fullValue);
}
@Override
public void errorOccurred(@NotNull String errorMessage) {
try {
String message = XDebuggerBundle.message("load.value.task.error", errorMessage);
XDebugSessionImpl.NOTIFICATION_GROUP.createNotification(message, NotificationType.ERROR).notify(myNode.getTree().getProject());
}
finally {
evaluationComplete(errorMessage);
}
}
private void evaluationComplete(@NotNull String value) {
try {
myEvaluated = true;
mySemaphore.up();
}
finally {
evaluationComplete(value, myNode.getTree().getProject());
}
}
protected void evaluationComplete(@NotNull String value, @NotNull Project project) {
}
@Override
public boolean isObsolete() {
return myCanceled;
}
public void showProgress() {
if (myEvaluated || myNode.isObsolete()) {
return;
}
new Task.Backgroundable(myNode.getTree().getProject(), XDebuggerBundle.message("load.value.task.text")) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
indicator.setIndeterminate(true);
int i = 0;
while (!myCanceled && !myEvaluated) {
indicator.checkCanceled();
indicator.setFraction(((i++) % 100) * 0.01);
mySemaphore.waitFor(300);
}
}
@Override
public boolean shouldStartInBackground() {
return false;
}
@Override
public void onCancel() {
myCanceled = true;
}
}.queue();
}
}