# HG changeset patch # User Hasan Yavuz ÖZDERYA # Date 2018-02-23 16:12:22 # Node ID 391ab62116c8cdc7937ccf931ed9ce75282cc967 # Parent b29ee53957530139da5ae77b710865f090c9da16 progress on unfinished stream class diff --git a/src/samplepack.h b/src/samplepack.h --- a/src/samplepack.h +++ b/src/samplepack.h @@ -1,5 +1,5 @@ /* - Copyright © 2017 Hasan Yavuz Özderya + Copyright © 2018 Hasan Yavuz Özderya This file is part of serialplot. diff --git a/src/sink.cpp b/src/sink.cpp --- a/src/sink.cpp +++ b/src/sink.cpp @@ -1,5 +1,5 @@ /* - Copyright © 2017 Hasan Yavuz Özderya + Copyright © 2018 Hasan Yavuz Özderya This file is part of serialplot. @@ -25,7 +25,7 @@ void Sink::connectFollower(Sink* sink) Q_ASSERT(!followers.contains(sink)); followers.append(sink); - sink->setNumChannels(numChannels(), hasX()); + sink->setNumChannels(_numChannels, _hasX); } void Sink::disconnectFollower(Sink* sink) @@ -45,6 +45,8 @@ void Sink::feedIn(const SamplePack& data void Sink::setNumChannels(unsigned nc, bool x) { + _numChannels = nc; + _hasX = x; for (auto sink : followers) { sink->setNumChannels(nc, x); diff --git a/src/sink.h b/src/sink.h --- a/src/sink.h +++ b/src/sink.h @@ -1,5 +1,5 @@ /* - Copyright © 2017 Hasan Yavuz Özderya + Copyright © 2018 Hasan Yavuz Özderya This file is part of serialplot. @@ -28,6 +28,8 @@ class Source; class Sink { public: + /// Placeholder virtual destructor + virtual ~Sink() {}; /// Connects a sink to get any data that this sink /// gets. Connecting an already connected sink is an error. void connectFollower(Sink* sink); @@ -44,10 +46,6 @@ protected: /// Is set by connected source. Re-implementations should call /// this function to update followers. virtual void setNumChannels(unsigned nc, bool x); - /// Returns true if sink has X data - virtual bool hasX() const = 0; - /// Returns number of channels - virtual unsigned numChannels() const = 0; /// Set by the connected source when its connected. When /// disconnecting it's set to `NULL`. /// @@ -60,6 +58,8 @@ protected: private: QList followers; const Source* source = NULL; ///< source that this sink is connected to + bool _hasX; + unsigned _numChannels; }; #endif // SINK_H diff --git a/src/source.h b/src/source.h --- a/src/source.h +++ b/src/source.h @@ -1,5 +1,5 @@ /* - Copyright © 2017 Hasan Yavuz Özderya + Copyright © 2018 Hasan Yavuz Özderya This file is part of serialplot. @@ -28,7 +28,11 @@ class Source { public: + /// Placeholder virtual destructor + virtual ~Source() {}; + /// Returns true if source has X data virtual bool hasX() const = 0; + /// Returns number of channels virtual unsigned numChannels() const = 0; /// Connects a sink to this source. Trying to connect an already diff --git a/src/stream.cpp b/src/stream.cpp new file mode 100644 --- /dev/null +++ b/src/stream.cpp @@ -0,0 +1,171 @@ +/* + 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" + +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() +{ + // notify deletion + // delete channels +} + +bool Stream::hasX() const +{ + return _hasx; +} + +unsigned Stream::numChannels() +{ + return channels.length(); +} + +unsigned Stream::numSamples() const +{ + return _numSamples; +} + +const StreamChannel* Stream::channel(unsigned index) const +{ + Q_ASSERT(index < numChannels()); + return channels[index]; +} + +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 (int i = oldNum; i < nc; i++) + { + auto c = new StreamChannel(i, xData, new RingBuffer(ns), &_infoModel); + channels.append(c); + } + } + else if (nc < oldNum) + { + for (int i = oldNum-1; i > nc-1; i--) + { + delete channels.takeLast(); + } + } + + // change the xdata + if (x != _hasX) + { + if (x) + { + xData = new RingBuffer(ns); + } + else + { + xData = new IndexBuffer(ns); + } + + for (auto c : channels) + { + c.setX(xData); + } + _hasX = x; + } + + if (nc != oldNum) + { + _infoModel.setNumChannels(nc); + // TODO: how abut X change? + emit numOfChannelsChanged(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) + { + xData.addSamples(data.xData(), ns); + } + for (unsigned i = 0; i < numChannels(); i++) + { + channels[i].yData()->addSamples(data.data(i), ns); + } + + Sink::feedIn(data); +} + +void Stream::pause(bool paused) +{ + _paused = paused; +} + +void Stream::setNumSamples(unsigned value) +{ + if (value == _numSamples) return; + _numSamples = value; + + xData.resize(value); + for (auto c : channels) + { + channels[i].yData()->resize(value); + } +} + +void Stream::saveSettings(QSettings* settings) const +{ + _infoModel.saveSettings(settings); +} + +void Stream::loadSettings(QSettings* settings) +{ + _infoModel.loadSettings(settings); +} diff --git a/src/stream.h b/src/stream.h --- a/src/stream.h +++ b/src/stream.h @@ -1,5 +1,5 @@ /* - Copyright © 2017 Hasan Yavuz Özderya + Copyright © 2018 Hasan Yavuz Özderya This file is part of serialplot. @@ -29,6 +29,7 @@ #include "source.h" #include "channelinfomodel.h" #include "streamchannel.h" +#include "resizablebuffer.h" /** * Main waveform storage class. It consists of channels. Channels are @@ -38,30 +39,33 @@ * connected to a `Device` source. Also implements a `Source` class * for data that exists the buffers. */ -class Stream : public Sink, public Source, public QObject +class Stream : public Sink, public QObject { public: /** * @param nc number of channels * @param ns number of samples */ - Stream(unsigned ns); + Stream(unsigned nc = 0, bool x = false, unsigned ns = 0); ~Stream(); // implementations for `Source` virtual bool hasX() const; virtual unsigned numChannels(); - // implementations for `Sink` - virtual void setNumChannels(unsigned nc, bool x); - unsigned numSamples() const; const StreamChannel* channel(unsigned index) const; + /// Saves channel information void saveSettings(QSettings* settings) const; /// Load channel information void loadSettings(QSettings* settings); +protected: + // implementations for `Sink` + virtual void setNumChannels(unsigned nc, bool x); + virtual void feedIn(const SamplePack& data); + signals: void numChannelsChanged(unsigned value); void numSamplesChanged(unsigned value); @@ -72,10 +76,20 @@ signals: public slots: // TODO: these won't be public void setNumChannels(unsigned number); - void setNumSamples(unsigned number); + void setNumSamples(unsigned value); + + /// When paused data feed is ignored + void pause(bool paused); - /// When paused `addData` does nothing. - void pause(bool paused); +private: + unsigned _numSamples; + bool _paused; + + bool _hasx; + ResizableBuffer* xData; + QList channels; + + ChannelInfoModel _infoModel; }; diff --git a/src/streamchannel.cpp b/src/streamchannel.cpp --- a/src/streamchannel.cpp +++ b/src/streamchannel.cpp @@ -1,5 +1,5 @@ /* - Copyright © 2017 Hasan Yavuz Özderya + Copyright © 2018 Hasan Yavuz Özderya This file is part of serialplot. @@ -41,3 +41,4 @@ const FrameBuffer* StreamChannel::xData( const FrameBuffer* StreamChannel::yData() const {return _y;} FrameBuffer* StreamChannel::yData() {return _y;} const ChannelInfoModel* StreamChannel::info() const {return _info;} +void StreamChannel::setX(const FrameBuffer* x) {_x = x}; diff --git a/src/streamchannel.h b/src/streamchannel.h --- a/src/streamchannel.h +++ b/src/streamchannel.h @@ -1,5 +1,5 @@ /* - Copyright © 2017 Hasan Yavuz Özderya + Copyright © 2018 Hasan Yavuz Özderya This file is part of serialplot. @@ -50,7 +50,7 @@ public: FrameBuffer* yData(); const FrameBuffer* yData() const; const ChannelInfoModel* info() const; - + void setX(const FrameBuffer* x); private: unsigned _index;