Audacity  2.2.2
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 #include "ODTask.h"
22 #include "ODManager.h"
25 {
26 }
27 
29 {
30  //we need to DELETE all ODTasks. We will have to block or wait until block for the active ones.
31  for(unsigned int i=0;i<mTasks.size();i++)
32  {
33  mTasks[i]->TerminateAndBlock();//blocks if active.
34  //small chance we may have rea-added the task back into the queue from a diff thread. - so remove it if we have.
36  mTasks[i].reset();
37  }
38 
39 }
40 
43 {
44  //have to be very careful when dealing with two lists that need to be locked.
45  if(GetNumTasks()!=otherQueue->GetNumTasks())
46  return false;
47 
48  mTasksMutex.Lock();
49  for(unsigned int i=0;i<mTasks.size();i++)
50  {
51  if(!mTasks[i]->CanMergeWith(otherQueue->GetTask(i)))
52  {
53  mTasksMutex.Unlock();
54  return false;
55  }
56  }
57  mTasksMutex.Unlock();
58  return true;
59 }
60 
66 {
67  AddWaveTrack(track);
68  mTasksMutex.Lock();
69  for(unsigned int i=0;i<mTasks.size();i++)
70  {
71  mTasks[i]->AddWaveTrack(track);
72  mTasks[i]->SetNeedsODUpdate();
73  }
74  mTasksMutex.Unlock();
75 
76 }
77 
80 {
81  mTracksMutex.Lock();
82  for(unsigned int i=0;i<mTracks.size();i++)
83  {
84  if(mTracks[i]==track)
85  {
86  mTracksMutex.Unlock();
87  return true;
88  }
89  }
90  mTracksMutex.Unlock();
91  return false;
92 }
95 {
96 
97  mTracksMutex.Lock();
98  if(track)
99  mTracks.push_back(track);
100 
101  mTracksMutex.Unlock();
102 }
103 
105 {
106  ODTask *task = mtask.get();
107 
108  mTasksMutex.Lock();
109  mTasks.push_back(std::move(mtask));
110  mTasksMutex.Unlock();
111 
112  //take all of the tracks in the task.
113  mTracksMutex.Lock();
114  for(int i=0;i<task->GetNumWaveTracks();i++)
115  {
116  //task->GetWaveTrack(i) may return NULL, but we handle it by checking before using.
117  //The other worry that the WaveTrack returned and was deleted in the meantime is also
118  //handled since mQueuesMutex is locked one up in the stack from here,
119  //and WaveTrack deletion is bound to that.
120  mTracks.push_back(task->GetWaveTrack(i));
121  }
122 
123  mTracksMutex.Unlock();
124 
125 }
126 
130 {
131  if(track)
132  {
133 
134  mTasksMutex.Lock();
135  for(unsigned int i=0;i<mTasks.size();i++)
136  mTasks[i]->StopUsingWaveTrack(track);
137  mTasksMutex.Unlock();
138 
139  mTracksMutex.Lock();
140  for(unsigned int i=0;i<mTracks.size();i++)
141  if(mTracks[i]==track)
142  mTracks.erase(mTracks.begin()+i--);//decrement i after the removal.
143 
144  mTracksMutex.Unlock();
145  }
146 }
147 
148 //if the wavetrack is in this queue, and is not the only wavetrack, clones the tasks and schedules it.
150 {
151 
152  mTracksMutex.Lock();
153  if(mTracks.size()<2)
154  {
155  //if there is only one track, it is already independent.
156  mTracksMutex.Unlock();
157  return;
158  }
159 
160  for(unsigned int i=0;i<mTracks.size();i++)
161  {
162  if(mTracks[i]==track)
163  {
164  mTracksMutex.Unlock();//release the lock, since RemoveWaveTrack is a public threadsafe method.
166 
167  //clone the items in order and add them to the ODManager.
168  mTasksMutex.Lock();
169  for(unsigned int j=0;j<mTasks.size();j++)
170  {
171  auto task = mTasks[j]->Clone();
172  task->AddWaveTrack(track);
173  //AddNewTask requires us to relinquish this lock. However, it is safe because ODManager::MakeWaveTrackIndependent
174  //has already locked the m_queuesMutex.
175  mTasksMutex.Unlock();
176  //AddNewTask locks the m_queuesMutex which is already locked by ODManager::MakeWaveTrackIndependent,
177  //so we pass a boolean flag telling it not to lock again.
178  ODManager::Instance()->AddNewTask(std::move(task), false);
179  mTasksMutex.Lock();
180  }
181  mTasksMutex.Unlock();
182  mTracksMutex.Lock();
183  break;
184  }
185  }
186  mTracksMutex.Unlock();
187 }
188 
193 {
194  if(track)
195  {
196  mTracksMutex.Lock();
197  for(unsigned int i=0;i<mTasks.size();i++)
198  {
199  mTasks[i]->DemandTrackUpdate(track,seconds);
200  }
201 
202  mTracksMutex.Unlock();
203  }
204 }
205 
206 
207 //Replaces all instances of a wavetracck with a NEW one (effectively transferes the task.)
209 {
210  if(oldTrack)
211  {
212  mTasksMutex.Lock();
213  for(unsigned int i=0;i<mTasks.size();i++)
214  mTasks[i]->ReplaceWaveTrack(oldTrack,newTrack);
215  mTasksMutex.Unlock();
216 
217  mTracksMutex.Lock();
218  for(unsigned int i=0;i<mTracks.size();i++)
219  if(mTracks[i]==oldTrack)
220  mTracks[i]=newTrack;
221  mTracksMutex.Unlock();
222  }
223 }
224 
225 //returns the wavetrack at position x.
227 {
228  WaveTrack* ret = NULL;
229  mTracksMutex.Lock();
230  if (x < mTracks.size())
231  ret = mTracks[x];
232  mTracksMutex.Unlock();
233  return ret;
234 }
235 
238 {
239  int ret = 0;
240  mTracksMutex.Lock();
241  ret=mTracks.size();
242  mTracksMutex.Unlock();
243  return ret;
244 }
245 
248 {
249  int ret = 0;
250  mTasksMutex.Lock();
251  ret=mTasks.size();
252  mTasksMutex.Unlock();
253  return ret;
254 }
255 
258 {
259  ODTask* ret = NULL;
260  mTasksMutex.Lock();
261  if (x < mTasks.size())
262  ret = mTasks[x].get();
263  mTasksMutex.Unlock();
264  return ret;
265 }
266 
267 
268 
269 //returns true if either tracks or tasks are empty
271 {
272  bool isEmpty;
273  mTracksMutex.Lock();
274  isEmpty = mTracks.size()<=0;
275  mTracksMutex.Unlock();
276 
277  mTasksMutex.Lock();
278  isEmpty = isEmpty || mTasks.size()<=0;
279  mTasksMutex.Unlock();
280 
281  return isEmpty;
282 }
283 
284 //returns true if the foremost task exists and is empty.
286 {
287  mTasksMutex.Lock();
288  if(mTasks.size())
289  {
290  //there is a chance the task got updated and now has more to do, (like when it is joined with a NEW track)
291  //check.
292  mTasks[0]->RecalculatePercentComplete();
293  bool ret;
294  ret = mTasks[0]->IsComplete();
295  mTasksMutex.Unlock();
296 
297  return ret;
298  }
299  mTasksMutex.Unlock();
300  return false;
301 }
302 
305 {
306  mTasksMutex.Lock();
307  if(mTasks.size())
308  {
309  //wait for the task to stop running.
310  mTasks.erase(mTasks.begin());
311  }
312  mTasksMutex.Unlock();
313 }
314 
317 {
318  mTasksMutex.Lock();
319  if(mTasks.size())
320  {
321  mTasksMutex.Unlock();
322  return mTasks[0].get();
323  }
324  mTasksMutex.Unlock();
325  return NULL;
326 }
327 
329 void ODWaveTrackTaskQueue::FillTipForWaveTrack( const WaveTrack * t, wxString &tip )
330 {
331  if(ContainsWaveTrack(t) && GetNumTasks())
332  {
333 
334  // if(GetNumTasks()==1)
335  mTipMsg.Printf(_("%s %2.0f%% complete. Click to change task focal point."), GetFrontTask()->GetTip(), GetFrontTask()->PercentComplete()*100.0 );
336  // else
337  // msg.Printf(_("%s %d additional tasks remaining."), GetFrontTask()->GetTip(), GetNumTasks());
338 
339  tip = mTipMsg;
340 
341  }
342 }
void MergeWaveTrack(WaveTrack *track)
void AddNewTask(movable_ptr< ODTask > &&mtask, bool lockMutex=true)
Adds a wavetrack, creates a queue member.
Definition: ODManager.cpp:145
static ODManager *(* Instance)()
Definition: ODManager.h:49
std::unique_ptr< T > movable_ptr
Definition: MemoryX.h:734
ODTask * GetFrontTask()
Schedules the front task for immediate execution.
void AddWaveTrack(WaveTrack *track)
Adds a track to the associated list.
void RemoveFrontTask()
Removes and deletes the front task from the list.
void AddTask(movable_ptr< ODTask > &&mtask)
Add a task to the queue.
int GetNumWaveTracks()
returns the number of wavetracks in this queue.
std::vector< WaveTrack * > mTracks
the list of tracks associated with this queue.
A class representing a modular task to be used with the On-Demand structures.
Definition: ODTask.h:39
bool ContainsWaveTrack(const WaveTrack *track)
returns true if the argument is in the WaveTrack list.
void FillTipForWaveTrack(const WaveTrack *t, wxString &tip)
fills in the status bar message for a given track
WaveTrack * GetWaveTrack(size_t x)
void RemoveWaveTrack(WaveTrack *track)
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
virtual WaveTrack * GetWaveTrack(int i)
Definition: ODTask.cpp:261
void RemoveTaskIfInQueue(ODTask *task)
removes a task from the active task queue
Definition: ODManager.cpp:125
int GetNumTasks()
returns the number of ODTasks in this queue
virtual int GetNumWaveTracks()
Definition: ODTask.cpp:279
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
void DemandTrackUpdate(WaveTrack *track, double seconds)
changes the tasks associated with this Waveform to process the task from a different point in the tra...
void MakeWaveTrackIndependent(WaveTrack *track)
ODWaveTrackTaskQueue()
Constructs an ODWaveTrackTaskQueue.
ODTask * GetTask(size_t x)
returns a ODTask at position x
A class representing a modular task to be used with the On-Demand structures.
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...
void ReplaceWaveTrack(WaveTrack *oldTrack, WaveTrack *newTrack)
replaces all instances of a WaveTrack within this task with another.
std::vector< movable_ptr< ODTask > > mTasks
the list of tasks associated with the tracks. This class owns these tasks.