Audacity 3.2.0
ChannelAttachments.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 @file ChannelAttachments.cpp
6
7 Dominic Mazzoni
8
9 Paul Licameli split from Track.cpp
10
11*//*******************************************************************/
12#include "ChannelAttachments.h"
13
15
18{
19 assert(typeid(*this) == typeid(other));
20 mAttachments = move(other.mAttachments);
21 return *this;
22}
23
24void ChannelAttachment::CopyTo(Track&, size_t) const
25{
26}
27
28void ChannelAttachment::Reparent(const std::shared_ptr<Track> &, size_t)
29{
30}
31
33{
34}
35
37 const std::string_view &, const XMLAttributeValueView &, size_t)
38{
39 return false;
40}
41
44 Track &track, size_t iChannel)
45{
46 // Precondition of this function; satisfies precondition of factory below
47 assert(iChannel < track.NChannels());
48 auto &attachments = track.AttachedObjects::Get<ChannelAttachmentsBase>(key);
49 auto &objects = attachments.mAttachments;
50 if (iChannel >= objects.size())
51 objects.resize(iChannel + 1);
52 auto &pObject = objects[iChannel];
53 if (!pObject) {
54 // Create on demand
55 pObject = attachments.mFactory(track, iChannel);
56 assert(pObject); // Precondition of constructor
57 }
58 return *pObject;
59}
60
63 Track *pTrack, size_t iChannel)
64{
65 assert(!pTrack || iChannel < pTrack->NChannels());
66 if (!pTrack)
67 return nullptr;
68 const auto pAttachments =
69 pTrack->AttachedObjects::Find<ChannelAttachmentsBase>(key);
70 // do not create on demand
71 if (!pAttachments || iChannel >= pAttachments->mAttachments.size())
72 return nullptr;
73 return pAttachments->mAttachments[iChannel].get();
74}
75
77 : mFactory{ move(factory) }
78{
79 const auto nChannels = track.NChannels();
80 for (size_t iChannel = 0; iChannel < nChannels; ++iChannel)
81 mAttachments.push_back(mFactory(track, iChannel));
82}
83
85
87{
88 // Maybe making a narrow empty copy so limit to the other track's number
89 // of channels
90 const size_t nn = std::min(mAttachments.size(), track.NChannels());
91 for (size_t ii = 0; ii < nn; ++ii) {
92 if (mAttachments[ii])
93 mAttachments[ii]->CopyTo(track, ii);
94 }
95}
96
97void ChannelAttachmentsBase::Reparent(const std::shared_ptr<Track> &parent)
98{
99 const size_t nn = mAttachments.size();
100 for (size_t ii = 0; ii < nn; ++ii) {
101 if (mAttachments[ii])
102 mAttachments[ii]->Reparent(parent, ii);
103 }
104}
105
107{
108 const size_t nn = mAttachments.size();
109 for (size_t ii = 0; ii < nn; ++ii) {
110 if (mAttachments[ii])
111 mAttachments[ii]->WriteXMLAttributes(writer, ii);
112 }
113}
114
116 const std::string_view& attr, const XMLAttributeValueView& valueView)
117{
118 size_t ii = 0;
119 return any_of(mAttachments.begin(), mAttachments.end(),
120 [&](auto &pAttachment) {
121 bool result = pAttachment &&
122 pAttachment->HandleXMLAttribute(attr, valueView, ii);
123 ++ii;
124 return result;
125 });
126}
127
128void ChannelAttachmentsBase::MakeStereo(const std::shared_ptr<Track> &parent,
130{
131 assert(typeid(*this) == typeid(other));
132 assert(Size() <= 1);
133 assert(other.Size() <= 1);
134 if (mAttachments.empty())
135 mAttachments.resize(1);
136 auto index = mAttachments.size();
137 for (auto &ptr : other.mAttachments) {
138 if (auto &pAttachment = mAttachments.emplace_back(move(ptr)))
139 pAttachment->Reparent(parent, index++);
140 }
141 other.mAttachments.clear();
142}
143
144void ChannelAttachmentsBase::SwapChannels(const std::shared_ptr<Track> &parent)
145{
146 assert(Size() <= 2);
147 if (mAttachments.empty())
148 return;
149 mAttachments.resize(2);
151 for (auto ii : { 0, 1 })
152 if (const auto &pAttachment = mAttachments[ii])
153 pAttachment->Reparent(parent, ii);
154}
155
156void ChannelAttachmentsBase::Erase(const std::shared_ptr<Track> &parent,
157 size_t index)
158{
159 auto size = mAttachments.size();
160 if (index < size) {
161 mAttachments.erase(mAttachments.begin() + index);
162 for (--size; index < size; ++index)
163 if (auto &pAttachment = mAttachments[index])
164 pAttachment->Reparent(parent, index);
165 }
166}
static RegisteredToolbarFactory factory
Adapts TrackAttachment interface with extra channel index argument.
int min(int a, int b)
static const AudacityProject::AttachedObjects::RegisteredFactory key
virtual ~ChannelAttachment()
virtual void WriteXMLAttributes(XMLWriter &writer, size_t iChannel) const
Serialize persistent attributes.
virtual bool HandleXMLAttribute(const std::string_view &attr, const XMLAttributeValueView &valueView, size_t iChannel)
Deserialize an attribute, returning true if recognized.
virtual void Reparent(const std::shared_ptr< Track > &parent, size_t iChannel)
Object may be shared among tracks but hold a special back-pointer to one of them; reassign it.
virtual void CopyTo(Track &track, size_t iChannel) const
Copy state, for undo/redo purposes.
Holds multiple objects as a single attachment to Track.
std::vector< std::shared_ptr< ChannelAttachment > > mAttachments
void Erase(const std::shared_ptr< Track > &parent, size_t index)
~ChannelAttachmentsBase() override
void SwapChannels(const std::shared_ptr< Track > &parent)
ChannelAttachmentsBase & operator=(const ChannelAttachmentsBase &)=delete
void WriteXMLAttributes(XMLWriter &writer) const override
Serialize persistent attributes.
void Reparent(const std::shared_ptr< Track > &parent) override
Object may be shared among tracks but hold a special back-pointer to one of them; reassign it.
static ChannelAttachment & Get(const AttachedTrackObjects::RegisteredFactory &key, Track &track, size_t iChannel)
std::function< std::shared_ptr< ChannelAttachment >(Track &, size_t)> Factory
static ChannelAttachment * Find(const AttachedTrackObjects::RegisteredFactory &key, Track *pTrack, size_t iChannel)
bool HandleXMLAttribute(const std::string_view &attr, const XMLAttributeValueView &valueView) override
Deserialize an attribute, returning true if recognized.
void CopyTo(Track &track) const override
Copy state, for undo/redo purposes.
void MakeStereo(const std::shared_ptr< Track > &parent, ChannelAttachmentsBase &&other)
ChannelAttachmentsBase(Track &track, Factory factory)
virtual size_t NChannels() const =0
Report the number of channels.
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
Definition: ClientData.h:275
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:110
A view into an attribute value. The class does not take the ownership of the data.
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:25
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:628