mirror of
https://github.com/love2d/love.git
synced 2026-08-17 11:00:31 +02:00
Multiple thread backends.
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
**/
|
||||
|
||||
#include "Audio.h"
|
||||
#include <common/delay.h>
|
||||
|
||||
#include <sound/Decoder.h>
|
||||
|
||||
@@ -28,8 +29,34 @@ namespace audio
|
||||
{
|
||||
namespace openal
|
||||
{
|
||||
Audio::PoolThread::PoolThread(Pool* pool)
|
||||
: pool(pool), finish(false) {
|
||||
|
||||
}
|
||||
|
||||
void Audio::PoolThread::main()
|
||||
{
|
||||
while(true) {
|
||||
{
|
||||
thread::Lock lock(mutex);
|
||||
if (finish) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pool->update();
|
||||
delay(5);
|
||||
}
|
||||
}
|
||||
|
||||
void Audio::PoolThread::setFinish()
|
||||
{
|
||||
thread::Lock lock(mutex);
|
||||
finish = true;
|
||||
}
|
||||
|
||||
|
||||
Audio::Audio()
|
||||
: finish(false)
|
||||
{
|
||||
// Passing zero for default device.
|
||||
device = alcOpenDevice(0);
|
||||
@@ -67,15 +94,16 @@ namespace openal
|
||||
// pool must be allocated after AL context.
|
||||
pool = new Pool();
|
||||
|
||||
thread = SDL_CreateThread(Audio::run, (void*)this);
|
||||
poolThread = new PoolThread(pool);
|
||||
poolThread->start();
|
||||
}
|
||||
|
||||
Audio::~Audio()
|
||||
{
|
||||
finish = true;
|
||||
|
||||
SDL_WaitThread(thread, 0);
|
||||
poolThread->setFinish();
|
||||
poolThread->wait();
|
||||
|
||||
delete poolThread;
|
||||
delete pool;
|
||||
|
||||
alcMakeContextCurrent(0);
|
||||
@@ -84,18 +112,6 @@ namespace openal
|
||||
alcCloseDevice(device);
|
||||
}
|
||||
|
||||
int Audio::run(void * d)
|
||||
{
|
||||
Audio * instance = (Audio*)d;
|
||||
|
||||
while(!instance->finish)
|
||||
{
|
||||
instance->pool->update();
|
||||
SDL_Delay(5);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * Audio::getName() const
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include "Source.h"
|
||||
#include "Pool.h"
|
||||
#include <thread/threads.h>
|
||||
|
||||
// OpenAL
|
||||
#ifdef LOVE_MACOSX
|
||||
@@ -66,17 +67,30 @@ namespace openal
|
||||
// The OpenAL context.
|
||||
ALCcontext * context;
|
||||
|
||||
SDL_Thread * thread;
|
||||
|
||||
// The Pool.
|
||||
Pool * pool;
|
||||
|
||||
// Set this to true when the thread should finish.
|
||||
// Main thread will write to this value, and Audio::run
|
||||
// will read from it.
|
||||
bool finish;
|
||||
|
||||
static int run(void * unused);
|
||||
class PoolThread: public thread::ThreadBase {
|
||||
protected:
|
||||
Pool* pool;
|
||||
|
||||
// Set this to true when the thread should finish.
|
||||
// Main thread will write to this value, and PoolThread
|
||||
// will read from it.
|
||||
volatile bool finish;
|
||||
|
||||
// finish lock
|
||||
thread::Mutex mutex;
|
||||
|
||||
virtual void main();
|
||||
|
||||
public:
|
||||
PoolThread(Pool* pool);
|
||||
void setFinish();
|
||||
};
|
||||
|
||||
PoolThread* poolThread;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace openal
|
||||
alGenSources(NUM_SOURCES, sources);
|
||||
|
||||
// Create the mutex.
|
||||
mutex = SDL_CreateMutex();
|
||||
mutex = new thread::Mutex();
|
||||
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
throw love::Exception("Could not generate sources.");
|
||||
@@ -58,7 +58,7 @@ namespace openal
|
||||
{
|
||||
stop();
|
||||
|
||||
SDL_DestroyMutex(mutex);
|
||||
delete mutex;
|
||||
|
||||
// Free all sources.
|
||||
alDeleteSources(NUM_SOURCES, sources);
|
||||
@@ -67,28 +67,30 @@ namespace openal
|
||||
bool Pool::isAvailable() const
|
||||
{
|
||||
bool has = false;
|
||||
LOCK(mutex);
|
||||
has = !available.empty();
|
||||
UNLOCK(mutex);
|
||||
{
|
||||
thread::Lock lock(mutex);
|
||||
has = !available.empty();
|
||||
}
|
||||
return has;
|
||||
}
|
||||
|
||||
bool Pool::isPlaying(Source * s)
|
||||
{
|
||||
bool p = false;
|
||||
LOCK(mutex);
|
||||
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
||||
{
|
||||
if(i->first == s)
|
||||
p = true;
|
||||
thread::Lock lock(mutex);
|
||||
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
||||
{
|
||||
if(i->first == s)
|
||||
p = true;
|
||||
}
|
||||
}
|
||||
UNLOCK(mutex);
|
||||
return p;
|
||||
}
|
||||
|
||||
void Pool::update()
|
||||
{
|
||||
LOCK(mutex);
|
||||
thread::Lock lock(mutex);
|
||||
|
||||
std::map<Source *, ALuint>::iterator i = playing.begin();
|
||||
|
||||
@@ -107,8 +109,6 @@ namespace openal
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK(mutex);
|
||||
}
|
||||
|
||||
int Pool::getNumSources() const
|
||||
@@ -126,7 +126,7 @@ namespace openal
|
||||
bool ok;
|
||||
out = 0;
|
||||
|
||||
LOCK(mutex);
|
||||
thread::Lock lock(mutex);
|
||||
|
||||
bool alreadyPlaying = findSource(source, out);
|
||||
|
||||
@@ -160,14 +160,12 @@ namespace openal
|
||||
ok = true;
|
||||
}
|
||||
|
||||
UNLOCK(mutex);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void Pool::stop()
|
||||
{
|
||||
LOCK(mutex);
|
||||
thread::Lock lock(mutex);
|
||||
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
||||
{
|
||||
i->first->stopAtomic();
|
||||
@@ -175,66 +173,57 @@ namespace openal
|
||||
}
|
||||
|
||||
playing.clear();
|
||||
|
||||
UNLOCK(mutex);
|
||||
}
|
||||
|
||||
void Pool::stop(Source * source)
|
||||
{
|
||||
LOCK(mutex);
|
||||
thread::Lock lock(mutex);
|
||||
removeSource(source);
|
||||
UNLOCK(mutex);
|
||||
}
|
||||
|
||||
void Pool::pause()
|
||||
{
|
||||
LOCK(mutex);
|
||||
thread::Lock lock(mutex);
|
||||
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
||||
i->first->pauseAtomic();
|
||||
UNLOCK(mutex);
|
||||
}
|
||||
|
||||
void Pool::pause(Source * source)
|
||||
{
|
||||
LOCK(mutex);
|
||||
thread::Lock lock(mutex);
|
||||
ALuint out;
|
||||
if(findSource(source, out))
|
||||
source->pauseAtomic();
|
||||
UNLOCK(mutex);
|
||||
}
|
||||
|
||||
void Pool::resume()
|
||||
{
|
||||
LOCK(mutex);
|
||||
thread::Lock lock(mutex);
|
||||
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
||||
i->first->resumeAtomic();
|
||||
UNLOCK(mutex);
|
||||
}
|
||||
|
||||
void Pool::resume(Source * source)
|
||||
{
|
||||
LOCK(mutex);
|
||||
thread::Lock lock(mutex);
|
||||
ALuint out;
|
||||
if(findSource(source, out))
|
||||
source->resumeAtomic();
|
||||
UNLOCK(mutex);
|
||||
}
|
||||
|
||||
void Pool::rewind()
|
||||
{
|
||||
LOCK(mutex);
|
||||
thread::Lock lock(mutex);
|
||||
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
||||
i->first->rewindAtomic();
|
||||
UNLOCK(mutex);
|
||||
}
|
||||
|
||||
void Pool::rewind(Source * source)
|
||||
{
|
||||
LOCK(mutex);
|
||||
thread::Lock lock(mutex);
|
||||
ALuint out;
|
||||
if(findSource(source, out))
|
||||
source->rewindAtomic();
|
||||
UNLOCK(mutex);
|
||||
}
|
||||
|
||||
void Pool::release(Source * source)
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
// LOVE
|
||||
#include <common/config.h>
|
||||
#include <common/Exception.h>
|
||||
#include <thread/threads.h>
|
||||
|
||||
// OpenAL
|
||||
#ifdef LOVE_MACOSX
|
||||
@@ -70,7 +71,7 @@ namespace openal
|
||||
|
||||
// Only one thread can access this object at the same time. This mutex will
|
||||
// make sure of that.
|
||||
SDL_mutex * mutex;
|
||||
thread::Mutex* mutex;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user