From b0d2938bf2a81be72f85629cfd20d4e862ce8f7f Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 3 Oct 2017 04:55:50 -0700 Subject: [PATCH] Use pImpl for Buffers --- examples/alure-play.cpp | 13 ++++++------- include/AL/alure2.h | 36 +++++++++++++++++++++--------------- src/buffer.cpp | 13 +++++++++++++ src/buffer.h | 25 ++++++++++++------------- src/context.cpp | 24 ++++++++++++------------ src/context.h | 6 +++--- src/source.cpp | 4 ++-- src/source.h | 2 +- 8 files changed, 70 insertions(+), 53 deletions(-) diff --git a/examples/alure-play.cpp b/examples/alure-play.cpp index 3cd44bf..c3aa2bb 100644 --- a/examples/alure-play.cpp +++ b/examples/alure-play.cpp @@ -37,18 +37,18 @@ int main(int argc, char *argv[]) for(int i = fileidx;i < argc;i++) { - alure::Buffer *buffer = ctx.getBuffer(argv[i]); + alure::Buffer buffer = ctx.getBuffer(argv[i]); alure::Source *source = ctx.createSource(); source->play(buffer); - std::cout<< "Playing "<getSampleType())<<", " - <getChannelConfig())<<", " - <getFrequency()<<"hz)" <getFrequency(); + float invfreq = 1.0f / buffer.getFrequency(); while(source->isPlaying()) { std::cout<< "\r "<getOffset()*invfreq)<<" / "<<(buffer->getLength()*invfreq); + (source->getOffset()*invfreq)<<" / "<<(buffer.getLength()*invfreq); std::cout.flush(); std::this_thread::sleep_for(std::chrono::milliseconds(25)); ctx.update(); @@ -58,7 +58,6 @@ int main(int argc, char *argv[]) source->release(); source = 0; ctx.removeBuffer(buffer); - buffer = 0; } alure::Context::MakeCurrent(nullptr); diff --git a/include/AL/alure2.h b/include/AL/alure2.h index ec2a4a6..cf8fca4 100644 --- a/include/AL/alure2.h +++ b/include/AL/alure2.h @@ -504,7 +504,7 @@ public: * Creates and caches a Buffer for the given audio file or resource name. * Multiple calls with the same name will return the same Buffer object. */ - Buffer *getBuffer(const String &name); + Buffer getBuffer(const String &name); /** * Creates and caches a Buffer for the given audio file or resource name. @@ -514,7 +514,7 @@ public: * and must be checked with a call to Buffer::getLoadStatus prior to being * played. */ - Buffer *getBufferAsync(const String &name); + Buffer getBufferAsync(const String &name); /** * Deletes the cached Buffer object for the given audio file or @@ -525,7 +525,7 @@ public: * Deletes the given cached buffer instance. The buffer must not be in use * by a Source. */ - void removeBuffer(Buffer *buffer); + void removeBuffer(Buffer buffer); /** * Creates a new Source. There is no practical limit to the number of @@ -577,28 +577,34 @@ enum class BufferLoadStatus { Ready }; +class ALBuffer; class ALURE_API Buffer { + friend class ALContext; + friend class ALSource; + + MAKE_PIMPL(Buffer, ALBuffer) + public: /** * Retrieves the length of the buffer in sample frames. The buffer must be * fully loaded before this method is called. */ - virtual ALuint getLength() const = 0; + ALuint getLength() const; /** Retrieves the buffer's frequency in hz. */ - virtual ALuint getFrequency() const = 0; + ALuint getFrequency() const; /** Retrieves the buffer's sample configuration. */ - virtual ChannelConfig getChannelConfig() const = 0; + ChannelConfig getChannelConfig() const; /** Retrieves the buffer's sample type. */ - virtual SampleType getSampleType() const = 0; + SampleType getSampleType() const; /** * Retrieves the storage size used by the buffer, in bytes. The buffer must * be fully loaded before this method is called. */ - virtual ALuint getSize() const = 0; + ALuint getSize() const; /** * Sets the buffer's loop points, used for looping sources. If the current @@ -612,19 +618,19 @@ public: * \param start The starting point, in sample frames (inclusive). * \param end The ending point, in sample frames (exclusive). */ - virtual void setLoopPoints(ALuint start, ALuint end) = 0; + void setLoopPoints(ALuint start, ALuint end); /** * Retrieves the current loop points as a [start,end) pair. The buffer must * be fully loaded before this method is called. */ - virtual std::pair getLoopPoints() const = 0; + std::pair getLoopPoints() const; /** * Retrieves the Source objects currently playing the buffer. Stopping the * returned sources will allow the buffer to be removed from the context. */ - virtual Vector getSources() const = 0; + Vector getSources() const; /** * Queries the buffer's load status. A return of BufferLoadStatus::Pending @@ -632,13 +638,13 @@ public: * call to Source::play. Buffers created with Context::getBuffer will * always return BufferLoadStatus::Ready. */ - virtual BufferLoadStatus getLoadStatus() = 0; + BufferLoadStatus getLoadStatus(); /** Retrieves the name the buffer was created with. */ - virtual const String &getName() const = 0; + const String &getName() const; /** Queries if the buffer is in use and can't be removed. */ - virtual bool isInUse() const = 0; + bool isInUse() const; }; @@ -648,7 +654,7 @@ public: * Plays the source using buffer. The same buffer may be played from * multiple sources simultaneously. */ - virtual void play(Buffer *buffer) = 0; + virtual void play(Buffer buffer) = 0; /** * Plays the source by streaming audio from decoder. This will use * queuesize buffers, each with updatelen sample frames. The given decoder diff --git a/src/buffer.cpp b/src/buffer.cpp index 4774b8d..283c9a7 100644 --- a/src/buffer.cpp +++ b/src/buffer.cpp @@ -155,6 +155,19 @@ BufferLoadStatus ALBuffer::getLoadStatus() return mLoadStatus; } +using ALuintPair = std::pair; +DECL_THUNK0(ALuint, Buffer, getLength, const) +DECL_THUNK0(ALuint, Buffer, getFrequency, const) +DECL_THUNK0(ChannelConfig, Buffer, getChannelConfig, const) +DECL_THUNK0(SampleType, Buffer, getSampleType, const) +DECL_THUNK0(ALuint, Buffer, getSize, const) +DECL_THUNK2(void, Buffer, setLoopPoints,, ALuint, ALuint) +DECL_THUNK0(ALuintPair, Buffer, getLoopPoints, const) +DECL_THUNK0(Vector, Buffer, getSources, const) +DECL_THUNK0(BufferLoadStatus, Buffer, getLoadStatus,) +DECL_THUNK0(const String&, Buffer, getName, const) +DECL_THUNK0(bool, Buffer, isInUse, const) + ALURE_API const char *GetSampleTypeName(SampleType type) { diff --git a/src/buffer.h b/src/buffer.h index 0bedab7..77652bc 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -15,7 +15,7 @@ class ALContext; ALenum GetFormat(ChannelConfig chans, SampleType type); -class ALBuffer : public Buffer { +class ALBuffer { ALContext *const mContext; ALuint mId; @@ -36,7 +36,6 @@ public: mLoadStatus(preloaded ? BufferLoadStatus::Ready : BufferLoadStatus::Pending), mIsLoaded(preloaded), mName(name) { } - virtual ~ALBuffer() { } void cleanup(); @@ -54,24 +53,24 @@ public: bool isReady() const { return mLoadStatus == BufferLoadStatus::Ready; } - ALuint getLength() const override final; + ALuint getLength() const; - ALuint getFrequency() const override final { return mFrequency; } - ChannelConfig getChannelConfig() const override final { return mChannelConfig; } - SampleType getSampleType() const override final { return mSampleType; } + ALuint getFrequency() const { return mFrequency; } + ChannelConfig getChannelConfig() const { return mChannelConfig; } + SampleType getSampleType() const { return mSampleType; } - ALuint getSize() const override final; + ALuint getSize() const; - void setLoopPoints(ALuint start, ALuint end) override final; - std::pair getLoopPoints() const override final; + void setLoopPoints(ALuint start, ALuint end); + std::pair getLoopPoints() const; - Vector getSources() const override final { return mSources; } + Vector getSources() const { return mSources; } - BufferLoadStatus getLoadStatus() override final; + BufferLoadStatus getLoadStatus(); - const String &getName() const override final { return mName; } + const String &getName() const { return mName; } - bool isInUse() const override final { return (mSources.size() > 0); } + bool isInUse() const { return (mSources.size() > 0); } }; } // namespace alure diff --git a/src/context.cpp b/src/context.cpp index 7e0451e..d460792 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -495,7 +495,7 @@ bool ALContext::isSupported(ChannelConfig channels, SampleType type) const } -Buffer *ALContext::getBuffer(const String &name) +Buffer ALContext::getBuffer(const String &name) { CheckContext(this); @@ -511,7 +511,7 @@ Buffer *ALContext::getBuffer(const String &name) ALBuffer *buffer = iter->get(); while(buffer->getLoadStatus() == BufferLoadStatus::Pending) std::this_thread::yield(); - return buffer; + return Buffer(buffer); } // NOTE: 'iter' is used later to insert a new entry! @@ -562,9 +562,9 @@ Buffer *ALContext::getBuffer(const String &name) if(alGetError() != AL_NO_ERROR) throw std::runtime_error("Failed to buffer data"); - return mBuffers.insert(iter, + return Buffer(mBuffers.insert(iter, MakeUnique(this, bid, srate, chans, type, true, name) - )->get(); + )->get()); } catch(...) { alDeleteBuffers(1, &bid); @@ -572,7 +572,7 @@ Buffer *ALContext::getBuffer(const String &name) } } -Buffer *ALContext::getBufferAsync(const String &name) +Buffer ALContext::getBufferAsync(const String &name) { CheckContext(this); @@ -582,7 +582,7 @@ Buffer *ALContext::getBufferAsync(const String &name) { return hasher(lhs->getName()) < rhs; } ); if(iter != mBuffers.end() && (*iter)->getName() == name) - return iter->get(); + return Buffer(iter->get()); // NOTE: 'iter' is used later to insert a new entry! auto decoder = createDecoder(name); @@ -621,7 +621,7 @@ Buffer *ALContext::getBufferAsync(const String &name) mWakeMutex.lock(); mWakeMutex.unlock(); mWakeThread.notify_all(); - return mBuffers.insert(iter, std::move(buffer))->get(); + return Buffer(mBuffers.insert(iter, std::move(buffer))->get()); } @@ -640,9 +640,9 @@ void ALContext::removeBuffer(const String &name) } } -void ALContext::removeBuffer(Buffer *buffer) +void ALContext::removeBuffer(Buffer buffer) { - removeBuffer(buffer->getName()); + removeBuffer(buffer.getName()); } @@ -872,10 +872,10 @@ DECL_THUNK1(void, Context, setAsyncWakeInterval,, ALuint) DECL_THUNK0(ALuint, Context, getAsyncWakeInterval, const) DECL_THUNK1(SharedPtr, Context, createDecoder,, const String&) DECL_THUNK2(bool, Context, isSupported, const, ChannelConfig, SampleType) -DECL_THUNK1(Buffer*, Context, getBuffer,, const String&) -DECL_THUNK1(Buffer*, Context, getBufferAsync,, const String&) +DECL_THUNK1(Buffer, Context, getBuffer,, const String&) +DECL_THUNK1(Buffer, Context, getBufferAsync,, const String&) DECL_THUNK1(void, Context, removeBuffer,, const String&) -DECL_THUNK1(void, Context, removeBuffer,, Buffer*) +DECL_THUNK1(void, Context, removeBuffer,, Buffer) DECL_THUNK0(Source*, Context, createSource,) DECL_THUNK0(AuxiliaryEffectSlot*, Context, createAuxiliaryEffectSlot,) DECL_THUNK0(Effect*, Context, createEffect,) diff --git a/src/context.h b/src/context.h index 02b3071..ae1b348 100644 --- a/src/context.h +++ b/src/context.h @@ -245,10 +245,10 @@ public: bool isSupported(ChannelConfig channels, SampleType type) const; - Buffer *getBuffer(const String &name); - Buffer *getBufferAsync(const String &name); + Buffer getBuffer(const String &name); + Buffer getBufferAsync(const String &name); void removeBuffer(const String &name); - void removeBuffer(Buffer *buffer); + void removeBuffer(Buffer buffer); Source *createSource(); diff --git a/src/source.cpp b/src/source.cpp index 9784ad3..7a7e3c8 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -312,9 +312,9 @@ void ALSource::groupPropUpdate(ALfloat gain, ALfloat pitch) } -void ALSource::play(Buffer *buffer) +void ALSource::play(Buffer buffer) { - ALBuffer *albuf = cast(buffer); + ALBuffer *albuf = buffer.pImpl; if(!albuf) throw std::runtime_error("Buffer is not valid"); CheckContext(mContext); CheckContext(albuf->getContext()); diff --git a/src/source.h b/src/source.h index 8238556..c596d50 100644 --- a/src/source.h +++ b/src/source.h @@ -98,7 +98,7 @@ public: void unsetPaused() { mPaused = false; } void makeStopped(); - void play(Buffer *buffer) override final; + void play(Buffer buffer) override final; void play(SharedPtr decoder, ALuint updatelen, ALuint queuesize) override final; void stop() override final; void pause() override final; -- 2.11.4.GIT