From 03b863d788f718f836d7134b1243b72f63c41b4d Mon Sep 17 00:00:00 2001 From: Bart van Strien Date: Sat, 11 Feb 2017 21:41:22 +0100 Subject: [PATCH] Simplify love.audio's Pool class Move most logic back to Source. Pool now simply contains a list of playing sources and a mutex. Also gets rid of the pause/pauseAtomic duplication in Source, since it can now request a lock from Pool itself. --HG-- branch : minor --- src/common/config.h | 10 ++ src/modules/audio/openal/Audio.cpp | 10 +- src/modules/audio/openal/Pool.cpp | 223 +++++----------------------- src/modules/audio/openal/Pool.h | 25 +--- src/modules/audio/openal/Source.cpp | 130 ++++++++++------ src/modules/audio/openal/Source.h | 13 +- src/modules/thread/threads.cpp | 9 +- src/modules/thread/threads.h | 1 + src/scripts/nogame.lua.h | 2 +- 9 files changed, 159 insertions(+), 264 deletions(-) diff --git a/src/common/config.h b/src/common/config.h index bacd6fddd..38ac69b46 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -86,6 +86,16 @@ # define LOVE_UNUSED(x) (void)sizeof(x) #endif + +// Warn on unused return values +#ifdef __GNUC__ +# define LOVE_WARN_UNUSED __attribute__((warn_unused_result)) +#elif _MSC_VER +# define LOVE_WARN_UNUSED _Check_return_ +#else +# define LOVE_WARN_UNUSED +#endif + #ifndef LOVE_BUILD # define LOVE_BUILD # define LOVE_BUILD_STANDALONE diff --git a/src/modules/audio/openal/Audio.cpp b/src/modules/audio/openal/Audio.cpp index 3c86dd784..f9a9a897a 100644 --- a/src/modules/audio/openal/Audio.cpp +++ b/src/modules/audio/openal/Audio.cpp @@ -240,7 +240,7 @@ bool Audio::play(love::audio::Source *source) bool Audio::play(const std::vector &sources) { - return pool->play(sources); + return Source::play(sources); } void Audio::stop(love::audio::Source *source) @@ -250,12 +250,12 @@ void Audio::stop(love::audio::Source *source) void Audio::stop(const std::vector &sources) { - return pool->stop(sources); + return Source::stop(sources); } void Audio::stop() { - pool->stop(); + return Source::stop(pool); } void Audio::pause(love::audio::Source *source) @@ -265,12 +265,12 @@ void Audio::pause(love::audio::Source *source) void Audio::pause(const std::vector &sources) { - return pool->pause(sources); + return Source::pause(sources); } std::vector Audio::pause() { - return pool->pause(); + return Source::pause(pool); } void Audio::setVolume(float volume) diff --git a/src/modules/audio/openal/Pool.cpp b/src/modules/audio/openal/Pool.cpp index 321198750..05cd71711 100644 --- a/src/modules/audio/openal/Pool.cpp +++ b/src/modules/audio/openal/Pool.cpp @@ -73,7 +73,7 @@ Pool::Pool() Pool::~Pool() { - stop(); + Source::stop(this); // Free all sources. alDeleteSources(totalSources, sources); @@ -103,20 +103,9 @@ void Pool::update() { thread::Lock lock(mutex); - std::map::iterator i = playing.begin(); - - while (i != playing.end()) - { - if (!i->first->update()) - { - i->first->stopAtomic(); - i->first->release(); - available.push(i->second); - playing.erase(i++); - } - else - i++; - } + for (const auto &i : playing) + if (!i.first->update()) + releaseSource(i.first); } int Pool::getSourceCount() const @@ -129,19 +118,14 @@ int Pool::getMaxSources() const return totalSources; } -bool Pool::assignSource(Source *source, ALuint &out, char *wasPlaying) +bool Pool::assignSource(Source *source, ALuint &out, char &wasPlaying) { out = 0; if (findSource(source, out)) - { - if (wasPlaying) - *wasPlaying = true; - return true; - } + return wasPlaying = true; - if (wasPlaying) - *wasPlaying = false; + wasPlaying = false; if (available.empty()) return false; @@ -154,179 +138,48 @@ bool Pool::assignSource(Source *source, ALuint &out, char *wasPlaying) return true; } -bool Pool::play(Source *source) +bool Pool::releaseSource(Source *source, bool stop) { - thread::Lock lock(mutex); - ALuint out; + ALuint s; - char wasPlaying; - if (!assignSource(source, out, &wasPlaying)) - return false; - - if (!wasPlaying) - return source->playAtomic(out); - else - { - source->resumeAtomic(); - return true; - } -} - -bool Pool::play(const std::vector &sources) -{ - thread::Lock lock(mutex); - - std::vector ids(sources.size()); - // NOTE: not bool, because std::vector is implemented as a bitvector - // which means no pointers can be created. - std::vector wasPlaying(sources.size()); - - for (size_t i = 0; i < sources.size(); i++) - { - Source *source = (Source*) sources[i]; - if (!assignSource(source, ids[i], &wasPlaying[i])) - { - // Now we need to release the resources we had already allocated - for (size_t j = 0; j < sources.size(); j++) - if (!wasPlaying[j]) - release((Source*) sources[j]); - return false; - } - } - - return Source::playAtomic(sources, ids, wasPlaying); -} - -void Pool::stop() -{ - thread::Lock lock(mutex); - for (const auto &i : playing) - { - i.first->stopAtomic(); - i.first->release(); - available.push(i.second); - } - - playing.clear(); -} - -void Pool::stop(Source *source) -{ - thread::Lock lock(mutex); - removeSource(source); -} - -void Pool::stop(const std::vector &sources) -{ - thread::Lock lock(mutex); - Source::stopAtomic(sources); -} - -std::vector Pool::pause() -{ - thread::Lock lock(mutex); - - std::vector werePlaying; - werePlaying.reserve(playing.size()); - - for (const auto &i : playing) - { - if (!i.first->isPlaying()) - continue; - werePlaying.push_back(i.first); - i.first->pauseAtomic(); - } - - return werePlaying; -} - -void Pool::pause(Source *source) -{ - thread::Lock lock(mutex); - ALuint out; - if (findSource(source, out)) - source->pauseAtomic(); -} - -void Pool::pause(const std::vector &sources) -{ - thread::Lock lock(mutex); - Source::pauseAtomic(sources); -} - -void Pool::release(Source *source) -{ - ALuint s = findi(source); - - if (s != 0) + if (findSource(source, s)) { + if (stop) + source->stopAtomic(); + source->release(); available.push(s); playing.erase(source); - } -} - -void Pool::seek(Source *source, float offset, void *unit) -{ - thread::Lock lock(mutex); - return source->seekAtomic(offset, unit); -} - -float Pool::tell(Source *source, void *unit) -{ - thread::Lock lock(mutex); - return source->tellAtomic(unit); -} - -double Pool::getDuration(Source *source, void *unit) -{ - thread::Lock lock(mutex); - return source->getDurationAtomic(unit); -} - -bool Pool::queue(Source *source, void *data, ALsizei length) -{ - thread::Lock lock(mutex); - return source->queueAtomic(data, length); -} - -ALuint Pool::findi(const Source *source) const -{ - std::map::const_iterator i = playing.find((Source *)source); - - if (i != playing.end()) - return i->second; - - return 0; -} - -bool Pool::findSource(Source *source, ALuint &out) -{ - std::map::const_iterator i = playing.find((Source *)source); - - bool found = i != playing.end(); - - if (found) - out = i->second; - - return found; -} - -bool Pool::removeSource(Source *source) -{ - std::map::iterator i = playing.find((Source *)source); - - if (i != playing.end()) - { - source->stopAtomic(); - available.push(i->second); - playing.erase(i++); - source->release(); return true; } return false; } +bool Pool::findSource(Source *source, ALuint &out) +{ + std::map::const_iterator i = playing.find(source); + + if (i == playing.end()) + return false; + + out = i->second; + return true; +} + +thread::Lock Pool::lock() +{ + return thread::Lock(mutex); +} + +std::vector Pool::getPlayingSources() +{ + std::vector sources; + sources.reserve(playing.size()); + for (auto &i : playing) + sources.push_back(i.first); + return sources; +} + } // openal } // audio } // love diff --git a/src/modules/audio/openal/Pool.h b/src/modules/audio/openal/Pool.h index 54d390fcd..c90f978b2 100644 --- a/src/modules/audio/openal/Pool.h +++ b/src/modules/audio/openal/Pool.h @@ -83,33 +83,20 @@ public: int getSourceCount() const; int getMaxSources() const; - bool play(Source *source); - void stop(); - void stop(Source *source); - std::vector pause(); - void pause(Source *source); - void seek(Source *source, float offset, void *unit); - float tell(Source *source, void *unit); - double getDuration(Source *source, void *unit); - bool queue(Source *source, void *data, ALsizei length); - - bool play(const std::vector &sources); - void stop(const std::vector &sources); - void pause(const std::vector &sources); - private: + friend class Source; + LOVE_WARN_UNUSED thread::Lock lock(); + std::vector getPlayingSources(); + /** * Makes the specified OpenAL source available for use. * @param source The OpenAL source. **/ - void release(Source *source); + bool releaseSource(Source *source, bool stop = true); - ALuint findi(const Source *source) const; - - bool assignSource(Source *source, ALuint &out, char *wasPlaying = nullptr); + bool assignSource(Source *source, ALuint &out, char &wasPlaying); bool findSource(Source *source, ALuint &out); - bool removeSource(Source *source); // Maximum possible number of OpenAL sources the pool attempts to generate. static const int MAX_SOURCES = 64; diff --git a/src/modules/audio/openal/Source.cpp b/src/modules/audio/openal/Source.cpp index 8836b965c..ba2ac2338 100644 --- a/src/modules/audio/openal/Source.cpp +++ b/src/modules/audio/openal/Source.cpp @@ -30,6 +30,8 @@ #define audiomodule() (Module::getInstance