1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-15 15:49:36 +02:00

All tracks allocated with make_shared, no more make_unique...

... so that we can use Track::SharedPointer without undefined behavior even on
tracks that don't yet belong to any TrackList.

Also fix the return type of function template TrackList::Add and remove some
casts.
This commit is contained in:
Paul Licameli 2018-11-18 23:07:05 -05:00
parent 6f89c48873
commit a0aa69a248
18 changed files with 60 additions and 109 deletions

View File

@ -99,7 +99,7 @@ int LabelTrack::mFontHeight=-1;
LabelTrack::Holder TrackFactory::NewLabelTrack()
{
return std::make_unique<LabelTrack>(mDirManager);
return std::make_shared<LabelTrack>(mDirManager);
}
LabelTrack::LabelTrack(const std::shared_ptr<DirManager> &projDirManager):
@ -1142,7 +1142,7 @@ double LabelTrack::GetEndTime() const
Track::Holder LabelTrack::Duplicate() const
{
return std::make_unique<LabelTrack>( *this );
return std::make_shared<LabelTrack>( *this );
}
void LabelTrack::SetSelected(bool s)
@ -2489,7 +2489,7 @@ Track::Holder LabelTrack::SplitCut(double t0, double t1)
Track::Holder LabelTrack::Copy(double t0, double t1, bool) const
{
auto tmp = std::make_unique<LabelTrack>(GetDirManager());
auto tmp = std::make_shared<LabelTrack>(GetDirManager());
const auto lt = static_cast<LabelTrack*>(tmp.get());
for (auto &labelStruct: mLabels) {
@ -2534,8 +2534,7 @@ Track::Holder LabelTrack::Copy(double t0, double t1, bool) const
}
lt->mClipLen = (t1 - t0);
// This std::move is needed to "upcast" the pointer type
return std::move(tmp);
return tmp;
}

View File

@ -161,7 +161,7 @@ class AUDACITY_DLL_API LabelTrack final : public Track
double GetStartTime() const override;
double GetEndTime() const override;
using Holder = std::unique_ptr<LabelTrack>;
using Holder = std::shared_ptr<LabelTrack>;
Track::Holder Duplicate() const override;
void SetSelected(bool s) override;

View File

@ -49,7 +49,8 @@ class WaveTrackCache;
void MixAndRender(TrackList * tracks, TrackFactory *factory,
double rate, sampleFormat format,
double startTime, double endTime,
std::unique_ptr<WaveTrack> &uLeft, std::unique_ptr<WaveTrack> &uRight);
std::shared_ptr<WaveTrack> &uLeft,
std::shared_ptr<WaveTrack> &uRight);
void MixBuffers(unsigned numChannels, int *channelFlags, float *gains,
samplePtr src,

View File

@ -104,7 +104,7 @@ SONFNS(AutoSave)
NoteTrack::Holder TrackFactory::NewNoteTrack()
{
return std::make_unique<NoteTrack>(mDirManager);
return std::make_shared<NoteTrack>(mDirManager);
}
NoteTrack::NoteTrack(const std::shared_ptr<DirManager> &projDirManager)
@ -155,7 +155,7 @@ Alg_seq &NoteTrack::GetSeq() const
Track::Holder NoteTrack::Duplicate() const
{
auto duplicate = std::make_unique<NoteTrack>(mDirManager);
auto duplicate = std::make_shared<NoteTrack>(mDirManager);
duplicate->Init(*this);
// The duplicate begins life in serialized state. Often the duplicate is
// pushed on the Undo stack. Then we want to un-serialize it (or a further
@ -190,8 +190,7 @@ Track::Holder NoteTrack::Duplicate() const
#ifdef EXPERIMENTAL_MIDI_OUT
duplicate->SetVelocity(GetVelocity());
#endif
// This std::move is needed to "upcast" the pointer type
return std::move(duplicate);
return duplicate;
}
@ -463,7 +462,7 @@ Track::Holder NoteTrack::Cut(double t0, double t1)
//( std::min( t1, GetEndTime() ) ) - ( std::max( t0, GetStartTime() ) )
//);
auto newTrack = std::make_unique<NoteTrack>(mDirManager);
auto newTrack = std::make_shared<NoteTrack>(mDirManager);
newTrack->Init(*this);
@ -480,8 +479,7 @@ Track::Holder NoteTrack::Cut(double t0, double t1)
//(mBottomNote, mDirManager,
// mSerializationBuffer, mSerializationLength, mVisibleChannels)
// This std::move is needed to "upcast" the pointer type
return std::move(newTrack);
return newTrack;
}
Track::Holder NoteTrack::Copy(double t0, double t1, bool) const
@ -491,7 +489,7 @@ Track::Holder NoteTrack::Copy(double t0, double t1, bool) const
double len = t1-t0;
auto newTrack = std::make_unique<NoteTrack>(mDirManager);
auto newTrack = std::make_shared<NoteTrack>(mDirManager);
newTrack->Init(*this);
@ -504,8 +502,7 @@ Track::Holder NoteTrack::Copy(double t0, double t1, bool) const
// (mBottomNote, mDirManager, mSerializationBuffer,
// mSerializationLength, mVisibleChannels)
// This std::move is needed to "upcast" the pointer type
return std::move(newTrack);
return newTrack;
}
bool NoteTrack::Trim(double t0, double t1)

View File

@ -75,7 +75,7 @@ class AUDACITY_DLL_API NoteTrack final
const AudacityProject *pProject, int currentTool, bool bMultiTool)
override;
using Holder = std::unique_ptr<NoteTrack>;
using Holder = std::shared_ptr<NoteTrack>;
Track::Holder Duplicate() const override;
double GetOffset() const override;

View File

@ -33,9 +33,9 @@
#define TIMETRACK_MIN 0.01
#define TIMETRACK_MAX 10.0
std::unique_ptr<TimeTrack> TrackFactory::NewTimeTrack()
std::shared_ptr<TimeTrack> TrackFactory::NewTimeTrack()
{
return std::make_unique<TimeTrack>(mDirManager, mZoomInfo);
return std::make_shared<TimeTrack>(mDirManager, mZoomInfo);
}
TimeTrack::TimeTrack(const std::shared_ptr<DirManager> &projDirManager, const ZoomInfo *zoomInfo):
@ -108,8 +108,7 @@ Track::Holder TimeTrack::Cut( double t0, double t1 )
Track::Holder TimeTrack::Copy( double t0, double t1, bool ) const
{
auto result = std::make_unique<TimeTrack>( *this, &t0, &t1 );
return Track::Holder{ std::move( result ) };
return std::make_shared<TimeTrack>( *this, &t0, &t1 );
}
void TimeTrack::Clear(double t0, double t1)
@ -143,7 +142,7 @@ void TimeTrack::InsertSilence(double t, double len)
Track::Holder TimeTrack::Duplicate() const
{
return std::make_unique<TimeTrack>(*this);
return std::make_shared<TimeTrack>(*this);
}
bool TimeTrack::GetInterpolateLog() const

View File

@ -728,35 +728,10 @@ Track *TrackList::FindById( TrackId id )
return it->get();
}
template<typename TrackKind>
Track *TrackList::Add(std::unique_ptr<TrackKind> &&t)
Track *TrackList::DoAddToHead(const std::shared_ptr<Track> &t)
{
Track *pTrack;
push_back(ListOfTracks::value_type(pTrack = t.release()));
auto n = getPrev( getEnd() );
pTrack->SetOwner(mSelf, n);
pTrack->SetId( TrackId{ ++sCounter } );
RecalcPositions(n);
AdditionEvent(n);
return back().get();
}
// Make instantiations for the linker to find
template Track *TrackList::Add<TimeTrack>(std::unique_ptr<TimeTrack> &&);
#if defined(USE_MIDI)
template Track *TrackList::Add<NoteTrack>(std::unique_ptr<NoteTrack> &&);
#endif
template Track *TrackList::Add<WaveTrack>(std::unique_ptr<WaveTrack> &&);
template Track *TrackList::Add<LabelTrack>(std::unique_ptr<LabelTrack> &&);
template Track *TrackList::Add<Track>(std::unique_ptr<Track> &&);
template<typename TrackKind>
Track *TrackList::AddToHead(std::unique_ptr<TrackKind> &&t)
{
Track *pTrack;
push_front(ListOfTracks::value_type(pTrack = t.release()));
Track *pTrack = t.get();
push_front(ListOfTracks::value_type(t));
auto n = getBegin();
pTrack->SetOwner(mSelf, n);
pTrack->SetId( TrackId{ ++sCounter } );
@ -765,11 +740,7 @@ Track *TrackList::AddToHead(std::unique_ptr<TrackKind> &&t)
return front().get();
}
// Make instantiations for the linker to find
template Track *TrackList::AddToHead<TimeTrack>(std::unique_ptr<TimeTrack> &&);
template<typename TrackKind>
Track *TrackList::Add(std::shared_ptr<TrackKind> &&t)
Track *TrackList::DoAdd(const std::shared_ptr<Track> &t)
{
push_back(t);
@ -782,10 +753,6 @@ Track *TrackList::Add(std::shared_ptr<TrackKind> &&t)
return back().get();
}
// Make instantiations for the linker to find
template Track *TrackList::Add<Track>(std::shared_ptr<Track> &&);
template Track *TrackList::Add<WaveTrack>(std::shared_ptr<WaveTrack> &&);
void TrackList::GroupChannels(
Track &track, size_t groupSize, bool resetChannels )
{
@ -1234,8 +1201,7 @@ TrackList::RegisterPendingChangedTrack( Updater updater, Track *src )
{
std::shared_ptr<Track> pTrack;
if (src)
// convert from unique_ptr to shared_ptr
pTrack.reset( src->Duplicate().release() );
pTrack = src->Duplicate();
if (pTrack) {
mUpdaters.push_back( updater );

View File

@ -367,7 +367,7 @@ private:
void Init(const Track &orig);
using Holder = std::unique_ptr<Track>;
using Holder = std::shared_ptr<Track>;
virtual Holder Duplicate() const = 0;
// Called when this track is merged to stereo with another, and should
@ -1330,6 +1330,9 @@ class TrackList final : public wxEvtHandler, public ListOfTracks
}
private:
Track *DoAddToHead(const std::shared_ptr<Track> &t);
Track *DoAdd(const std::shared_ptr<Track> &t);
template< typename TrackType, typename InTrackType >
static TrackIterRange< TrackType >
Channels_( TrackIter< InTrackType > iter1 )
@ -1369,15 +1372,12 @@ public:
/// Add a Track, giving it a fresh id
template<typename TrackKind>
Track *Add(std::unique_ptr<TrackKind> &&t);
TrackKind *AddToHead( const std::shared_ptr< TrackKind > &t )
{ return static_cast< TrackKind* >( DoAddToHead( t ) ); }
/// Add a Track, giving it a fresh id
template<typename TrackKind>
Track *AddToHead(std::unique_ptr<TrackKind> &&t);
/// Add a Track, giving it a fresh id
template<typename TrackKind>
Track *Add(std::shared_ptr<TrackKind> &&t);
TrackKind *Add( const std::shared_ptr< TrackKind > &t )
{ return static_cast< TrackKind* >( DoAdd( t ) ); }
/** \brief Define a group of channels starting at the given track
*
@ -1632,13 +1632,13 @@ class AUDACITY_DLL_API TrackFactory
public:
// These methods are defined in WaveTrack.cpp, NoteTrack.cpp,
// LabelTrack.cpp, and TimeTrack.cpp respectively
std::unique_ptr<WaveTrack> DuplicateWaveTrack(const WaveTrack &orig);
std::unique_ptr<WaveTrack> NewWaveTrack(sampleFormat format = (sampleFormat)0,
std::shared_ptr<WaveTrack> DuplicateWaveTrack(const WaveTrack &orig);
std::shared_ptr<WaveTrack> NewWaveTrack(sampleFormat format = (sampleFormat)0,
double rate = 0);
std::unique_ptr<LabelTrack> NewLabelTrack();
std::unique_ptr<TimeTrack> NewTimeTrack();
std::shared_ptr<LabelTrack> NewLabelTrack();
std::shared_ptr<TimeTrack> NewTimeTrack();
#if defined(USE_MIDI)
std::unique_ptr<NoteTrack> NewNoteTrack();
std::shared_ptr<NoteTrack> NewNoteTrack();
#endif
};

View File

@ -70,15 +70,13 @@ using std::max;
WaveTrack::Holder TrackFactory::DuplicateWaveTrack(const WaveTrack &orig)
{
return std::unique_ptr<WaveTrack>
{ static_cast<WaveTrack*>(orig.Duplicate().release()) };
return std::static_pointer_cast<WaveTrack>( orig.Duplicate() );
}
WaveTrack::Holder TrackFactory::NewWaveTrack(sampleFormat format, double rate)
{
return std::unique_ptr<WaveTrack>
{ safenew WaveTrack(mDirManager, format, rate) };
return std::make_shared<WaveTrack> ( mDirManager, format, rate );
}
WaveTrack::WaveTrack(const std::shared_ptr<DirManager> &projDirManager, sampleFormat format, double rate) :
@ -395,7 +393,7 @@ int WaveTrack::ZeroLevelYCoordinate(wxRect rect) const
Track::Holder WaveTrack::Duplicate() const
{
return Track::Holder{ safenew WaveTrack{ *this } };
return std::make_shared<WaveTrack>( *this );
}
double WaveTrack::GetRate() const
@ -629,9 +627,8 @@ Track::Holder WaveTrack::Copy(double t0, double t1, bool forClipboard) const
if (t1 < t0)
THROW_INCONSISTENCY_EXCEPTION;
WaveTrack *newTrack;
Track::Holder result
{ newTrack = safenew WaveTrack{ mDirManager } };
auto result = std::make_shared<WaveTrack>( mDirManager );
WaveTrack *newTrack = result.get();
newTrack->Init(*this);

View File

@ -58,28 +58,24 @@ using Regions = std::vector < Region >;
class Envelope;
class AUDACITY_DLL_API WaveTrack final : public PlayableTrack {
private:
public:
//
// Constructor / Destructor / Duplicator
//
// Private since only factories are allowed to construct WaveTracks
//
WaveTrack(const std::shared_ptr<DirManager> &projDirManager,
sampleFormat format = (sampleFormat)0,
double rate = 0);
WaveTrack(const WaveTrack &orig);
void Init(const WaveTrack &orig);
public:
// overwrite data excluding the sample sequence but including display
// settings
void Reinit(const WaveTrack &orig);
private:
void Init(const WaveTrack &orig);
Track::Holder Duplicate() const override;
friend class TrackFactory;
@ -87,7 +83,7 @@ private:
public:
typedef WaveTrackLocation Location;
using Holder = std::unique_ptr<WaveTrack>;
using Holder = std::shared_ptr<WaveTrack>;
virtual ~WaveTrack();

View File

@ -1207,7 +1207,7 @@ bool Effect::DoEffect(wxWindow *parent,
// We don't yet know the effect type for code in the Nyquist Prompt, so
// assume it requires a track and handle errors when the effect runs.
if ((GetType() == EffectTypeGenerate || GetPath() == NYQUIST_PROMPT_ID) && (mNumTracks == 0)) {
newTrack = static_cast<WaveTrack*>(mTracks->Add(mFactory->NewWaveTrack()));
newTrack = mTracks->Add(mFactory->NewWaveTrack());
newTrack->SetSelected(true);
}
@ -1553,7 +1553,7 @@ bool Effect::ProcessTrack(int count,
auto chans = std::min<unsigned>(mNumAudioOut, mNumChannels);
std::unique_ptr<WaveTrack> genLeft, genRight;
std::shared_ptr<WaveTrack> genLeft, genRight;
decltype(len) genLength = 0;
bool isGenerator = GetType() == EffectTypeGenerate;
@ -2073,11 +2073,11 @@ void Effect::CopyInputTracks(bool allSyncLockSelected)
}
}
Track *Effect::AddToOutputTracks(std::unique_ptr<Track> &&t)
Track *Effect::AddToOutputTracks(const std::shared_ptr<Track> &t)
{
mIMap.push_back(NULL);
mOMap.push_back(t.get());
return mOutputTracks->Add(std::move(t));
return mOutputTracks->Add(t);
}
Effect::AddedAnalysisTrack::AddedAnalysisTrack(Effect *pEffect, const wxString &name)

View File

@ -443,7 +443,7 @@ protected:
void ReplaceProcessedTracks(const bool bGoodResult);
// Use this to append a NEW output track.
Track *AddToOutputTracks(std::unique_ptr<Track> &&t);
Track *AddToOutputTracks(const std::shared_ptr<Track> &t);
//
// protected data

View File

@ -59,8 +59,8 @@ public:
// Not required by callbacks, but makes for easier cleanup
std::unique_ptr<Resampler> resampler;
std::unique_ptr<SBSMSQuality> quality;
std::unique_ptr<WaveTrack> outputLeftTrack;
std::unique_ptr<WaveTrack> outputRightTrack;
std::shared_ptr<WaveTrack> outputLeftTrack;
std::shared_ptr<WaveTrack> outputRightTrack;
std::exception_ptr mpException {};
};

View File

@ -1419,7 +1419,7 @@ bool NyquistEffect::ProcessOne()
return false;
}
std::unique_ptr<WaveTrack> outputTrack[2];
std::shared_ptr<WaveTrack> outputTrack[2];
double rate = mCurTrack[0]->GetRate();
for (int i = 0; i < outChannels; i++) {

View File

@ -23,7 +23,7 @@ class wxWindow;
// Newly constructed WaveTracks that are not yet owned by a TrackList
// are held in unique_ptr not shared_ptr
using NewChannelGroup = std::vector< std::unique_ptr<WaveTrack> >;
using NewChannelGroup = std::vector< std::shared_ptr<WaveTrack> >;
using TrackHolders = std::vector< NewChannelGroup >;

View File

@ -41,10 +41,8 @@ int DoAddLabel(
auto lt = * iter.Filter< LabelTrack >();
// If none found, start a NEW label track and use it
if (!lt) {
lt = static_cast<LabelTrack*>
(tracks->Add(trackFactory->NewLabelTrack()));
}
if (!lt)
lt = tracks->Add(trackFactory->NewLabelTrack());
// LLL: Commented as it seemed a little forceful to remove users
// selection when adding the label. This does not happen if
@ -158,7 +156,7 @@ void EditByLabel(
}
}
using EditDestFunction = std::unique_ptr<Track> (WaveTrack::*)(double, double);
using EditDestFunction = std::shared_ptr<Track> (WaveTrack::*)(double, double);
//Executes the edit function on all selected wave tracks with
//regions specified by selected labels

View File

@ -1168,9 +1168,7 @@ bool ControlToolBar::DoRecord(AudacityProject &project,
Track *first {};
for (int c = 0; c < recordingChannels; c++) {
std::shared_ptr<WaveTrack> newTrack{
p->GetTrackFactory()->NewWaveTrack().release()
};
auto newTrack = p->GetTrackFactory()->NewWaveTrack();
if (!first)
first = newTrack.get();

View File

@ -156,7 +156,7 @@ class TranscriptionToolBar final : public ToolBar {
int mBackgroundWidth;
int mBackgroundHeight;
std::unique_ptr<TimeTrack> mTimeTrack;
std::shared_ptr<TimeTrack> mTimeTrack;
public: