Audacity  3.0.3
ODWaveTrackTaskQueue.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  ODWaveTrackTaskQueue.h
6 
7  Created by Michael Chinen (mchinen) on 6/11/08
8  Audacity(R) is copyright (c) 1999-2008 Audacity Team.
9  License: GPL v2. See License.txt.
10 
11 ******************************************************************//*******************************************************************/
18 
19 #include "../Audacity.h"
20 #include "ODWaveTrackTaskQueue.h"
21 
22 #include "ODTask.h"
23 #include "ODManager.h"
24 #include "../WaveTrack.h"
27 {
28 }
29 
31 {
32  //we need to DELETE all ODTasks. We will have to block or wait until block for the active ones.
33  for(unsigned int i=0;i<mTasks.size();i++)
34  {
35  mTasks[i]->TerminateAndBlock();//blocks if active.
36  //small chance we may have rea-added the task back into the queue from a diff thread. - so remove it if we have.
38  mTasks[i].reset();
39  }
40 
41 }
42 
45 {
46  //have to be very careful when dealing with two lists that need to be locked.
47  if(GetNumTasks()!=otherQueue->GetNumTasks())
48  return false;
49 
50  mTasksMutex.Lock();
51  for(unsigned int i=0;i<mTasks.size();i++)
52  {
53  if(!mTasks[i]->CanMergeWith(otherQueue->GetTask(i)))
54  {
55  mTasksMutex.Unlock();
56  return false;
57  }
58  }
59  mTasksMutex.Unlock();
60  return true;
61 }
62 
68  const std::shared_ptr< WaveTrack > &track)
69 {
70  AddWaveTrack(track);
71  mTasksMutex.Lock();
72  for(unsigned int i=0;i<mTasks.size();i++)
73  {
74  mTasks[i]->AddWaveTrack(track);
75  mTasks[i]->SetNeedsODUpdate();
76  }
77  mTasksMutex.Unlock();
78 
79 }
80 
83 {
84  mTracksMutex.Lock();
85  for(unsigned int i=0;i<mTracks.size();i++)
86  {
87  if ( mTracks[i].lock().get() == track )
88  {
89  mTracksMutex.Unlock();
90  return true;
91  }
92  }
93  mTracksMutex.Unlock();
94  return false;
95 }
98  const std::shared_ptr< WaveTrack > &track)
99 {
100 
101  mTracksMutex.Lock();
102  if(track)
103  mTracks.push_back(track);
104 
105  mTracksMutex.Unlock();
106 }
107 
108 void ODWaveTrackTaskQueue::AddTask(std::unique_ptr<ODTask> &&mtask)
109 {
110  ODTask *task = mtask.get();
111 
112  mTasksMutex.Lock();
113  mTasks.push_back(std::move(mtask));
114  mTasksMutex.Unlock();
115 
116  //take all of the tracks in the task.
117  mTracksMutex.Lock();
118  for(int i=0;i<task->GetNumWaveTracks();i++)
119  {
120  //task->GetWaveTrack(i) may return NULL, but we handle it by checking before using.
121  //The other worry that the WaveTrack returned and was deleted in the meantime is also
122  //handled by keeping standard weak pointers to tracks, which give thread safety.
123  mTracks.push_back(task->GetWaveTrack(i));
124  }
125 
126  mTracksMutex.Unlock();
127 
128 }
129 
130 //if the wavetrack is in this queue, and is not the only wavetrack, clones the tasks and schedules it.
132  const std::shared_ptr< WaveTrack > &track)
133 {
134  // First remove expired weak pointers
135  Compress();
136 
137  mTracksMutex.Lock();
138 
139  if(mTracks.size()<2)
140  {
141  //if there is only one track, it is already independent.
142  mTracksMutex.Unlock();
143  return;
144  }
145 
146  for(unsigned int i=0;i<mTracks.size();i++)
147  {
148  if ( mTracks[i].lock() == track )
149  {
150  mTracks[i].reset();
151 
152  //clone the items in order and add them to the ODManager.
153  mTasksMutex.Lock();
154  for(unsigned int j=0;j<mTasks.size();j++)
155  {
156  auto task = mTasks[j]->Clone();
157  mTasks[j]->StopUsingWaveTrack( track.get() );
158  //AddNewTask requires us to relinquish this lock. However, it is safe because ODManager::MakeWaveTrackIndependent
159  //has already locked the m_queuesMutex.
160  mTasksMutex.Unlock();
161  //AddNewTask locks the m_queuesMutex which is already locked by ODManager::MakeWaveTrackIndependent,
162  //so we pass a boolean flag telling it not to lock again.
163  ODManager::Instance()->AddNewTask(std::move(task), false);
164  mTasksMutex.Lock();
165  }
166  mTasksMutex.Unlock();
167  break;
168  }
169  }
170  mTracksMutex.Unlock();
171 }
172 
177 {
178  if(track)
179  {
180  mTracksMutex.Lock();
181  for(unsigned int i=0;i<mTasks.size();i++)
182  {
183  mTasks[i]->DemandTrackUpdate(track,seconds);
184  }
185 
186  mTracksMutex.Unlock();
187  }
188 }
189 
190 
191 //Replaces all instances of a wavetracck with a NEW one (effectively transferes the task.)
193  const std::shared_ptr<Track> &newTrack)
194 {
195  if(oldTrack)
196  {
197  mTasksMutex.Lock();
198  for(unsigned int i=0;i<mTasks.size();i++)
199  mTasks[i]->ReplaceWaveTrack( oldTrack, newTrack );
200  mTasksMutex.Unlock();
201 
202  mTracksMutex.Lock();
203  for(unsigned int i=0;i<mTracks.size();i++)
204  if ( mTracks[i].lock().get() == oldTrack )
205  mTracks[i] = std::static_pointer_cast<WaveTrack>( newTrack );
206  mTracksMutex.Unlock();
207  }
208 }
209 
212 {
213  Compress();
214 
215  int ret = 0;
216  mTracksMutex.Lock();
217  ret=mTracks.size();
218  mTracksMutex.Unlock();
219  return ret;
220 }
221 
224 {
225  int ret = 0;
226  mTasksMutex.Lock();
227  ret=mTasks.size();
228  mTasksMutex.Unlock();
229  return ret;
230 }
231 
234 {
235  ODTask* ret = NULL;
236  mTasksMutex.Lock();
237  if (x < mTasks.size())
238  ret = mTasks[x].get();
239  mTasksMutex.Unlock();
240  return ret;
241 }
242 
243 
244 
245 //returns true if either tracks or tasks are empty
247 {
248  Compress();
249 
250  bool isEmpty;
251  mTracksMutex.Lock();
252  isEmpty = mTracks.size()<=0;
253  mTracksMutex.Unlock();
254 
255  mTasksMutex.Lock();
256  isEmpty = isEmpty || mTasks.size()<=0;
257  mTasksMutex.Unlock();
258 
259  return isEmpty;
260 }
261 
262 //returns true if the foremost task exists and is empty.
264 {
265  mTasksMutex.Lock();
266  if(mTasks.size())
267  {
268  //there is a chance the task got updated and now has more to do, (like when it is joined with a NEW track)
269  //check.
270  mTasks[0]->RecalculatePercentComplete();
271  bool ret;
272  ret = mTasks[0]->IsComplete();
273  mTasksMutex.Unlock();
274 
275  return ret;
276  }
277  mTasksMutex.Unlock();
278  return false;
279 }
280 
283 {
284  mTasksMutex.Lock();
285  if(mTasks.size())
286  {
287  //wait for the task to stop running.
288  mTasks.erase(mTasks.begin());
289  }
290  mTasksMutex.Unlock();
291 }
292 
295 {
296  mTasksMutex.Lock();
297  if(mTasks.size())
298  {
299  mTasksMutex.Unlock();
300  return mTasks[0].get();
301  }
302  mTasksMutex.Unlock();
303  return NULL;
304 }
305 
308  const WaveTrack * t, TranslatableString &tip )
309 {
310  if(ContainsWaveTrack(t) && GetNumTasks())
311  {
312 
313  // if(GetNumTasks()==1)
314  mTipMsg = XO("%s %2.0f%% complete. Click to change task focal point.")
315  .Format(
316  GetFrontTask()->GetTip(),
317  GetFrontTask()->PercentComplete()*100.0 );
318  // else
319  // msg = XO("%s %d additional tasks remaining.")
320  // .Format( GetFrontTask()->GetTip(), GetNumTasks());
321 
322  tip = mTipMsg;
323 
324  }
325 }
326 
328 {
329  mTracksMutex.Lock();
330  auto begin = mTracks.begin(), end = mTracks.end(),
331  new_end = std::remove_if( begin, end,
332  []( const std::weak_ptr<WaveTrack> &ptr ){ return ptr.expired(); } );
333  mTracks.erase( new_end, end );
334  mTracksMutex.Unlock();
335 }
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:69
ODWaveTrackTaskQueue::GetTask
ODTask * GetTask(size_t x)
returns a ODTask at position x
Definition: ODWaveTrackTaskQueue.cpp:233
ODWaveTrackTaskQueue::mTasks
std::vector< std::unique_ptr< ODTask > > mTasks
the list of tasks associated with the tracks. This class owns these tasks.
Definition: ODWaveTrackTaskQueue.h:107
ODWaveTrackTaskQueue::GetFrontTask
ODTask * GetFrontTask()
Schedules the front task for immediate execution.
Definition: ODWaveTrackTaskQueue.cpp:294
ODWaveTrackTaskQueue::GetNumWaveTracks
int GetNumWaveTracks()
returns the number of wavetracks in this queue.
Definition: ODWaveTrackTaskQueue.cpp:211
ODWaveTrackTaskQueue::FillTipForWaveTrack
void FillTipForWaveTrack(const WaveTrack *t, TranslatableString &tip)
fills in the status bar message for a given track
Definition: ODWaveTrackTaskQueue.cpp:307
ODWaveTrackTaskQueue::Compress
void Compress()
Definition: ODWaveTrackTaskQueue.cpp:327
ODWaveTrackTaskQueue::AddTask
void AddTask(std::unique_ptr< ODTask > &&mtask)
Add a task to the queue.
Definition: ODWaveTrackTaskQueue.cpp:108
ODWaveTrackTaskQueue::~ODWaveTrackTaskQueue
virtual ~ODWaveTrackTaskQueue()
Definition: ODWaveTrackTaskQueue.cpp:30
ODManager::AddNewTask
void AddNewTask(std::unique_ptr< ODTask > &&mtask, bool lockMutex=true)
Adds a wavetrack, creates a queue member.
Definition: ODManager.cpp:245
XO
#define XO(s)
Definition: Internat.h:31
ODWaveTrackTaskQueue::IsFrontTaskComplete
bool IsFrontTaskComplete()
Definition: ODWaveTrackTaskQueue.cpp:263
ODWaveTrackTaskQueue::mTracks
std::vector< std::weak_ptr< WaveTrack > > mTracks
the list of tracks associated with this queue.
Definition: ODWaveTrackTaskQueue.h:103
ODWaveTrackTaskQueue::ContainsWaveTrack
bool ContainsWaveTrack(const WaveTrack *track)
returns true if the argument is in the WaveTrack list.
Definition: ODWaveTrackTaskQueue.cpp:82
ODWaveTrackTaskQueue::mTasksMutex
ODLock mTasksMutex
Definition: ODWaveTrackTaskQueue.h:108
ODManager.h
ODWaveTrackTaskQueue::mTracksMutex
ODLock mTracksMutex
Definition: ODWaveTrackTaskQueue.h:104
ODWaveTrackTaskQueue::ReplaceWaveTrack
void ReplaceWaveTrack(Track *oldTrack, const std::shared_ptr< Track > &newTrack)
replaces all instances of a WaveTrack within this task with another.
Definition: ODWaveTrackTaskQueue.cpp:192
ODManager::RemoveTaskIfInQueue
void RemoveTaskIfInQueue(ODTask *task)
removes a task from the active task queue
Definition: ODManager.cpp:225
ODWaveTrackTaskQueue.h
ODWaveTrackTaskQueue::MakeWaveTrackIndependent
void MakeWaveTrackIndependent(const std::shared_ptr< WaveTrack > &track)
Definition: ODWaveTrackTaskQueue.cpp:131
ODWaveTrackTaskQueue::RemoveFrontTask
void RemoveFrontTask()
Removes and deletes the front task from the list.
Definition: ODWaveTrackTaskQueue.cpp:282
ODWaveTrackTaskQueue::CanMergeWith
bool CanMergeWith(ODWaveTrackTaskQueue *otherQueue)
returns whether or not this queue's task list and another's can merge together, as when we make two m...
Definition: ODWaveTrackTaskQueue.cpp:44
ODWaveTrackTaskQueue
A class representing a modular task to be used with the On-Demand structures.
Definition: ODWaveTrackTaskQueue.h:33
ODTask
A class representing a modular task to be used with the On-Demand structures.
Definition: ODTask.h:40
ODWaveTrackTaskQueue::MergeWaveTrack
void MergeWaveTrack(const std::shared_ptr< WaveTrack > &track)
Definition: ODWaveTrackTaskQueue.cpp:67
ODTask.h
ODWaveTrackTaskQueue::ODWaveTrackTaskQueue
ODWaveTrackTaskQueue()
Constructs an ODWaveTrackTaskQueue.
Definition: ODWaveTrackTaskQueue.cpp:26
ODWaveTrackTaskQueue::IsEmpty
bool IsEmpty()
Definition: ODWaveTrackTaskQueue.cpp:246
Track
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:239
ODTask::GetNumWaveTracks
virtual int GetNumWaveTracks()
Definition: ODTask.cpp:273
ODWaveTrackTaskQueue::GetNumTasks
int GetNumTasks()
returns the number of ODTasks in this queue
Definition: ODWaveTrackTaskQueue.cpp:223
ODWaveTrackTaskQueue::mTipMsg
TranslatableString mTipMsg
Definition: ODWaveTrackTaskQueue.h:99
ODTask::GetWaveTrack
virtual std::shared_ptr< WaveTrack > GetWaveTrack(int i)
Definition: ODTask.cpp:255
ODManager::Instance
static ODManager *(* Instance)()
Definition: ODManager.h:51
ODWaveTrackTaskQueue::AddWaveTrack
void AddWaveTrack(const std::shared_ptr< WaveTrack > &track)
Adds a track to the associated list.
Definition: ODWaveTrackTaskQueue.cpp:97
ODWaveTrackTaskQueue::DemandTrackUpdate
void DemandTrackUpdate(WaveTrack *track, double seconds)
changes the tasks associated with this Waveform to process the task from a different point in the tra...
Definition: ODWaveTrackTaskQueue.cpp:176