/*
Copyright © 2018 Hasan Yavuz Özderya
This file is part of serialplot.
serialplot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
serialplot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with serialplot. If not, see .
*/
#include "stream.h"
#include "ringbuffer.h"
#include "indexbuffer.h"
Stream::Stream(unsigned nc, bool x, unsigned ns) :
_infoModel(nc)
{
_numSamples = ns;
_paused = false;
// create xdata buffer
_hasx = x;
if (x)
{
xData = new RingBuffer(ns);
}
else
{
xData = new IndexBuffer(ns);
}
// create channels
for (unsigned i = 0; i < nc; i++)
{
auto c = new StreamChannel(i, xData, new RingBuffer(ns), &_infoModel);
channels.append(c);
}
}
Stream::~Stream()
{
// TODO: notify deletion
// TODO: delete channels
}
bool Stream::hasX() const
{
return _hasx;
}
unsigned Stream::numChannels() const
{
return channels.length();
}
unsigned Stream::numSamples() const
{
return _numSamples;
}
const StreamChannel* Stream::channel(unsigned index) const
{
Q_ASSERT(index < numChannels());
return channels[index];
}
StreamChannel* Stream::channel(unsigned index)
{
return const_cast(static_cast(*this).channel(index));
}
const ChannelInfoModel* Stream::infoModel() const
{
return &_infoModel;
}
ChannelInfoModel* Stream::infoModel()
{
return const_cast(static_cast(*this).infoModel());
}
void Stream::setNumChannels(unsigned nc, bool x)
{
unsigned oldNum = numChannels();
if (oldNum == nc && x == _hasx) return;
// adjust the number of channels
if (nc > oldNum)
{
for (unsigned i = oldNum; i < nc; i++)
{
auto c = new StreamChannel(i, xData, new RingBuffer(_numSamples), &_infoModel);
channels.append(c);
}
}
else if (nc < oldNum)
{
for (unsigned i = oldNum-1; i > nc-1; i--)
{
delete channels.takeLast();
}
}
// change the xdata
if (x != _hasx)
{
if (x)
{
xData = new RingBuffer(_numSamples);
}
else
{
xData = new IndexBuffer(_numSamples);
}
for (auto c : channels)
{
c->setX(xData);
}
_hasx = x;
}
if (nc != oldNum)
{
_infoModel.setNumOfChannels(nc);
// TODO: how abut X change?
emit numChannelsChanged(nc);
}
Sink::setNumChannels(nc, x);
}
void Stream::feedIn(const SamplePack& data)
{
Q_ASSERT(data.numChannels() == numChannels() &&
data.hasX() == hasX());
if (_paused) return;
unsigned ns = data.numSamples();
if (_hasx)
{
static_cast(xData)->addSamples(data.xData(), ns);
}
for (unsigned i = 0; i < numChannels(); i++)
{
static_cast(channels[i]->yData())->addSamples(data.data(i), ns);
}
Sink::feedIn(data);
emit dataAdded();
}
void Stream::pause(bool paused)
{
_paused = paused;
}
void Stream::clear()
{
for (auto c : channels)
{
static_cast(c->yData())->clear();
}
}
void Stream::setNumSamples(unsigned value)
{
if (value == _numSamples) return;
_numSamples = value;
xData->resize(value);
for (auto c : channels)
{
static_cast(c->yData())->resize(value);
}
}
void Stream::saveSettings(QSettings* settings) const
{
_infoModel.saveSettings(settings);
}
void Stream::loadSettings(QSettings* settings)
{
_infoModel.loadSettings(settings);
}