/******************************************************************************* * 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(); } } } }