/****************************************************************************** * This file is protected by Copyright. * Please refer to the COPYRIGHT file distributed with this source distribution. * * This file is part of REDHAWK IDE. * * 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 *******************************************************************************/ package gov.redhawk.datalist.ui.internal; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.annotation.NonNull; import BULKIO.PrecisionUTCTime; import BULKIO.StreamSRI; import gov.redhawk.bulkio.util.AbstractUberBulkIOPort; import gov.redhawk.bulkio.util.BulkIOType; import gov.redhawk.bulkio.util.BulkIOUtilActivator; import gov.redhawk.datalist.ui.DataCollectionSettings; import gov.redhawk.datalist.ui.DataListPlugin; import gov.redhawk.datalist.ui.Sample; import gov.redhawk.datalist.ui.views.OptionsComposite.CaptureMethod; import gov.redhawk.model.sca.ScaUsesPort; public class DataBuffer extends AbstractUberBulkIOPort { private final List<Sample> dataBuffer = new LinkedList<Sample>(); private int dimension = 1; private final ScaUsesPort port; private final ListenerList<IDataBufferListener> listeners = new ListenerList<IDataBufferListener>(); private List<Object> cached; private final Job disconnectJob = new Job("Disconnecting...") { @Override protected IStatus run(final IProgressMonitor monitor) { BulkIOType type2 = getBulkIOType(); String ior2 = port.getIor(); if (type2 != null && ior2 != null) { BulkIOUtilActivator.getBulkIOPortConnectionManager().disconnect(ior2, type2, DataBuffer.this); } return Status.OK_STATUS; } }; private final Job connectJob = new Job("Connecting...") { @Override protected IStatus run(final IProgressMonitor monitor) { try { BulkIOType type2 = getBulkIOType(); String ior2 = port.getIor(); if (type2 != null && ior2 != null) { BulkIOUtilActivator.getBulkIOPortConnectionManager().connect(ior2, type2, DataBuffer.this); } } catch (CoreException e) { return new Status(e.getStatus().getSeverity(), DataListPlugin.PLUGIN_ID, "Failed to connect port.", e); } // converting to seconds (double) DataBuffer.this.initialTime = ((double) System.currentTimeMillis()) / 1000; return Status.OK_STATUS; } }; private int samples; private int index; private double initialTime; private double currentTimeDuration; private double currentSampleDelta; private double totalTime; private CaptureMethod captureMethod; private DataCollectionSettings settings; private boolean connected = false; public DataBuffer(@NonNull ScaUsesPort port, @NonNull BulkIOType type) { super(type); this.port = port; } public void addDataBufferListener(final IDataBufferListener listener) { this.listeners.add(listener); } public void removeDataBufferListener(final IDataBufferListener listener) { this.listeners.remove(listener); } protected void fireDataBufferChanged() { for (final Object listener : listeners.getListeners()) { ((IDataBufferListener) listener).dataBufferChanged(this); } } protected void fireDataBufferComplete() { for (final Object listener : listeners.getListeners()) { ((IDataBufferListener) listener).dataBufferComplete(this); } } public ScaUsesPort getPort() { return this.port; } public void acquire(final DataCollectionSettings settings) { if (connected) { return; } connected = true; clear(); this.setDimension(settings.getDimensions()); CaptureMethod method = settings.getProcessType(); this.currentSampleDelta = 1; switch (method) { case NUMBER: this.samples = (int) settings.getSamples(); this.totalTime = samples * this.currentSampleDelta; break; case SAMPLE_TIME: this.totalTime = settings.getSamples(); this.samples = (int) (this.totalTime / this.currentSampleDelta + .5); break; case INDEFINITELY: this.totalTime = 0; this.samples = 0; break; case CLOCK_TIME: this.totalTime = settings.getSamples(); this.samples = 0; break; default: throw new IllegalArgumentException("Unsupported Capture Type"); } this.captureMethod = method; this.settings = settings; this.connectJob.schedule(); } public void dispose() { disconnect(); this.listeners.clear(); } public void clear() { this.index = 0; this.currentTimeDuration = 0; this.totalTime = 0; this.dataBuffer.clear(); if (this.cached != null) { this.cached.clear(); this.cached = null; } fireDataBufferChanged(); } public void setDimension(final int dimension) { this.dimension = dimension; } /* * @see gov.redhawk.bulkio.util.AbstractBulkIOPort#handleStreamSRIChanged(java.lang.String, BULKIO.StreamSRI, BULKIO.StreamSRI) */ @Override protected void handleStreamSRIChanged(String streamID, StreamSRI oldSri, StreamSRI newSri) { super.handleStreamSRIChanged(streamID, oldSri, newSri); if (samples > index && newSri != null) { if (this.captureMethod == CaptureMethod.SAMPLE_TIME) { this.currentSampleDelta = (newSri.xdelta != 0) ? newSri.xdelta : 1; samples = ((int) (((this.totalTime - this.currentTimeDuration) / currentSampleDelta) + .5)) + this.index; } } } public void pushPacket(final Object data, final PrecisionUTCTime time, final boolean eos, final String streamID) { if (!connected) { return; } final int length = Array.getLength(data); super.pushPacket(length, time, eos, streamID); // converting from milliseconds to seconds (double) double t = ((double) System.currentTimeMillis()) / 1000; for (int i = 0; i < length; i++) { if (reachedLimit(t) || eos) { disconnect(); break; } if (this.dimension == 1) { this.dataBuffer.add(new Sample(time, this.index++, Array.get(data, i))); } else { List<Object> sampleList = new ArrayList<Object>(); if (cached != null) { sampleList.addAll(cached); cached.clear(); cached = null; } while (i < length) { if (Array.get(data, i) != null) { sampleList.add(Array.get(data, i)); } if (sampleList.size() >= this.dimension) { break; } i++; } if (sampleList.size() == this.dimension) { this.dataBuffer.add(new Sample(time, this.index++, sampleList.toArray())); } else { cached = sampleList; } } } fireDataBufferChanged(); } private boolean reachedLimit(double currentTime) { switch (captureMethod) { case NUMBER: return (this.index >= this.samples); case SAMPLE_TIME: return (this.index >= this.samples); case CLOCK_TIME: currentTimeDuration = currentTime - initialTime; return (this.currentTimeDuration >= this.totalTime); case INDEFINITELY: return false; default: return false; } } private DataCollectionSettings saveSettings() { if (captureMethod != null) { switch (captureMethod) { case NUMBER: return settings; default: settings.setSamples((double) samples); return settings; } } return null; } public void disconnect() { if (!connected) { return; } connected = false; saveSettings(); this.disconnectJob.schedule(); fireDataBufferComplete(); } public List<Sample> getBuffer() { return Collections.unmodifiableList(dataBuffer); } @Override public void pushPacket(short[] data, PrecisionUTCTime time, boolean eos, String streamID) { pushPacket((Object) data, time, eos, streamID); } @Override public void pushPacket(byte[] data, PrecisionUTCTime time, boolean eos, String streamID) { pushPacket((Object) data, time, eos, streamID); } @Override public void pushPacket(int[] data, PrecisionUTCTime time, boolean eos, String streamID) { pushPacket((Object) data, time, eos, streamID); } @Override public void pushPacket(char[] data, PrecisionUTCTime time, boolean eos, String streamID) { pushPacket((Object) data, time, eos, streamID); } @Override public void pushPacket(long[] data, PrecisionUTCTime time, boolean eos, String streamID) { pushPacket((Object) data, time, eos, streamID); } @Override public void pushPacket(float[] data, PrecisionUTCTime time, boolean eos, String streamID) { pushPacket((Object) data, time, eos, streamID); } @Override public void pushPacket(double[] data, PrecisionUTCTime time, boolean eos, String streamID) { pushPacket((Object) data, time, eos, streamID); } public int getDimension() { return dimension; } public int size() { return dataBuffer.size(); } }