/*******************************************************************************
* Copyright (c) 2007, 2011 Association for Decentralized Information Management
* in Industry THTH ry.
* 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:
* VTT Technical Research Centre of Finland - initial API and implementation
*******************************************************************************/
package org.simantics.charts.editor;
import java.util.concurrent.atomic.AtomicInteger;
import org.simantics.databoard.annotations.Optional;
import org.simantics.db.Resource;
import org.simantics.history.Collector;
import org.simantics.history.HistoryManager;
import org.simantics.simulation.data.Datasource;
import org.simantics.simulation.experiment.IExperiment;
/**
* @author Tuukka Lehtonen
*/
public final class ChartData {
/**
* The model for which this ChartData is valid, i.e. the model that contains
* {@link #run} if {@link #run} is nonnon-null
*/
@Optional
public Resource model;
/**
* If just reading data from file system, not the database, this may be
* null
.
*/
@Optional
public Resource run;
/**
* Used for giving the chart access to the active experiment state.
*/
@Optional
public IExperiment experiment;
/**
* May be null if the chart data is not connected to a running experiment.
*/
@Optional
public Datasource datasource;
@Optional
public HistoryManager history;
/**
* Optional collector, Chart uses this to flush data right before drawing it
*/
@Optional
public Collector collector;
/**
* This (shared instance) is used to track the amount of users of this ChartData
* instance. The same instance may end up in many ChartData instances through
* {@link #readFrom(ChartData)}.
*/
public AtomicInteger refCount = new AtomicInteger();
public ChartData(Resource model, Resource run, IExperiment experiment, Datasource datasource, HistoryManager history, Collector collector) {
this.model = model;
this.run = run;
this.experiment = experiment;
this.datasource = datasource;
this.history = history;
this.collector = collector;
}
public void readFrom(ChartData other) {
if (other==null) {
this.model = null;
this.run = null;
this.experiment = null;
this.datasource = null;
this.history = null;
this.collector = null;
this.refCount = null;
} else {
this.model = other.model;
this.run = other.run;
this.experiment = other.experiment;
this.datasource = other.datasource;
this.history = other.history;
this.collector = other.collector;
this.refCount = other.refCount;
}
}
/**
* Dispose by closing history
*/
public void dispose() {
model = null;
run = null;
experiment = null;
datasource = null;
if (history != null) {
history.close();
history = null;
}
}
public int reference() {
AtomicInteger i = refCount;
if (i == null)
return 0;
int result = i.incrementAndGet();
//System.out.println(this + ": reference: " + (result-1) + " -> " + result + " (" + System.identityHashCode(refCount) + ")");
return result;
}
public int dereference() {
AtomicInteger i = refCount;
if (i == null)
return 0;
int result = i.decrementAndGet();
//System.out.println(this + ": dereference: " + (result+1) + " -> " + result + " (" + System.identityHashCode(refCount) + ")");
if (result <= 0) {
synchronized (i) {
i.notifyAll();
}
}
return result;
}
public void waitUntilNotReferenced() throws InterruptedException {
AtomicInteger i = refCount;
if (i == null)
return;
synchronized (i) {
while (i.get() > 0) {
i.wait();
}
}
}
}