From daf92c43f860d8e1343c646746084d7253f2dd3c Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sun, 10 Apr 2016 20:24:30 -0400 Subject: [PATCH] Sequence::Copy is a factory returning smart pointer. WaveClip stores it. --- src/Sequence.cpp | 19 +++++++++---------- src/Sequence.h | 3 ++- src/WaveClip.cpp | 33 +++++++++++++-------------------- src/WaveClip.h | 21 +++++---------------- 4 files changed, 29 insertions(+), 47 deletions(-) diff --git a/src/Sequence.cpp b/src/Sequence.cpp index 096244cfa..9b1ae8a58 100644 --- a/src/Sequence.cpp +++ b/src/Sequence.cpp @@ -29,6 +29,7 @@ #include "Audacity.h" +#include "Sequence.h" #include #include @@ -40,8 +41,6 @@ #include #include -#include "Sequence.h" - #include "BlockFile.h" #include "blockfile/ODDecodeBlockFile.h" #include "DirManager.h" @@ -406,9 +405,9 @@ bool Sequence::GetRMS(sampleCount start, sampleCount len, return true; } -bool Sequence::Copy(sampleCount s0, sampleCount s1, Sequence **dest) +bool Sequence::Copy(sampleCount s0, sampleCount s1, std::unique_ptr &dest) const { - *dest = 0; + dest.reset(); if (s0 >= s1 || s0 >= mNumSamples || s1 < 0) return false; @@ -423,8 +422,8 @@ bool Sequence::Copy(sampleCount s0, sampleCount s1, Sequence **dest) wxUnusedVar(numBlocks); wxASSERT(b0 <= b1); - *dest = new Sequence(mDirManager, mSampleFormat); - (*dest)->mBlock.reserve(b1 - b0 + 1); + dest = std::make_unique(mDirManager, mSampleFormat); + dest->mBlock.reserve(b1 - b0 + 1); SampleBuffer buffer(mMaxSamples, mSampleFormat); @@ -439,14 +438,14 @@ bool Sequence::Copy(sampleCount s0, sampleCount s1, Sequence **dest) wxASSERT(file->IsAlias() || (blocklen <= mMaxSamples)); // Vaughan, 2012-02-29 Get(b0, buffer.ptr(), mSampleFormat, s0, blocklen); - (*dest)->Append(buffer.ptr(), mSampleFormat, blocklen); + dest->Append(buffer.ptr(), mSampleFormat, blocklen); } else --b0; // If there are blocks in the middle, copy the blockfiles directly for (int bb = b0 + 1; bb < b1; ++bb) - (*dest)->AppendBlock(mBlock[bb]); // Increase ref count or duplicate file + dest->AppendBlock(mBlock[bb]); // Increase ref count or duplicate file // Do the last block if (b1 > b0) { @@ -456,11 +455,11 @@ bool Sequence::Copy(sampleCount s0, sampleCount s1, Sequence **dest) wxASSERT(file->IsAlias() || (blocklen <= mMaxSamples)); // Vaughan, 2012-02-29 if (blocklen < file->GetLength()) { Get(b1, buffer.ptr(), mSampleFormat, block.start, blocklen); - (*dest)->Append(buffer.ptr(), mSampleFormat, blocklen); + dest->Append(buffer.ptr(), mSampleFormat, blocklen); } else // Special case, copy exactly - (*dest)->AppendBlock(block); // Increase ref count or duplicate file + dest->AppendBlock(block); // Increase ref count or duplicate file } return ConsistencyCheck(wxT("Sequence::Copy()")); diff --git a/src/Sequence.h b/src/Sequence.h index 0007dbca2..3230c1373 100644 --- a/src/Sequence.h +++ b/src/Sequence.h @@ -11,6 +11,7 @@ #ifndef __AUDACITY_SEQUENCE__ #define __AUDACITY_SEQUENCE__ +#include "MemoryX.h" #include #include #include @@ -99,7 +100,7 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{ bool GetWaveDisplay(float *min, float *max, float *rms, int* bl, int len, const sampleCount *where); - bool Copy(sampleCount s0, sampleCount s1, Sequence **dest); + bool Copy(sampleCount s0, sampleCount s1, std::unique_ptr &dest) const; bool Paste(sampleCount s0, const Sequence *src); sampleCount GetIdealAppendLen(); diff --git a/src/WaveClip.cpp b/src/WaveClip.cpp index 8cf32df12..7009b620a 100644 --- a/src/WaveClip.cpp +++ b/src/WaveClip.cpp @@ -294,7 +294,7 @@ WaveClip::WaveClip(DirManager *projDirManager, sampleFormat format, int rate) { mOffset = 0; mRate = rate; - mSequence = new Sequence(projDirManager, format); + mSequence = std::make_unique(projDirManager, format); mEnvelope = new Envelope(); mWaveCache = new WaveCache(); mSpecCache = new SpecCache(); @@ -312,7 +312,7 @@ WaveClip::WaveClip(const WaveClip& orig, DirManager *projDirManager) mOffset = orig.mOffset; mRate = orig.mRate; - mSequence = new Sequence(*orig.mSequence, projDirManager); + mSequence = std::make_unique(*orig.mSequence, projDirManager); mEnvelope = new Envelope(); mEnvelope->Paste(0.0, orig.mEnvelope); mEnvelope->SetOffset(orig.GetOffset()); @@ -331,8 +331,6 @@ WaveClip::WaveClip(const WaveClip& orig, DirManager *projDirManager) WaveClip::~WaveClip() { - delete mSequence; - delete mEnvelope; mEnvelope = NULL; @@ -547,7 +545,7 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0, if (match && mWaveCache->start == t0 && mWaveCache->len >= numPixels) { - mWaveCache->LoadInvalidRegions(mSequence, true); + mWaveCache->LoadInvalidRegions(mSequence.get(), true); mWaveCache->ClearInvalidRegions(); // Satisfy the request completely from the cache @@ -604,7 +602,7 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0, //TODO: only load inval regions if //necessary. (usually is the case, so no rush.) //also, we should be updating the NEW cache, but here we are patching the old one up. - oldCache->LoadInvalidRegions(mSequence, false); + oldCache->LoadInvalidRegions(mSequence.get(), false); oldCache->ClearInvalidRegions(); // Copy what we can from the old cache. @@ -1379,7 +1377,7 @@ void WaveClip::HandleXMLEndTag(const wxChar *tag) XMLTagHandler *WaveClip::HandleXMLChild(const wxChar *tag) { if (!wxStrcmp(tag, wxT("sequence"))) - return mSequence; + return mSequence.get(); else if (!wxStrcmp(tag, wxT("envelope"))) return mEnvelope; else if (!wxStrcmp(tag, wxT("waveclip"))) @@ -1414,15 +1412,14 @@ bool WaveClip::CreateFromCopy(double t0, double t1, const WaveClip* other) other->TimeToSamplesClip(t0, &s0); other->TimeToSamplesClip(t1, &s1); - Sequence* oldSequence = mSequence; + std::unique_ptr oldSequence = std::move(mSequence); mSequence = NULL; - if (!other->mSequence->Copy(s0, s1, &mSequence)) + if (!other->mSequence->Copy(s0, s1, mSequence)) { - mSequence = oldSequence; + mSequence = std::move(oldSequence); return false; } - delete oldSequence; delete mEnvelope; mEnvelope = new Envelope(); mEnvelope->CopyFrom(other->mEnvelope, (double)s0/mRate, (double)s1/mRate); @@ -1461,7 +1458,7 @@ bool WaveClip::Paste(double t0, const WaveClip* other) TimeToSamplesClip(t0, &s0); bool result = false; - if (mSequence->Paste(s0, pastedClip->mSequence)) + if (mSequence->Paste(s0, pastedClip->mSequence.get())) { MarkChanged(); mEnvelope->Paste((double)s0/mRate + mOffset, pastedClip->mEnvelope); @@ -1741,8 +1738,8 @@ bool WaveClip::Resample(int rate, ProgressDialog *progress) int outGenerated = 0; sampleCount numSamples = mSequence->GetNumSamples(); - Sequence* newSequence = - new Sequence(mSequence->GetDirManager(), mSequence->GetSampleFormat()); + auto newSequence = + std::make_unique(mSequence->GetDirManager(), mSequence->GetSampleFormat()); /** * We want to keep going as long as we have something to feed the resampler @@ -1796,13 +1793,9 @@ bool WaveClip::Resample(int rate, ProgressDialog *progress) delete[] inBuffer; delete[] outBuffer; - if (error) + if (!error) { - delete newSequence; - } else - { - delete mSequence; - mSequence = newSequence; + mSequence = std::move(newSequence); mRate = rate; // Invalidate wave display cache diff --git a/src/WaveClip.h b/src/WaveClip.h index 1d46bb8fe..14357c7ae 100644 --- a/src/WaveClip.h +++ b/src/WaveClip.h @@ -13,6 +13,7 @@ #define __AUDACITY_WAVECLIP__ #include "Audacity.h" +#include "MemoryX.h" #include "SampleFormat.h" #include "widgets/ProgressDialog.h" #include "ondemand/ODTaskThread.h" @@ -205,20 +206,8 @@ class AUDACITY_DLL_API WaveClip final : public XMLTagHandler { private: // It is an error to copy a WaveClip without specifying the DirManager. - // We define these break-inducing single-arg methods so that - // if some developer makes the mistake of calling a single-arg copy - // constructor rather than the one below (that requires a DirManager*), - // rather than it going to C++-generated default copy constructor, - // it goes here and the error is made clear to that developer. - WaveClip(const WaveClip&) - { - wxFAIL_MSG(wxT("It is an error to copy a WaveClip without specifying the DirManager.")); - } - WaveClip& operator=(const WaveClip& orig) - { - WaveClip bogus(orig); - return *this; - } + WaveClip(const WaveClip&) PROHIBITED; + WaveClip& operator= (const WaveClip&) PROHIBITED; public: // typical constructor @@ -271,7 +260,7 @@ public: // Get low-level access to the sequence. Whenever possible, don't use this, // but use more high-level functions inside WaveClip (or add them if you // think they are useful for general use) - Sequence* GetSequence() { return mSequence; } + Sequence* GetSequence() { return mSequence.get(); } /** WaveTrack calls this whenever data in the wave clip changes. It is * called automatically when WaveClip has a chance to know that something @@ -387,7 +376,7 @@ protected: int mRate; int mDirty; bool mIsCutLine; - Sequence *mSequence; + std::unique_ptr mSequence; Envelope *mEnvelope; mutable WaveCache *mWaveCache;