From 7f5875aeee4665364ec68d24afb263a2df836745 Mon Sep 17 00:00:00 2001 From: saker Date: Sun, 2 Feb 2025 20:10:57 -0500 Subject: [PATCH] Manage ownership of clips using std::unique_ptr's --- include/AutomationTrack.h | 3 +- include/InstrumentTrack.h | 4 +- include/PatternTrack.h | 3 +- include/SampleTrack.h | 3 +- include/Track.h | 35 +++------------- plugins/MidiImport/MidiImport.cpp | 14 +++---- src/core/AutomationClip.cpp | 4 +- src/core/Clip.cpp | 5 --- src/core/Song.cpp | 4 +- src/core/Track.cpp | 52 +++++++++++++----------- src/core/TrackContainer.cpp | 4 +- src/gui/FileBrowser.cpp | 2 +- src/gui/clips/ClipView.cpp | 2 +- src/gui/clips/SampleClipView.cpp | 2 +- src/gui/tracks/AutomationTrackView.cpp | 2 +- src/gui/tracks/SampleTrackView.cpp | 2 +- src/gui/tracks/TrackView.cpp | 2 +- src/tracks/AutomationTrack.cpp | 11 +---- src/tracks/InstrumentTrack.cpp | 23 +++-------- src/tracks/MidiClip.cpp | 2 +- src/tracks/PatternTrack.cpp | 14 ++----- src/tracks/SampleTrack.cpp | 18 ++------ tests/src/tracks/AutomationTrackTest.cpp | 16 ++++---- 23 files changed, 80 insertions(+), 147 deletions(-) diff --git a/include/AutomationTrack.h b/include/AutomationTrack.h index 705ec621348..8a18759c0f7 100644 --- a/include/AutomationTrack.h +++ b/include/AutomationTrack.h @@ -48,8 +48,7 @@ class LMMS_EXPORT AutomationTrack : public Track } gui::TrackView * createView( gui::TrackContainerView* ) override; - Clip* createClip() override; - bool canAddClip(Clip* clip) override; + std::unique_ptr createClip() override; void saveTrackSpecificSettings(QDomDocument& doc, QDomElement& parent, bool presetMode) override; void loadTrackSpecificSettings( const QDomElement & _this ) override; diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index 5caad67bdee..d33e673375b 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -129,9 +129,7 @@ class LMMS_EXPORT InstrumentTrack : public Track, public MidiEventProcessor gui::TrackView* createView( gui::TrackContainerView* tcv ) override; // create new track-content-object = clip - Clip* createClip() override; - - bool canAddClip(Clip* clip) override; + std::unique_ptr createClip() override; // called by track void saveTrackSpecificSettings(QDomDocument& doc, QDomElement& parent, bool presetMode) override; diff --git a/include/PatternTrack.h b/include/PatternTrack.h index a05c25764a7..76a87a62130 100644 --- a/include/PatternTrack.h +++ b/include/PatternTrack.h @@ -55,8 +55,7 @@ class LMMS_EXPORT PatternTrack : public Track const f_cnt_t _frame_base, int _clip_num = -1 ) override; gui::TrackView * createView( gui::TrackContainerView* tcv ) override; - Clip* createClip() override; - bool canAddClip(Clip* clip) override; + std::unique_ptr createClip() override; void saveTrackSpecificSettings(QDomDocument& doc, QDomElement& parent, bool presetMode) override; void loadTrackSpecificSettings( const QDomElement & _this ) override; diff --git a/include/SampleTrack.h b/include/SampleTrack.h index 0d80f5eeb9e..5de11c9b60e 100644 --- a/include/SampleTrack.h +++ b/include/SampleTrack.h @@ -51,8 +51,7 @@ class LMMS_EXPORT SampleTrack : public Track bool play( const TimePos & _start, const fpp_t _frames, const f_cnt_t _frame_base, int _clip_num = -1 ) override; gui::TrackView * createView( gui::TrackContainerView* tcv ) override; - Clip* createClip() override; - bool canAddClip(Clip* clip) override; + std::unique_ptr createClip() override; void saveTrackSpecificSettings(QDomDocument& doc, QDomElement& parent, bool presetMode) override; void loadTrackSpecificSettings( const QDomElement & _this ) override; diff --git a/include/Track.h b/include/Track.h index 2aa8d35a136..563e5525d25 100644 --- a/include/Track.h +++ b/include/Track.h @@ -72,8 +72,6 @@ class LMMS_EXPORT Track : public Model, public JournallingObject mapPropertyFromModel(bool,isMuted,setMuted,m_mutedModel); mapPropertyFromModel(bool,isSolo,setSolo,m_soloModel); public: - using clipVector = std::vector; - enum class Type { Instrument, @@ -100,12 +98,8 @@ class LMMS_EXPORT Track : public Model, public JournallingObject virtual bool play( const TimePos & start, const fpp_t frames, const f_cnt_t frameBase, int clipNum = -1 ) = 0; - - virtual gui::TrackView * createView( gui::TrackContainerView * view ) = 0; - virtual Clip* createClip() = 0; - virtual bool canAddClip(Clip* clip) = 0; - + virtual std::unique_ptr createClip() = 0; virtual void saveTrackSpecificSettings(QDomDocument& doc, QDomElement& parent, bool presetMode) = 0; virtual void loadTrackSpecificSettings( const QDomElement & element ) = 0; @@ -117,22 +111,7 @@ class LMMS_EXPORT Track : public Model, public JournallingObject void saveSettings( QDomDocument & doc, QDomElement & element ) override; void loadSettings( const QDomElement & element ) override; - template - T* addClip(Args&&... args) - { - static_assert(std::is_base_of_v, "T must be a kind of Clip"); - const auto guard = Engine::audioEngine()->requestChangesGuard(); - - auto clip = new T(std::forward(args)...); - assert(canAddClip(clip) && "This clip cannot be added to this track (incompatible types?)"); - - m_clips.push_back(clip); - clip->setTrack(this); - clip->onAddedToTrack(this); - emit clipAdded(clip); - return clip; - } - + Clip* addClip(std::unique_ptr clip); void removeClip(Clip* clip); void deleteClips(); @@ -140,12 +119,8 @@ class LMMS_EXPORT Track : public Model, public JournallingObject auto getClip(std::size_t clipNum) -> Clip*; int getClipNum(const Clip* clip ); - const clipVector & getClips() const - { - return m_clips; - } - void getClipsInRange( clipVector & clipV, const TimePos & start, - const TimePos & end ); + std::vector getClips() const; + std::vector getClipsInRange(const TimePos& start, const TimePos& end); void swapPositionOfClips( int clipNum1, int clipNum2 ); void createClipsForPattern(int pattern); @@ -238,7 +213,7 @@ public slots: BoolModel m_soloModel; bool m_mutedBeforeSolo; - clipVector m_clips; + std::vector> m_clips; QMutex m_processingLock; diff --git a/plugins/MidiImport/MidiImport.cpp b/plugins/MidiImport/MidiImport.cpp index f1443eebc81..a9724e997ea 100644 --- a/plugins/MidiImport/MidiImport.cpp +++ b/plugins/MidiImport/MidiImport.cpp @@ -187,7 +187,7 @@ class smfMidiCC if( !ap || time > lastPos + DefaultTicksPerBar ) { TimePos pPos = TimePos( time.getBar(), 0 ); - ap = static_cast(at->createClip()); + ap = static_cast(at->addClip(at->createClip())); ap->movePosition(pPos); ap->addObject(objModel); } @@ -254,7 +254,7 @@ class smfMidiChannel it->pitchRangeModel()->setInitValue( 2 ); // Create a default pattern - p = static_cast(it->createClip()); + p = static_cast(it->addClip(it->createClip())); } return this; } @@ -264,7 +264,7 @@ class smfMidiChannel { if (!p) { - p = static_cast(it->createClip()); + p = static_cast(it->addClip(it->createClip())); } p->addNote(n, false); hasNotes = true; @@ -281,7 +281,7 @@ class smfMidiChannel if (!newMidiClip || n->pos() > lastEnd + DefaultTicksPerBar) { TimePos pPos = TimePos(n->pos().getBar(), 0); - newMidiClip = static_cast(it->createClip()); + newMidiClip = static_cast(it->addClip(it->createClip())); newMidiClip->movePosition(pPos); } lastEnd = n->pos() + n->length(); @@ -335,10 +335,10 @@ bool MidiImport::readSMF( TrackContainer* tc ) auto dt = Engine::getSong()->addTrack(); dt->setName(tr("MIDI Time Signature Denominator")); - auto timeSigNumeratorPat = static_cast(nt->createClip()); + auto timeSigNumeratorPat = static_cast(nt->addClip(nt->createClip())); timeSigNumeratorPat->setDisplayName(tr("Numerator")); timeSigNumeratorPat->addObject(&timeSigMM.numeratorModel()); - auto timeSigDenominatorPat = static_cast(dt->createClip()); + auto timeSigDenominatorPat = static_cast(dt->addClip(dt->createClip())); timeSigDenominatorPat->setDisplayName(tr("Denominator")); timeSigDenominatorPat->addObject(&timeSigMM.denominatorModel()); @@ -363,7 +363,7 @@ bool MidiImport::readSMF( TrackContainer* tc ) // Tempo stuff auto tt = Engine::getSong()->addTrack(); tt->setName(tr("Tempo")); - auto tap = static_cast(tt->createClip()); + auto tap = static_cast(tt->addClip(tt->createClip())); tap->setDisplayName(tr("Tempo")); tap->addObject(&Engine::getSong()->tempoModel()); if( tap ) diff --git a/src/core/AutomationClip.cpp b/src/core/AutomationClip.cpp index d3a975e89f8..99289407c3c 100644 --- a/src/core/AutomationClip.cpp +++ b/src/core/AutomationClip.cpp @@ -1029,8 +1029,8 @@ AutomationClip * AutomationClip::globalAutomationClip( } } - auto a = static_cast(t->createClip()); - a->addObject( _m, false ); + auto a = static_cast(t->addClip(t->createClip())); + a->addObject(_m, false); return a; } diff --git a/src/core/Clip.cpp b/src/core/Clip.cpp index e1dc4497676..7766e8ecfa7 100644 --- a/src/core/Clip.cpp +++ b/src/core/Clip.cpp @@ -60,11 +60,6 @@ Clip::Clip() : Clip::~Clip() { emit destroyedClip(); - - if( getTrack() ) - { - getTrack()->removeClip( this ); - } } diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 5ca9ab8871d..858553d3aa6 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -381,11 +381,11 @@ void Song::processAutomations(const TrackList &tracklist, TimePos timeStart, fpp values = container->automatedValuesAt(timeStart, clipNum); const TrackList& tracks = container->tracks(); - Track::clipVector clips; + auto clips = std::vector{}; for (Track* track : tracks) { if (track->type() == Track::Type::Automation) { - track->getClipsInRange(clips, 0, timeStart); + clips = track->getClipsInRange(0, timeStart); } } diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 10654e882f2..cb7ffa69e79 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -79,12 +79,6 @@ Track::~Track() { lock(); emit destroyedTrack(); - - while (!m_clips.empty()) - { - delete m_clips.back(); - } - m_trackContainer->removeTrack( this ); unlock(); } @@ -262,13 +256,23 @@ void Track::loadSettings(const QDomElement& element) loadTrack(element, false); } +Clip* Track::addClip(std::unique_ptr clip) +{ + m_clips.emplace_back(std::move(clip)); + m_clips.back()->setTrack(this); + m_clips.back()->onAddedToTrack(this); + emit clipAdded(m_clips.back().get()); + return m_clips.back().get(); +} + /*! \brief Remove a given Clip from this track * * \param clip The Clip to remove from this track. */ void Track::removeClip( Clip * clip ) { - clipVector::iterator it = std::find( m_clips.begin(), m_clips.end(), clip ); + const auto it = std::find_if(m_clips.begin(), m_clips.end(), [&](auto& x) { return x.get() == clip; }); + if( it != m_clips.end() ) { m_clips.erase( it ); @@ -284,10 +288,7 @@ void Track::removeClip( Clip * clip ) /*! \brief Remove all Clips from this track */ void Track::deleteClips() { - while (!m_clips.empty()) - { - delete m_clips.front(); - } + m_clips.clear(); } @@ -319,14 +320,14 @@ auto Track::getClip(std::size_t clipNum) -> Clip* { if( clipNum < m_clips.size() ) { - return m_clips[clipNum]; + return m_clips[clipNum].get(); } printf( "called Track::getClip( %zu ), " "but Clip %zu doesn't exist\n", clipNum, clipNum ); auto clip = createClip(); clip->movePosition(clipNum * TimePos::ticksPerBar()); - return clip; + return addClip(std::move(clip)); } @@ -340,7 +341,7 @@ auto Track::getClip(std::size_t clipNum) -> Clip* int Track::getClipNum( const Clip * clip ) { // for( int i = 0; i < getTrackContentWidget()->numOfClips(); ++i ) - clipVector::iterator it = std::find( m_clips.begin(), m_clips.end(), clip ); + const auto it = std::find_if(m_clips.begin(), m_clips.end(), [&](auto& x) { return x.get() == clip; }); if( it != m_clips.end() ) { /* if( getClip( i ) == _clip ) @@ -353,8 +354,12 @@ int Track::getClipNum( const Clip * clip ) return 0; } - - +std::vector Track::getClips() const +{ + auto clips = std::vector(m_clips.size()); + std::transform(m_clips.begin(), m_clips.end(), clips.begin(), [](auto& x) { return x.get(); }); + return clips; +} /*! \brief Retrieve a list of clips that fall within a period. * @@ -367,21 +372,22 @@ int Track::getClipNum( const Clip * clip ) * \param start The MIDI start time of the range. * \param end The MIDI endi time of the range. */ -void Track::getClipsInRange( clipVector & clipV, const TimePos & start, - const TimePos & end ) +std::vector Track::getClipsInRange(const TimePos& start, const TimePos& end) { - for( Clip* clip : m_clips ) + auto clips = std::vector(); + + for (auto& clip : m_clips) { int s = clip->startPosition(); int e = clip->endPosition(); if( ( s <= end ) && ( e >= start ) ) { - // Clip is within given range - // Insert sorted by Clip's position - clipV.insert(std::upper_bound(clipV.begin(), clipV.end(), clip, Clip::comparePosition), - clip); + clips.push_back(clip.get()); } } + + std::sort(clips.begin(), clips.end(), Clip::comparePosition); + return clips; } diff --git a/src/core/TrackContainer.cpp b/src/core/TrackContainer.cpp index 17b3894e8f1..060560ecd44 100644 --- a/src/core/TrackContainer.cpp +++ b/src/core/TrackContainer.cpp @@ -273,7 +273,7 @@ AutomatedValueMap TrackContainer::automatedValuesAt(TimePos time, int clipNum) c AutomatedValueMap TrackContainer::automatedValuesFromTracks(const TrackList &tracks, TimePos time, int clipNum) { - Track::clipVector clips; + auto clips = std::vector{}; for (Track* track: tracks) { @@ -287,7 +287,7 @@ AutomatedValueMap TrackContainer::automatedValuesFromTracks(const TrackList &tra case Track::Type::HiddenAutomation: case Track::Type::Pattern: if (clipNum < 0) { - track->getClipsInRange(clips, 0, time); + clips = track->getClipsInRange(0, time); } else { Q_ASSERT(track->numOfClips() > clipNum); clips.push_back(track->getClip(clipNum)); diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 06a2ef66c24..3c7cfa3580e 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -982,7 +982,7 @@ bool FileBrowserTreeWidget::openInNewSampleTrack(FileItem* item) // Add the sample clip to the track Engine::audioEngine()->requestChangeInModel(); - auto clip = static_cast(sampleTrack->createClip()); + auto clip = static_cast(sampleTrack->addClip(sampleTrack->createClip())); clip->setSampleFile(item->fullName()); Engine::audioEngine()->doneChangeInModel(); return true; diff --git a/src/gui/clips/ClipView.cpp b/src/gui/clips/ClipView.cpp index 527cd7877ee..c272b72f818 100644 --- a/src/gui/clips/ClipView.cpp +++ b/src/gui/clips/ClipView.cpp @@ -1279,7 +1279,7 @@ void ClipView::mergeClips(QVector clipvs) const TimePos earliestPos = (*earliestClipV)->getClip()->startPosition(); // Create a clip where all notes will be added - auto newMidiClip = static_cast(track->createClip()); + auto newMidiClip = static_cast(track->addClip(track->createClip())); if (!newMidiClip) { diff --git a/src/gui/clips/SampleClipView.cpp b/src/gui/clips/SampleClipView.cpp index eec75fc7a99..b16cf7887dd 100644 --- a/src/gui/clips/SampleClipView.cpp +++ b/src/gui/clips/SampleClipView.cpp @@ -362,7 +362,7 @@ bool SampleClipView::splitClip( const TimePos pos ) m_clip->getTrack()->addJournalCheckPoint(); m_clip->getTrack()->saveJournallingState( false ); - auto rightClip = m_clip->getTrack()->addClip(*m_clip); + auto rightClip = m_clip->getTrack()->addClip(m_clip->getTrack()->createClip()); m_clip->changeLength( splitPos - m_initialClipPos ); diff --git a/src/gui/tracks/AutomationTrackView.cpp b/src/gui/tracks/AutomationTrackView.cpp index 759049bcef7..9d0045ddb6f 100644 --- a/src/gui/tracks/AutomationTrackView.cpp +++ b/src/gui/tracks/AutomationTrackView.cpp @@ -77,7 +77,7 @@ void AutomationTrackView::dropEvent( QDropEvent * _de ) pos.setTicks( 0 ); } - auto autoClip = static_cast(getTrack()->createClip()); + auto autoClip = static_cast(getTrack()->addClip(getTrack()->createClip())); autoClip->movePosition(pos); autoClip->addObject( mod ); } diff --git a/src/gui/tracks/SampleTrackView.cpp b/src/gui/tracks/SampleTrackView.cpp index f87719f8e21..403b428b214 100644 --- a/src/gui/tracks/SampleTrackView.cpp +++ b/src/gui/tracks/SampleTrackView.cpp @@ -217,7 +217,7 @@ void SampleTrackView::dropEvent(QDropEvent *de) * TimePos::ticksPerBar()) + trackContainerView()->currentPosition() ).quantize(1.0); - auto sClip = static_cast(getTrack()->createClip()); + auto sClip = static_cast(getTrack()->addClip(getTrack()->createClip())); sClip->movePosition(clipPos); if (sClip) { sClip->setSampleFile(value); } } diff --git a/src/gui/tracks/TrackView.cpp b/src/gui/tracks/TrackView.cpp index ecd397975f1..4da145c9eb8 100644 --- a/src/gui/tracks/TrackView.cpp +++ b/src/gui/tracks/TrackView.cpp @@ -109,7 +109,7 @@ TrackView::TrackView( Track * track, TrackContainerView * tcv ) : connect(trackGrip, &TrackGrip::released, this, &TrackView::onTrackGripReleased); // create views for already existing clips - for (const auto& clip : m_track->m_clips) + for (const auto& clip : m_track->getClips()) { createClipView(clip); } diff --git a/src/tracks/AutomationTrack.cpp b/src/tracks/AutomationTrack.cpp index 36bc32afddd..f44561c9dc7 100644 --- a/src/tracks/AutomationTrack.cpp +++ b/src/tracks/AutomationTrack.cpp @@ -55,16 +55,9 @@ gui::TrackView* AutomationTrack::createView( gui::TrackContainerView* tcv ) -Clip* AutomationTrack::createClip() +std::unique_ptr AutomationTrack::createClip() { - return addClip(); -} - - - -bool AutomationTrack::canAddClip(Clip* clip) -{ - return dynamic_cast(clip) != nullptr; + return std::make_unique(); } void AutomationTrack::saveTrackSpecificSettings(QDomDocument& doc, QDomElement& _this, bool presetMode) diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index f4e5606f2c3..05c73687bfb 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -706,8 +706,9 @@ bool InstrumentTrack::play( const TimePos & _start, const fpp_t _frames, } const float frames_per_tick = Engine::framesPerTick(); - clipVector clips; + auto clips = std::vector{}; class PatternTrack * pattern_track = nullptr; + if( _clip_num >= 0 ) { Clip * clip = getClip( _clip_num ); @@ -717,11 +718,7 @@ bool InstrumentTrack::play( const TimePos & _start, const fpp_t _frames, pattern_track = PatternTrack::findPatternTrack(_clip_num); } } - else - { - getClipsInRange( clips, _start, _start + static_cast( - _frames / frames_per_tick ) ); - } + else { clips = getClipsInRange(_start, _start + static_cast(_frames / frames_per_tick)); } // Handle automation: detuning for (const auto& processHandle : m_processHandles) @@ -800,21 +797,11 @@ bool InstrumentTrack::play( const TimePos & _start, const fpp_t _frames, return played_a_note; } - - - -Clip* InstrumentTrack::createClip() -{ - return addClip(); -} - - -bool InstrumentTrack::canAddClip(Clip* clip) +std::unique_ptr InstrumentTrack::createClip() { - return dynamic_cast(clip) != nullptr; + return std::make_unique(); } - gui::TrackView* InstrumentTrack::createView( gui::TrackContainerView* tcv ) { return new gui::InstrumentTrackView( this, tcv ); diff --git a/src/tracks/MidiClip.cpp b/src/tracks/MidiClip.cpp index aeaa61632ed..616ae4906b0 100644 --- a/src/tracks/MidiClip.cpp +++ b/src/tracks/MidiClip.cpp @@ -448,7 +448,7 @@ MidiClip * MidiClip::nextMidiClip() const MidiClip * MidiClip::adjacentMidiClipByOffset(int offset) const { - auto& clips = getTrack()->getClips(); + auto clips = getTrack()->getClips(); int clipNum = getTrack()->getClipNum(this) + offset; if (clipNum < 0 || static_cast(clipNum) >= clips.size()) { return nullptr; } return dynamic_cast(clips[clipNum]); diff --git a/src/tracks/PatternTrack.cpp b/src/tracks/PatternTrack.cpp index 0fc267edfe6..383186ea77d 100644 --- a/src/tracks/PatternTrack.cpp +++ b/src/tracks/PatternTrack.cpp @@ -95,8 +95,7 @@ bool PatternTrack::play( const TimePos & _start, const fpp_t _frames, return Engine::patternStore()->play(_start, _frames, _offset, s_infoMap[this]); } - clipVector clips; - getClipsInRange( clips, _start, _start + static_cast( _frames / Engine::framesPerTick() ) ); + const auto clips = getClipsInRange(_start, _start + static_cast(_frames / Engine::framesPerTick())); if( clips.size() == 0 ) { @@ -140,18 +139,11 @@ gui::TrackView* PatternTrack::createView(gui::TrackContainerView* tcv) -Clip* PatternTrack::createClip() +std::unique_ptr PatternTrack::createClip() { - return addClip(); + return std::make_unique(); } - -bool PatternTrack::canAddClip(Clip* clip) -{ - return dynamic_cast(clip) != nullptr; -} - - void PatternTrack::saveTrackSpecificSettings(QDomDocument& doc, QDomElement& _this, bool presetMode) { // _this.setAttribute( "icon", m_trackLabel->pixmapFile() ); diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 6b50cbb54c3..86646135bbd 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -76,9 +76,9 @@ bool SampleTrack::play( const TimePos & _start, const fpp_t _frames, m_audioPort.effects()->startRunning(); bool played_a_note = false; // will be return variable - - clipVector clips; + auto clips = std::vector{}; class PatternTrack * pattern_track = nullptr; + if( _clip_num >= 0 ) { if (_start > getClip(_clip_num)->length()) @@ -175,19 +175,9 @@ gui::TrackView * SampleTrack::createView( gui::TrackContainerView* tcv ) return new gui::SampleTrackView( this, tcv ); } - - - -Clip * SampleTrack::createClip() -{ - return addClip(); -} - - - -bool SampleTrack::canAddClip(Clip* clip) +std::unique_ptr SampleTrack::createClip() { - return dynamic_cast(clip) != nullptr; + return std::make_unique(); } void SampleTrack::saveTrackSpecificSettings(QDomDocument& _doc, QDomElement& _this, bool presetMode) diff --git a/tests/src/tracks/AutomationTrackTest.cpp b/tests/src/tracks/AutomationTrackTest.cpp index 6118841fd0e..b82336731f8 100644 --- a/tests/src/tracks/AutomationTrackTest.cpp +++ b/tests/src/tracks/AutomationTrackTest.cpp @@ -96,20 +96,20 @@ private slots: auto song = Engine::getSong(); auto track = song->addTrack(); - auto c1 = static_cast(track->createClip()); + auto c1 = static_cast(track->addClip(track->createClip())); c1->setProgressionType(AutomationClip::ProgressionType::Linear); c1->putValue(0, 0.0, false); c1->putValue(10, 1.0, false); c1->addObject(&model); - auto c2 = static_cast(track->createClip()); + auto c2 = static_cast(track->addClip(track->createClip())); c2->setProgressionType(AutomationClip::ProgressionType::Linear); c2->putValue(0, 0.0, false); c2->putValue(100, 1.0, false); c2->movePosition(100); c2->addObject(&model); - auto c3 = static_cast(track->createClip()); + auto c3 = static_cast(track->addClip(track->createClip())); c3->addObject(&model); //XXX: Why is this even necessary? c3->clear(); @@ -130,7 +130,7 @@ private slots: auto song = Engine::getSong(); auto track = song->addTrack(); - auto c = static_cast(track->createClip()); + auto c = static_cast(track->addClip(track->createClip())); c->setProgressionType(AutomationClip::ProgressionType::Linear); c->addObject(&model); @@ -155,7 +155,7 @@ private slots: auto song = Engine::getSong(); auto instrumentTrack = song->addTrack(); - auto midiClip = static_cast(instrumentTrack->createClip()); + auto midiClip = static_cast(instrumentTrack->addClip(instrumentTrack->createClip())); midiClip->changeLength(TimePos(4, 0)); Note* note = midiClip->addNote(Note(TimePos(4, 0)), false); @@ -204,7 +204,7 @@ private slots: QCOMPARE(patternStore->automatedValuesAt(5, patternTrack->patternIndex())[&model], 0.5f); QVERIFY(! patternStore->automatedValuesAt(5, patternTrack2->patternIndex()).size()); - auto clip = static_cast(patternTrack->createClip()); + auto clip = static_cast(patternTrack->addClip(patternTrack->createClip())); clip->changeLength(TimePos::ticksPerBar() * 2); QCOMPARE(song->automatedValuesAt(0)[&model], 0.0f); @@ -221,10 +221,10 @@ private slots: auto song = Engine::getSong(); auto globalTrack = song->globalAutomationTrack(); - auto globalClip = static_cast(globalTrack->createClip()); + auto globalClip = static_cast(globalTrack->addClip(globalTrack->createClip())); auto localTrack = song->addTrack(); - auto localClip = static_cast(localTrack->createClip()); + auto localClip = static_cast(localTrack->addClip(localTrack->createClip())); FloatModel model; globalClip->setProgressionType(AutomationClip::ProgressionType::Discrete);