package jetbrains.mps.debugger.api.ui.tree;
/*Generated by MPS */
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.debug.api.programState.IWatchable;
import jetbrains.mps.debug.api.AbstractUiState;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.List;
import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.ArrayList;
import jetbrains.mps.debug.api.programState.Watchable2;
import jetbrains.mps.debug.api.programState.IValue;
import javax.swing.tree.DefaultTreeModel;
import com.intellij.openapi.application.ApplicationManager;
import org.apache.log4j.Level;
public class WatchableNode extends AbstractWatchableNode {
private static final Logger LOG = LogManager.getLogger(WatchableNode.class);
private volatile boolean myInitialized;
@NotNull
private final IWatchable myWatchable;
private final AbstractUiState myState;
private final AtomicBoolean myInitializationInProgress = new AtomicBoolean(false);
private final List<_FunctionTypes._void_P0_E0> myCallbacks = ListSequence.fromList(new ArrayList<_FunctionTypes._void_P0_E0>());
public WatchableNode(@NotNull IWatchable w, AbstractUiState state) {
super((w instanceof Watchable2 ? ((Watchable2) w).getSourceNode() : ((w.getNode() == null ? null : w.getNode().getReference()))));
myWatchable = w;
myState = state;
setNodeIdentifier(calculateNodeId(w));
setIcon(w.getPresentationIcon());
}
@Override
protected void doUpdate() {
this.removeAllChildren();
myInitialized = false;
}
@Override
public boolean isInitialized() {
return myInitialized;
}
private static String calculateNodeId(IWatchable watchable) {
IValue value = watchable.getValue();
if (value == null) {
return watchable.getName() + " = null";
}
return watchable.getName() + " = " + value.getValuePresentation();
}
@Override
public boolean isLeaf() {
IValue value = getValue();
return value == null || !(value.isStructure());
}
public IValue getValue() {
return myWatchable.getValue();
}
/*package*/ void nodeChanged() {
((DefaultTreeModel) getTree().getModel()).nodeStructureChanged(this);
}
@Override
protected void doInit() {
init(new _FunctionTypes._void_P0_E0() {
public void invoke() {
}
});
}
public void init(final _FunctionTypes._void_P0_E0 callback) {
if (myInitialized) {
callback.invoke();
return;
}
if (!(isLeaf())) {
if (myInitializationInProgress.compareAndSet(false, true)) {
myState.invokeEvaluation(new _FunctionTypes._void_P0_E0() {
public void invoke() {
try {
myWatchable.getValue().initSubvalues();
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
try {
removeAllChildren();
for (IWatchable watchable : ListSequence.fromList(getValue().getSubvalues())) {
add(new WatchableNode(watchable, myState));
}
updatePresentation();
myInitialized = true;
callback.invoke();
for (_FunctionTypes._void_P0_E0 callback : ListSequence.fromList(myCallbacks)) {
try {
callback.invoke();
} catch (Throwable t) {
if (LOG.isEnabledFor(Level.ERROR)) {
LOG.error("", t);
}
}
}
ListSequence.fromList(myCallbacks).clear();
nodeChanged();
} finally {
myInitializationInProgress.set(false);
}
}
});
} catch (Throwable t) {
myInitializationInProgress.set(false);
}
}
});
} else {
// callbacks are accessed from ui thread only
ListSequence.fromList(myCallbacks).addElement(callback);
}
}
}
}