mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 02:27:40 -04:00
Use hsThread for SoundBuffer preloading.
This commit is contained in:
@ -40,11 +40,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
#include "plStatusLog/plStatusLog.h"
|
#include "plStatusLog/plStatusLog.h"
|
||||||
#include "hsTimer.h"
|
#include "hsTimer.h"
|
||||||
|
|
||||||
static bool s_running;
|
|
||||||
static LISTDECL(plSoundBuffer, link) s_loading;
|
|
||||||
static CCritSect s_critsect;
|
|
||||||
static CEvent s_event(kEventAutoReset);
|
|
||||||
|
|
||||||
static void GetFullPath( const char filename[], char *destStr )
|
static void GetFullPath( const char filename[], char *destStr )
|
||||||
{
|
{
|
||||||
char path[ kFolderIterator_MaxPath ];
|
char path[ kFolderIterator_MaxPath ];
|
||||||
@ -79,73 +74,74 @@ static plAudioFileReader *CreateReader( hsBool fullpath, const char filename[],
|
|||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
// our loading thread
|
hsError plSoundPreloader::Run()
|
||||||
static void LoadCallback(void *)
|
|
||||||
{
|
{
|
||||||
LISTDECL(plSoundBuffer, link) templist;
|
hsTArray<plSoundBuffer*> templist;
|
||||||
while(s_running)
|
|
||||||
{
|
while (fRunning)
|
||||||
s_critsect.Enter();
|
{
|
||||||
{
|
fCritSect.Lock();
|
||||||
while(plSoundBuffer *buffer = s_loading.Head())
|
for (int i = fBuffers.GetCount(); i > 0; i--)
|
||||||
{
|
{
|
||||||
templist.Link(buffer);
|
templist.Append(fBuffers.Pop());
|
||||||
}
|
}
|
||||||
}
|
fCritSect.Unlock();
|
||||||
s_critsect.Leave();
|
|
||||||
|
if (templist.GetCount() == 0)
|
||||||
if(!templist.Head())
|
{
|
||||||
{
|
fEvent.Wait();
|
||||||
s_event.Wait(kEventWaitForever);
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
|
||||||
plAudioFileReader *reader = nil;
|
plAudioFileReader *reader = nil;
|
||||||
while(plSoundBuffer *buffer = templist.Head())
|
for (int i = templist.GetCount(); i > 0; i--)
|
||||||
{
|
{
|
||||||
if(buffer->GetData())
|
plSoundBuffer* buf = templist.Pop();
|
||||||
{
|
|
||||||
reader = CreateReader(true, buffer->GetFileName(), buffer->GetAudioReaderType(), buffer->GetReaderSelect());
|
if (buf->GetData())
|
||||||
|
{
|
||||||
|
reader = CreateReader(true, buf->GetFileName(), buf->GetAudioReaderType(), buf->GetReaderSelect());
|
||||||
|
|
||||||
if( reader )
|
if( reader )
|
||||||
{
|
{
|
||||||
unsigned readLen = buffer->GetAsyncLoadLength() ? buffer->GetAsyncLoadLength() : buffer->GetDataLength();
|
unsigned readLen = buf->GetAsyncLoadLength() ? buf->GetAsyncLoadLength() : buf->GetDataLength();
|
||||||
reader->Read( readLen, buffer->GetData() );
|
reader->Read( readLen, buf->GetData() );
|
||||||
buffer->SetAudioReader(reader); // give sound buffer reader, since we may need it later
|
buf->SetAudioReader(reader); // give sound buffer reader, since we may need it later
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
buffer->SetError();
|
{
|
||||||
}
|
buf->SetError();
|
||||||
|
}
|
||||||
templist.Unlink(buffer);
|
}
|
||||||
buffer->SetLoaded(true);
|
|
||||||
}
|
buf->SetLoaded(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// we need to be sure that all buffers are removed from our load list when shutting this thread down or we will hang,
|
// we need to be sure that all buffers are removed from our load list when shutting this thread down or we will hang,
|
||||||
// since the sound buffer will wait to be destroyed until it is marked as loaded
|
// since the sound buffer will wait to be destroyed until it is marked as loaded
|
||||||
s_critsect.Enter();
|
fCritSect.Lock();
|
||||||
{
|
for (int i = fBuffers.GetCount(); i > 0; i--)
|
||||||
while(plSoundBuffer *buffer = s_loading.Head())
|
{
|
||||||
{
|
plSoundBuffer* buf = fBuffers.Pop();
|
||||||
buffer->SetLoaded(true);
|
buf->SetLoaded(true);
|
||||||
s_loading.Unlink(buffer);
|
}
|
||||||
}
|
fCritSect.Unlock();
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
return hsOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static plSoundPreloader gLoaderThread;
|
||||||
|
|
||||||
void plSoundBuffer::Init()
|
void plSoundBuffer::Init()
|
||||||
{
|
{
|
||||||
s_running = true;
|
gLoaderThread.Start();
|
||||||
_beginthread(LoadCallback, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void plSoundBuffer::Shutdown()
|
void plSoundBuffer::Shutdown()
|
||||||
{
|
{
|
||||||
s_running = false;
|
gLoaderThread.Stop();
|
||||||
s_event.Signal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Constructor/Destructor //////////////////////////////////////////////////
|
//// Constructor/Destructor //////////////////////////////////////////////////
|
||||||
@ -175,7 +171,6 @@ plSoundBuffer::~plSoundBuffer()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(!link.IsLinked());
|
|
||||||
delete [] fFileName;
|
delete [] fFileName;
|
||||||
UnLoad();
|
UnLoad();
|
||||||
}
|
}
|
||||||
@ -342,7 +337,7 @@ void plSoundBuffer::IGetFullPath( char *destStr )
|
|||||||
// While a file is loading(fLoading == true, and fLoaded == false) a buffer, no paremeters of the buffer should be modified.
|
// While a file is loading(fLoading == true, and fLoaded == false) a buffer, no paremeters of the buffer should be modified.
|
||||||
plSoundBuffer::ELoadReturnVal plSoundBuffer::AsyncLoad(plAudioFileReader::StreamType type, unsigned length /* = 0 */ )
|
plSoundBuffer::ELoadReturnVal plSoundBuffer::AsyncLoad(plAudioFileReader::StreamType type, unsigned length /* = 0 */ )
|
||||||
{
|
{
|
||||||
if(!s_running)
|
if(!gLoaderThread.IsRunning())
|
||||||
return kError; // we cannot load the data since the load thread is no longer running
|
return kError; // we cannot load the data since the load thread is no longer running
|
||||||
if(!fLoading && !fLoaded)
|
if(!fLoading && !fLoaded)
|
||||||
{
|
{
|
||||||
@ -354,13 +349,9 @@ plSoundBuffer::ELoadReturnVal plSoundBuffer::AsyncLoad(plAudioFileReader::Stream
|
|||||||
if( fData == nil )
|
if( fData == nil )
|
||||||
return kError;
|
return kError;
|
||||||
}
|
}
|
||||||
s_critsect.Enter();
|
|
||||||
{
|
gLoaderThread.AddBuffer(this);
|
||||||
fLoading = true;
|
fLoading = true;
|
||||||
s_loading.Link(this);
|
|
||||||
}
|
|
||||||
s_critsect.Leave();
|
|
||||||
s_event.Signal();
|
|
||||||
}
|
}
|
||||||
if(fLoaded)
|
if(fLoaded)
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
#include "pnKeyedObject/hsKeyedObject.h"
|
#include "pnKeyedObject/hsKeyedObject.h"
|
||||||
#include "plAudioCore.h"
|
#include "plAudioCore.h"
|
||||||
#include "plAudioFileReader.h"
|
#include "plAudioFileReader.h"
|
||||||
#include "pnUtils/pnUtils.h"
|
#include "hsThread.h"
|
||||||
|
|
||||||
//// Class Definition ////////////////////////////////////////////////////////
|
//// Class Definition ////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -55,8 +55,6 @@ public:
|
|||||||
CLASSNAME_REGISTER( plSoundBuffer );
|
CLASSNAME_REGISTER( plSoundBuffer );
|
||||||
GETINTERFACE_ANY( plSoundBuffer, hsKeyedObject );
|
GETINTERFACE_ANY( plSoundBuffer, hsKeyedObject );
|
||||||
|
|
||||||
LINK(plSoundBuffer) link;
|
|
||||||
|
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
kIsExternal = 0x0001,
|
kIsExternal = 0x0001,
|
||||||
@ -143,4 +141,38 @@ protected:
|
|||||||
plAudioFileReader *IGetReader( hsBool fullpath );
|
plAudioFileReader *IGetReader( hsBool fullpath );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class plSoundPreloader : public hsThread
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
hsTArray<plSoundBuffer*> fBuffers;
|
||||||
|
hsEvent fEvent;
|
||||||
|
bool fRunning;
|
||||||
|
hsMutex fCritSect;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual hsError Run();
|
||||||
|
|
||||||
|
virtual void Start() {
|
||||||
|
fRunning = true;
|
||||||
|
hsThread::Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Stop() {
|
||||||
|
fRunning = false;
|
||||||
|
fEvent.Signal();
|
||||||
|
hsThread::Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsRunning() const { return fRunning; }
|
||||||
|
|
||||||
|
void AddBuffer(plSoundBuffer* buffer) {
|
||||||
|
fCritSect.Lock();
|
||||||
|
fBuffers.Push(buffer);
|
||||||
|
fCritSect.Unlock();
|
||||||
|
|
||||||
|
fEvent.Signal();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif //_plSoundBuffer_h
|
#endif //_plSoundBuffer_h
|
||||||
|
Reference in New Issue
Block a user