blob: 3091fb3d79e4117ba3e8b74d1d79c6b53314d656 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2010, 2019 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.internal.r.debug.core.model;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.Status;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.status.Statuses;
import org.eclipse.statet.r.core.data.CombinedRElement;
import org.eclipse.statet.r.debug.core.IRVariable;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.UnexpectedRDataException;
import org.eclipse.statet.rj.services.FQRObjectRef;
import org.eclipse.statet.rj.services.util.dataaccess.LazyRStore;
import org.eclipse.statet.rj.services.util.dataaccess.LazyRStore.Fragment;
import org.eclipse.statet.rj.services.util.dataaccess.RDataAssignment;
import org.eclipse.statet.rj.ts.core.RToolService;
@NonNullByDefault
public class RElementVariableValue<TRElement extends CombinedRElement> extends RElementValue<TRElement> {
protected abstract class RDataLoader<V extends RObject> implements LazyRStore.Updater<V> {
private @Nullable FQRObjectRef ref;
public RDataLoader() {
}
@Override
public void scheduleUpdate(final LazyRStore<V> store,
final @Nullable RDataAssignment assignment, final @Nullable Fragment<V> fragment,
final int flags, final ProgressMonitor m) {
final AtomicReference<Status> set= new AtomicReference<>();
V data= null;
try {
final RMainThread thread= RElementVariableValue.this.variable.getThread();
data= thread.loadData(thread.new AccessDataRunnable<V>() {
@Override
protected int getRequiredStamp() {
return RElementVariableValue.this.stamp;
}
private @Nullable FQRObjectRef getRef(final ProgressMonitor m) {
if (RDataLoader.this.ref == null) {
RDataLoader.this.ref= getThread().createElementRef(
RElementVariableValue.this.element, getRequiredStamp(),
m );
}
return RDataLoader.this.ref;
}
@Override
protected V doRun(final RToolService r, final ProgressMonitor m)
throws StatusException, UnexpectedRDataException {
final FQRObjectRef ref= getRef(m);
if (ref == null) {
return null;
}
if (assignment != null) {
RDataLoader.this.doSet(ref, assignment, r, m);
set.set(Statuses.OK_STATUS);
}
if (fragment != null) {
return RDataLoader.this.doLoad(ref,
fragment, r, m);
}
else {
return null;
}
}
});
}
finally {
if (assignment != null) {
store.updateAssignment(assignment, set.get());
}
if (fragment != null) {
store.updateFragment(fragment, data);
}
}
}
protected void doSet(final FQRObjectRef ref,
final RDataAssignment assignment,
final RToolService r, final ProgressMonitor m) throws StatusException, UnexpectedRDataException {
throw new UnsupportedOperationException();
}
protected abstract V doLoad(FQRObjectRef ref,
Fragment<V> fragment,
RToolService r, ProgressMonitor m) throws StatusException, UnexpectedRDataException;
}
protected final RElementVariable variable;
public RElementVariableValue(final RElementVariable variable) {
super(variable.getDebugTarget(),
(TRElement) variable.getCurrentElement(), variable.getCurrentStamp());
this.variable= variable;
}
@Override
public IRVariable getAssignedVariable() {
return this.variable;
}
}