1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-30 23:23:44 +02:00

Fix whitespace and comments in ODComputeSummaryTask and ODManager

This commit is contained in:
mchinen 2010-07-19 13:25:52 +00:00
parent f918edb36a
commit 0fac236e9a
4 changed files with 167 additions and 219 deletions

View File

@ -31,33 +31,29 @@ ODComputeSummaryTask::ODComputeSummaryTask()
mMaxBlockFiles = 0;
mComputedBlockFiles = 0;
mHasUpdateRan=false;
}
ODTask* ODComputeSummaryTask::Clone()
{
ODComputeSummaryTask* clone = new ODComputeSummaryTask;
clone->mDemandSample=GetDemandSample();
return clone;
}
///releases memory that the ODTask owns. Subclasses should override.
void ODComputeSummaryTask::Terminate()
{
//The terminate cblock won't allow DoSomeInternal and this method to be run async, so this is thread-safe
//we are going to take things out of the array. But first deref them since we ref them when we put them in.
//The terminate block won't allow DoSomeInternal and this method to be run async, so this is thread-safe.
//Deref the block files since they are ref'ed when put into the array.
mBlockFilesMutex.Lock();
for(unsigned int i=0;i<mBlockFiles.size();i++)
mBlockFiles[i]->Deref();
mBlockFiles.clear();
mBlockFilesMutex.Unlock();
}
///Computes and writes the data for one BlockFile if it still has a refcount.
}
///Computes and writes the data for one BlockFile if it still has a refcount.
void ODComputeSummaryTask::DoSomeInternal()
{
if(mBlockFiles.size()<=0)
@ -67,19 +63,18 @@ void ODComputeSummaryTask::DoSomeInternal()
mPercentCompleteMutex.Unlock();
return;
}
ODPCMAliasBlockFile* bf;
sampleCount blockStartSample;
sampleCount blockEndSample;
bool success =false;
mBlockFilesMutex.Lock();
for(size_t i=0; i < mWaveTracks.size() && mBlockFiles.size();i++)
{
bf = mBlockFiles[0];
//first check to see if the ref count is at least 2. It should have one
//first check to see if the ref count is at least 2. It should have one
//from when we added it to this instance's mBlockFiles array, and one from
//the Wavetrack/sequence. If it doesn't it has been deleted and we should forget it.
if(bf->RefCount()>=2)
@ -96,19 +91,18 @@ void ODComputeSummaryTask::DoSomeInternal()
//because now there is less work to do.
mMaxBlockFiles--;
}
//Release the refcount we placed on it.
bf->Deref();
//take it out of the array - we are done with it.
mBlockFiles.erase(mBlockFiles.begin());
//This is a bit of a convenience in case someone tries to terminate the task by closing the trackpanel or window.
//ODComputeSummaryTask::Terminate() uses this lock to remove everything, and we don't want it to wait since the UI is being blocked.
//This is a bit of a convenience in case someone tries to terminate the task by closing the trackpanel or window.
//ODComputeSummaryTask::Terminate() uses this lock to remove everything, and we don't want it to wait since the UI is being blocked.
mBlockFilesMutex.Unlock();
wxThread::This()->Yield();
mBlockFilesMutex.Lock();
//upddate the gui for all associated blocks. It doesn't matter that we're hitting more wavetracks then we should
//because this loop runs a number of times equal to the number of tracks, they probably are getting processed in
//the next iteration at the same sample window.
@ -119,28 +113,26 @@ void ODComputeSummaryTask::DoSomeInternal()
mWaveTracks[i]->AddInvalidRegion(blockStartSample,blockEndSample);
}
mWaveTrackMutex.Unlock();
}
}
mBlockFilesMutex.Unlock();
//update percentage complete.
CalculatePercentComplete();
}
///compute the next time we should take a break in terms of overall percentage.
///We want to do a constant number of blockfiles.
///We want to do a constant number of blockfiles.
float ODComputeSummaryTask::ComputeNextWorkUntilPercentageComplete()
{
if(mMaxBlockFiles==0)
return 1.0;
float nextPercent;
mPercentCompleteMutex.Lock();
nextPercent=mPercentComplete + ((float)kNumBlockFilesPerDoSome/(mMaxBlockFiles+1));
mPercentCompleteMutex.Unlock();
return nextPercent;
}
@ -149,7 +141,7 @@ void ODComputeSummaryTask::MarkUpdateRan()
mHasUpdateRanMutex.Lock();
mHasUpdateRan=true;
mHasUpdateRanMutex.Unlock();
}
}
bool ODComputeSummaryTask::HasUpdateRan()
{
@ -172,14 +164,14 @@ void ODComputeSummaryTask::CalculatePercentComplete()
mPercentCompleteMutex.Unlock();
}
///by default creates the order of the wavetrack to load.
///creates the order of the wavetrack to load.
///by default left to right, or frome the point the user has clicked.
void ODComputeSummaryTask::Update()
{
std::vector<ODPCMAliasBlockFile*> tempBlocks;
mWaveTrackMutex.Lock();
for(size_t j=0;j<mWaveTracks.size();j++)
{
if(mWaveTracks[j])
@ -187,27 +179,27 @@ void ODComputeSummaryTask::Update()
WaveClip *clip;
BlockArray *blocks;
Sequence *seq;
//gather all the blockfiles that we should process in the wavetrack.
WaveClipList::compatibility_iterator node = mWaveTracks[j]->GetClipIterator();
while(node) {
clip = node->GetData();
seq = clip->GetSequence();
//This lock may be way too big since the whole file is one sequence.
//This lock may be way too big since the whole file is one sequence.
//TODO: test for large files and find a way to break it down.
seq->LockDeleteUpdateMutex();
//See Sequence::Delete() for why need this for now..
//We don't need the mBlockFilesMutex here because it is only for the vector list.
//These are existing blocks, and its wavetrack or blockfiles won't be deleted because
//of the respective mWaveTrackMutex lock and LockDeleteUpdateMutex() call.
//We don't need the mBlockFilesMutex here because it is only for the vector list.
//These are existing blocks, and its wavetrack or blockfiles won't be deleted because
//of the respective mWaveTrackMutex lock and LockDeleteUpdateMutex() call.
blocks = clip->GetSequenceBlockArray();
int i;
int insertCursor;
insertCursor =0;//OD TODO:see if this works, removed from inner loop (bfore was n*n)
for(i=0; i<(int)blocks->GetCount(); i++)
{
//if there is data but no summary, this blockfile needs summarizing.
@ -216,59 +208,59 @@ void ODComputeSummaryTask::Update()
blocks->Item(i)->f->Ref();
((ODPCMAliasBlockFile*)blocks->Item(i)->f)->SetStart(blocks->Item(i)->start);
((ODPCMAliasBlockFile*)blocks->Item(i)->f)->SetClipOffset((sampleCount)(clip->GetStartTime()*clip->GetRate()));
//these will always be linear within a sequence-lets take advantage of this by keeping a cursor.
while(insertCursor<(int)tempBlocks.size()&&
(sampleCount)(tempBlocks[insertCursor]->GetStart()+tempBlocks[insertCursor]->GetClipOffset()) <
while(insertCursor<(int)tempBlocks.size()&&
(sampleCount)(tempBlocks[insertCursor]->GetStart()+tempBlocks[insertCursor]->GetClipOffset()) <
(sampleCount)(((ODPCMAliasBlockFile*)blocks->Item(i)->f)->GetStart()+((ODPCMAliasBlockFile*)blocks->Item(i)->f)->GetClipOffset()))
insertCursor++;
tempBlocks.insert(tempBlocks.begin()+insertCursor++,(ODPCMAliasBlockFile*)blocks->Item(i)->f);
}
}
}
seq->UnlockDeleteUpdateMutex();
node = node->GetNext();
}
}
}
mWaveTrackMutex.Unlock();
//get the new order.
mBlockFilesMutex.Lock();
OrderBlockFiles(tempBlocks);
mBlockFilesMutex.Unlock();
MarkUpdateRan();
}
///Orders the input as either On-Demand or default layered order.
///Computes the summary calculation queue order of the blockfiles
void ODComputeSummaryTask::OrderBlockFiles(std::vector<ODPCMAliasBlockFile*> &unorderedBlocks)
{
//we are going to take things out of the array. But first deref them since we ref them when we put them in.
for(unsigned int i=0;i<mBlockFiles.size();i++)
mBlockFiles[i]->Deref();
mBlockFiles.clear();
//TODO:order the blockfiles into our queue in a fancy convenient way. (this could be user-prefs)
//Order the blockfiles into our queue in a fancy convenient way. (this could be user-prefs)
//for now just put them in linear. We start the order from the first block that includes the ondemand sample
//(which the user sets by clicking.)
//(which the user sets by clicking.)
//Note that this code assumes that the array is sorted in time.
//find the startpoint
sampleCount processStartSample = GetDemandSample();
sampleCount processStartSample = GetDemandSample();
for(int i= ((int)unorderedBlocks.size())-1;i>= 0;i--)
{
//check to see if the refcount is at least two before we add it to the list.
//There should be one Ref() from the one added by this ODTask, and one from the track.
//There should be one Ref() from the one added by this ODTask, and one from the track.
//If there isn't, then the block was deleted for some reason and we should ignore it.
if(unorderedBlocks[i]->RefCount()>=2)
{
//test if the blockfiles are near the task cursor. we use the last mBlockFiles[0] as our point of reference
//and add ones that are closer.
if(mBlockFiles.size() &&
unorderedBlocks[i]->GetGlobalEnd() >= processStartSample &&
( mBlockFiles[0]->GetGlobalEnd() < processStartSample ||
if(mBlockFiles.size() &&
unorderedBlocks[i]->GetGlobalEnd() >= processStartSample &&
( mBlockFiles[0]->GetGlobalEnd() < processStartSample ||
unorderedBlocks[i]->GetGlobalStart() <= mBlockFiles[0]->GetGlobalStart())
)
{
@ -289,5 +281,4 @@ void ODComputeSummaryTask::OrderBlockFiles(std::vector<ODPCMAliasBlockFile*> &un
unorderedBlocks[i]->Deref();
}
}
}
}

View File

@ -16,9 +16,6 @@ updating the ODPCMAliasBlockFile and the GUI of the newly available data.
*//*******************************************************************/
#ifndef __AUDACITY_ODComputeSummaryTask__
#define __AUDACITY_ODComputeSummaryTask__
@ -54,10 +51,8 @@ class ODComputeSummaryTask:public ODTask
///releases memory that the ODTask owns. Subclasses should override.
virtual void Terminate();
protected:
///recalculates the percentage complete.
virtual void CalculatePercentComplete();
@ -78,17 +73,10 @@ protected:
//mBlockFiles is touched on several threads- the OD terminate thread, and the task thread, so we need to mutex it.
ODLock mBlockFilesMutex;
std::vector<ODPCMAliasBlockFile*> mBlockFiles;
int mMaxBlockFiles;
int mComputedBlockFiles;
ODLock mHasUpdateRanMutex;
bool mHasUpdateRan;
};
#endif

View File

@ -10,7 +10,7 @@
\file ODManager.cpp
\brief Singleton ODManager class. Is the bridge between client side
ODTask requests and internals.
ODTask requests and internals.
*//*******************************************************************/
@ -28,11 +28,11 @@ ODTask requests and internals.
ODLock gODInitedMutex;
bool gManagerCreated=false;
bool gPause=false; //to be loaded in and used with Pause/Resume before ODMan init.
/// a flag that is set if we have loaded some OD blockfiles from PCM.
/// a flag that is set if we have loaded some OD blockfiles from PCM.
bool sHasLoadedOD=false;
ODManager* ODManager::pMan=NULL;
//init the accessor function pointer - use the first time version of the interface fetcher
ODManager* ODManager::pMan=NULL;
//init the accessor function pointer - use the first time version of the interface fetcher
//first we need to typedef the function pointer type because the compiler doesn't support it in the raw
typedef ODManager* (*pfodman)();
pfodman ODManager::Instance = &(ODManager::InstanceFirstTime);
@ -42,7 +42,7 @@ ODLock sLibSndFileMutex;
DEFINE_EVENT_TYPE(EVT_ODTASK_UPDATE)
//using this with wxStringArray::Sort will give you a list that
//using this with wxStringArray::Sort will give you a list that
//is alphabetical, without depending on case. If you use the
//default sort, you will get strings with 'R' before 'a', because it is in caps.
int CompareNoCaseFileName(const wxString& first, const wxString& second)
@ -67,7 +67,7 @@ ODManager::ODManager()
mTerminate = false;
mTerminated = false;
mPause= gPause;
//must set up the queue condition
mQueueNotEmptyCond = new ODCondition(&mQueueNotEmptyCondLock);
}
@ -83,17 +83,15 @@ ODManager::~ODManager()
delete mQueueNotEmptyCond;
}
///Adds a task to running queue. Thread-safe.
void ODManager::AddTask(ODTask* task)
{
mTasksMutex.Lock();
mTasks.push_back(task);
mTasksMutex.Unlock();
//signal the queue not empty condition.
//signal the queue not empty condition.
bool paused;
mPauseLock.Lock();
paused=mPause;
mPauseLock.Unlock();
@ -103,13 +101,12 @@ void ODManager::AddTask(ODTask* task)
if(!paused)
mQueueNotEmptyCond->Signal();
mQueueNotEmptyCondLock.Unlock();
}
void ODManager::SignalTaskQueueLoop()
{
bool paused;
mPauseLock.Lock();
paused=mPause;
mPauseLock.Unlock();
@ -154,7 +151,7 @@ void ODManager::AddNewTask(ODTask* task, bool lockMutex)
if(mQueues[i]->ContainsWaveTrack(task->GetWaveTrack(0)))
queue=mQueues[i];
}
if(queue)
{
//Add it to the existing queue but keep the lock since this reference can be deleted.
@ -171,12 +168,11 @@ void ODManager::AddNewTask(ODTask* task, bool lockMutex)
mQueues.push_back(queue);
if(lockMutex)
mQueuesMutex.Unlock();
AddTask(task);
}
}
//that switches out the mutex/null check.
ODManager* ODManager::InstanceFirstTime()
{
@ -188,10 +184,10 @@ ODManager* ODManager::InstanceFirstTime()
gManagerCreated = true;
}
gODInitedMutex.Unlock();
//change the accessor function to use the quicker method.
Instance = &(ODManager::InstanceNormal);
return pMan;
}
@ -215,15 +211,15 @@ void ODManager::Init()
{
mCurrentThreads = 0;
mMaxThreads = 5;
// wxLogDebug(wxT("Initializing ODManager...Creating manager thread\n"));
ODManagerHelperThread* startThread = new ODManagerHelperThread;
// startThread->SetPriority(0);//default of 50.
startThread->Create();
// printf("starting thread from init\n");
startThread->Run();
// printf("started thread from init\n");
//destruction of thread is taken care of by thread library
}
@ -237,12 +233,12 @@ void ODManager::DecrementCurrentThreads()
///Main loop for managing threads and tasks.
void ODManager::Start()
{
{
ODTaskThread* thread;
bool tasksInArray;
bool paused;
int numQueues=0;
mNeedsDraw=0;
//wxLog calls not threadsafe. are printfs? thread-messy for sure, but safe?
@ -254,54 +250,52 @@ void ODManager::Start()
{
mTerminateMutex.Unlock();
// printf("ODManager thread running \n");
//we should look at our WaveTrack queues to see if we can process a new task to the running queue.
UpdateQueues();
//start some threads if necessary
mTasksMutex.Lock();
tasksInArray = mTasks.size()>0;
mTasksMutex.Unlock();
mCurrentThreadsMutex.Lock();
mPauseLock.Lock();
paused=mPause;
mPauseLock.Unlock();
// keep adding tasks if there is work to do, up to the limit.
while(!paused && tasksInArray && (mCurrentThreads < mMaxThreads))
{
mCurrentThreads++;
mCurrentThreadsMutex.Unlock();
//remove the head
//detach a new thread.
thread = new ODTaskThread(mTasks[0]);//task);
// thread->SetPriority(10);//default is 50.
//thread->SetPriority(10);//default is 50.
thread->Create();
thread->Run();
mTasks.erase(mTasks.begin());
mTasks.erase(mTasks.begin());
tasksInArray = mTasks.size()>0;
mTasksMutex.Unlock();
mCurrentThreadsMutex.Lock();
}
mCurrentThreadsMutex.Unlock();
//use a conditon variable to block here instead of a sleep.
//use a conditon variable to block here instead of a sleep.
// JKC: If there are no tasks ready to run, or we're paused then
// JKC: If there are no tasks ready to run, or we're paused then
// we wait for there to be tasks in the queue.
mQueueNotEmptyCondLock.Lock();
if( (!tasksInArray) || paused)
mQueueNotEmptyCond->Wait();
mQueueNotEmptyCondLock.Unlock();
//if there is some ODTask running, then there will be something in the queue. If so then redraw to show progress
mQueueNotEmptyCondLock.Unlock();
//if there is some ODTask running, then there will be something in the queue. If so then redraw to show progress
mQueuesMutex.Lock();
mNeedsDraw += mQueues.size()>0?1:0;
numQueues=mQueues.size();
@ -319,15 +313,15 @@ void ODManager::Start()
if(proj)
proj->AddPendingEvent( event );
AudacityProject::AllProjectsDeleteUnlock();
}
}
mTerminateMutex.Lock();
}
mTerminateMutex.Unlock();
mTerminatedMutex.Lock();
mTerminated=true;
mTerminatedMutex.Unlock();
//wxLogDebug Not thread safe.
//printf("ODManager thread terminating\n");
@ -343,7 +337,7 @@ void ODManager::Pause(bool pause)
pMan->mPauseLock.Lock();
pMan->mPause = pause;
pMan->mPauseLock.Unlock();
//we should check the queue again.
pMan->mQueueNotEmptyCondLock.Lock();
pMan->mQueueNotEmptyCond->Signal();
@ -367,13 +361,15 @@ void ODManager::Quit()
pMan->mTerminateMutex.Lock();
pMan->mTerminate = true;
pMan->mTerminateMutex.Unlock();
//This while loop waits for ODTasks to finish and the delete removes all tasks from the Queue.
//This function is called from the main audacity event thread, so there should not be more requests for pMan
pMan->mTerminatedMutex.Lock();
while(!pMan->mTerminated)
{
pMan->mTerminatedMutex.Unlock();
wxThread::Sleep(200);
//signal the queue not empty condition since the ODMan thread will wait on the queue condition
pMan->mQueueNotEmptyCondLock.Lock();
pMan->mQueueNotEmptyCond->Signal();
@ -382,15 +378,11 @@ void ODManager::Quit()
pMan->mTerminatedMutex.Lock();
}
pMan->mTerminatedMutex.Unlock();
delete pMan;
//The above while loop waits for ODTasks to finish and the delete removes all tasks from the Queue.
//This function is called from the main audacity event thread, so there should not be more requests for pMan
}
}
///removes a wavetrack and notifies its associated tasks to stop using its reference.
///removes a wavetrack and notifies its associated tasks to stop using its reference.
void ODManager::RemoveWaveTrack(WaveTrack* track)
{
mQueuesMutex.Lock();
@ -411,7 +403,7 @@ void ODManager::ReplaceWaveTrack(WaveTrack* oldTrack,WaveTrack* newTrack)
mQueues[i]->ReplaceWaveTrack(oldTrack,newTrack);
}
mQueuesMutex.Unlock();
}
}
///if it shares a queue/task, creates a new queue/task for the track, and removes it from any previously existing tasks.
void ODManager::MakeWaveTrackIndependent(WaveTrack* track)
@ -430,24 +422,22 @@ void ODManager::MakeWaveTrackIndependent(WaveTrack* track)
owner->MakeWaveTrackIndependent(track);
mQueuesMutex.Unlock();
}
///attach the track in question to another, already existing track's queues and tasks. Remove the task/tracks.
///only works if both tracks exist. Sets needODUpdate flag for the task. This is complicated and will probably need
///better design in the future.
///@return returns success. Some ODTask conditions require that the tasks finish before merging.
///e.g. they have different effects being processed at the same time.
///@return returns success. Some ODTask conditions require that the tasks finish before merging.
///e.g. they have different effects being processed at the same time.
bool ODManager::MakeWaveTrackDependent(WaveTrack* dependentTrack,WaveTrack* masterTrack)
{
//First, check to see if the task lists are mergeable. If so, we can simply add this track to the other task and queue,
//First, check to see if the task lists are mergeable. If so, we can simply add this track to the other task and queue,
//then delete this one.
ODWaveTrackTaskQueue* masterQueue=NULL;
ODWaveTrackTaskQueue* dependentQueue=NULL;
unsigned int dependentIndex;
bool canMerge = false;
mQueuesMutex.Lock();
for(unsigned int i=0;i<mQueues.size();i++)
{
@ -465,17 +455,16 @@ bool ODManager::MakeWaveTrackDependent(WaveTrack* dependentTrack,WaveTrack* mast
if(masterQueue&&dependentQueue)
canMerge=masterQueue->CanMergeWith(dependentQueue);
//otherwise we need to let dependentTrack's queue live on. We'll have to wait till the conflicting tasks are done.
if(!canMerge)
{
{
mQueuesMutex.Unlock();
return false;
}
}
//then we add dependentTrack to the masterTrack's queue - this will allow future ODScheduling to affect them together.
//this sets the NeedODUpdateFlag since we don't want the head task to finish without haven't dealt with the depednent
masterQueue->MergeWaveTrack(dependentTrack);
//finally remove the dependent track
mQueues.erase(mQueues.begin()+dependentIndex);
mQueuesMutex.Unlock();
@ -495,9 +484,8 @@ void ODManager::DemandTrackUpdate(WaveTrack* track, double seconds)
mQueues[i]->DemandTrackUpdate(track,seconds);
}
mQueuesMutex.Unlock();
}
///remove tasks from ODWaveTrackTaskQueues that have been done. Schedules new ones if they exist
///Also remove queues that have become empty.
void ODManager::UpdateQueues()
@ -505,7 +493,6 @@ void ODManager::UpdateQueues()
mQueuesMutex.Lock();
for(unsigned int i=0;i<mQueues.size();i++)
{
if(mQueues[i]->IsFrontTaskComplete())
{
//this should delete and remove the front task instance.
@ -517,11 +504,11 @@ void ODManager::UpdateQueues()
//so get a temp.
ODWaveTrackTaskQueue* queue;
queue = mQueues[i];
AddTask(queue->GetFrontTask());
}
}
//if the queue is empty delete it.
if(mQueues[i]->IsEmpty())
{
@ -531,25 +518,24 @@ void ODManager::UpdateQueues()
}
}
mQueuesMutex.Unlock();
}
//static
///sets a flag that is set if we have loaded some OD blockfiles from PCM.
//static
///sets a flag that is set if we have loaded some OD blockfiles from PCM.
void ODManager::MarkLoadedODFlag()
{
sHasLoadedOD = true;
}
//static
///resets a flag that is set if we have loaded some OD blockfiles from PCM.
}
//static
///resets a flag that is set if we have loaded some OD blockfiles from PCM.
void ODManager::UnmarkLoadedODFlag()
{
sHasLoadedOD = false;
}
//static
///returns a flag that is set if we have loaded some OD blockfiles from PCM.
//static
///returns a flag that is set if we have loaded some OD blockfiles from PCM.
bool ODManager::HasLoadedODFlag()
{
return sHasLoadedOD;
@ -576,12 +562,12 @@ float ODManager::GetOverallPercentComplete()
total+=mQueues[i]->GetFrontTask()->PercentComplete();
}
mQueuesMutex.Unlock();
//avoid div by zero and be thread smart.
int totalTasks = GetTotalNumTasks();
return (float) total/(totalTasks>0?totalTasks:1);
}
///Get Total Number of Tasks.
int ODManager::GetTotalNumTasks()
{

View File

@ -3,7 +3,7 @@
Audacity: A Digital Audio Editor
ODManager.h
Created by Michael Chinen (mchinen) on 6/8/08
Audacity(R) is copyright (c) 1999-2008 Audacity Team.
License: GPL v2. See License.txt.
@ -11,39 +11,32 @@
******************************************************************//**
\class ODManager
\brief A singleton that manages currently running Tasks on an arbitrary
\brief A singleton that manages currently running Tasks on an arbitrary
number of threads.
*//*******************************************************************/
#ifndef __AUDACITY_ODMANAGER__
#define __AUDACITY_ODMANAGER__
#include <vector>
#include "ODTask.h"
#include "ODTaskThread.h"
#include <wx/thread.h>
#include <wx/wx.h>
#ifdef __WXMAC__
// On Mac OS X, it's better not to use the wxThread class.
// We use our own implementation based on pthreads instead.
#include <pthread.h>
#include <time.h>
#endif //__WXMAC__
DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_ODTASK_UPDATE, -1)
///wxstring compare function for sorting case, which is needed to load correctly.
int CompareNoCaseFileName(const wxString& first, const wxString& second);
/// A singleton that manages currently running Tasks on an arbitrary
/// A singleton that manages currently running Tasks on an arbitrary
/// number of threads.
class WaveTrack;
class ODWaveTrackTaskQueue;
@ -57,61 +50,61 @@ class ODManager
static ODManager* InstanceFirstTime();
///Gets the singleton instance
static ODManager* InstanceNormal();
///Kills the ODMananger Thread.
static void Quit();
static void Quit();
///changes the tasks associated with this Waveform to process the task from a different point in the track
void DemandTrackUpdate(WaveTrack* track, double seconds);
///Reduces the count of current threads running. Meant to be called when ODTaskThreads end in their own threads. Thread-safe.
void DecrementCurrentThreads();
///Adds a wavetrack, creates a queue member.
///Adds a wavetrack, creates a queue member.
void AddNewTask(ODTask* task, bool lockMutex=true);
///Wakes the queue loop up by signalling its condition variable.
void SignalTaskQueueLoop();
///removes a wavetrack and notifies its associated tasks to stop using its reference.
///removes a wavetrack and notifies its associated tasks to stop using its reference.
void RemoveWaveTrack(WaveTrack* track);
///if it shares a queue/task, creates a new queue/task for the track, and removes it from any previously existing tasks.
void MakeWaveTrackIndependent(WaveTrack* track);
///attach the track in question to another, already existing track's queues and tasks. Remove the task/tracks.
///Returns success if it was possible.. Some ODTask conditions make it impossible until the Tasks finish.
bool MakeWaveTrackDependent(WaveTrack* dependentTrack,WaveTrack* masterTrack);
///replace the wavetrack whose wavecache the gui watches for updates
void ReplaceWaveTrack(WaveTrack* oldTrack,WaveTrack* newTrack);
void ReplaceWaveTrack(WaveTrack* oldTrack,WaveTrack* newTrack);
///Adds a task to the running queue. Threas-safe.
void AddTask(ODTask* task);
void RemoveTaskIfInQueue(ODTask* task);
///sets a flag that is set if we have loaded some OD blockfiles from PCM.
///sets a flag that is set if we have loaded some OD blockfiles from PCM.
static void MarkLoadedODFlag();
///resets a flag that is set if we have loaded some OD blockfiles from PCM.
///resets a flag that is set if we have loaded some OD blockfiles from PCM.
static void UnmarkLoadedODFlag();
///returns a flag that is set if we have loaded some OD blockfiles from PCM.
///returns a flag that is set if we have loaded some OD blockfiles from PCM.
static bool HasLoadedODFlag();
///returns whether or not the singleton instance was created yet
static bool IsInstanceCreated();
///fills in the status bar message for a given track
void FillTipForWaveTrack( WaveTrack * t, const wxChar ** ppTip );
///Gets the total percent complete for all tasks combined.
float GetOverallPercentComplete();
///Get Total Number of Tasks.
int GetTotalNumTasks();
//Pause/unpause all OD Tasks. Does not occur immediately.
static void Pause(bool pause = true);
static void Resume();
@ -120,7 +113,7 @@ class ODManager
static void UnlockLibSndFileMutex();
protected:
//private constructor - Singleton.
ODManager();
@ -131,47 +124,46 @@ class ODManager
///Start the main loop for the manager.
void Start();
///Remove references in our array to Tasks that have been completed/Schedule new ones
void UpdateQueues();
//instance
static ODManager* pMan;
//List of tracks and their active and inactive tasks.
std::vector<ODWaveTrackTaskQueue*> mQueues;
ODLock mQueuesMutex;
//List of current Task to do.
std::vector<ODTask*> mTasks;
//mutex for above variable
ODLock mTasksMutex;
//global pause switch for OD
volatile bool mPause;
ODLock mPauseLock;
volatile int mNeedsDraw;
///Number of threads currently running. Accessed thru multiple threads
volatile int mCurrentThreads;
//mutex for above variable
ODLock mCurrentThreadsMutex;
///Maximum number of threads allowed out.
int mMaxThreads;
volatile bool mTerminate;
ODLock mTerminateMutex;
volatile bool mTerminated;
ODLock mTerminatedMutex;
//for the queue not empty comdition
ODLock mQueueNotEmptyCondLock;
ODCondition* mQueueNotEmptyCond;
#ifdef __WXMAC__
// On Mac OS X, it's better not to use the wxThread class.
@ -201,34 +193,30 @@ class ODManagerHelperThread {
ODManagerHelperThread *th = (ODManagerHelperThread *)p;
/* return (void *) */th->Entry();
}
///Specifies the priority the thread will run at. Currently doesn't work.
///@param priority value from 0 (min priority) to 100 (max priority)
void SetPriority(int priority)
{
mPriority=priority;
}
void Run() {
pthread_create(&mThread, NULL, callback, this);
}
private:
bool mDestroy;
pthread_t mThread;
int mPriority;
};
#else
class ODManagerHelperThread : public wxThread
class ODManagerHelperThread : public wxThread
{
public:
///Constructs a ODTaskThread
///@param task the task to be launched as an
///@param task the task to be launched as an
ODManagerHelperThread(): wxThread(){}
protected:
///Executes a part of the task
void *Entry()
@ -236,14 +224,9 @@ class ODManagerHelperThread {
ODManager::Instance()->Start();
return NULL;
}
};
#endif //__WXMAC__
};
#endif