From 21af34e2927199aadb62e5b5efcdef6be627c043 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 4 Nov 2017 18:50:33 -0700 Subject: [PATCH] Make sources and source groups specify their parent --- include/AL/alure2.h | 34 ++++++-------- src/source.cpp | 55 +++++++++++++--------- src/source.h | 3 +- src/sourcegroup.cpp | 132 ++++++++++++++-------------------------------------- src/sourcegroup.h | 22 ++------- 5 files changed, 90 insertions(+), 156 deletions(-) diff --git a/include/AL/alure2.h b/include/AL/alure2.h index b2066d6..8cf91e7 100644 --- a/include/AL/alure2.h +++ b/include/AL/alure2.h @@ -1066,6 +1066,16 @@ public: bool isPaused() const; /** + * Sets this source as a child of the given source group. The given source + * group's parameters will influence this and all other sources that belong + * to it. A source can only be the child of one source group at a time, + * although that source group may belong to another source group. + * + * Passing in a null group removes it from its current source group. + */ + void setGroup(SourceGroup group); + + /** * Specifies the source's playback priority. Lowest priority sources will * be evicted first when higher priority sources are played. */ @@ -1322,27 +1332,11 @@ public: StringView getName() const; /** - * Adds a source to the source group. A source may only be part of one - * group at a time, and will automatically be removed from its current - * group as needed. - */ - void addSource(Source source); - /** Removes a source from the source group. */ - void removeSource(Source source); - - /** Adds a list of sources to the group at once. */ - void addSources(ArrayView sources); - /** Removes a list of sources from the source group. */ - void removeSources(ArrayView sources); - - /** - * Adds a group as a subgroup of this source group. This method will throw - * an exception if group is being added to a group it has as a sub-group - * (i.e. it would create a circular sub-group chain). + * Adds this source group as a subgroup of the specified source group. This + * method will throw an exception if this group is being added to a group + * it has as a sub-group (i.e. it would create a circular sub-group chain). */ - void addSubGroup(SourceGroup group); - /** Removes group from the source group. */ - void removeSubGroup(SourceGroup group); + void setParentGroup(SourceGroup group); /** Returns the list of sources currently in the group. */ Vector getSources() const; diff --git a/src/source.cpp b/src/source.cpp index 6dbcb05..29652c6 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -179,7 +179,7 @@ SourceImpl::~SourceImpl() void SourceImpl::resetProperties() { if(mGroup) - mGroup->removeSource(Source(this)); + mGroup->eraseSource(this); mGroup = nullptr; mGroupPitch = 1.0f; mGroupGain = 1.0f; @@ -281,30 +281,10 @@ void SourceImpl::applyProperties(bool looping, ALuint offset) const } -void SourceImpl::setGroup(SourceGroupImpl *group) -{ - if(mGroup) - mGroup->removeSource(Source(this)); - mGroup = group; - mGroupPitch = mGroup->getAppliedPitch(); - mGroupGain = mGroup->getAppliedGain(); - if(mId) - { - alSourcef(mId, AL_PITCH, mPitch * mGroupPitch); - alSourcef(mId, AL_GAIN, mGain * mGroupGain * mFadeGain); - } -} - void SourceImpl::unsetGroup() { mGroup = nullptr; - mGroupPitch = 1.0f; - mGroupGain = 1.0f; - if(mId) - { - alSourcef(mId, AL_PITCH, mPitch * mGroupPitch); - alSourcef(mId, AL_GAIN, mGain * mGroupGain * mFadeGain); - } + groupPropUpdate(1.0f, 1.0f); } void SourceImpl::groupPropUpdate(ALfloat gain, ALfloat pitch) @@ -570,6 +550,36 @@ bool SourceImpl::isPaused() const } +void SourceImpl::setGroup(SourceGroup group) +{ + CheckContext(mContext); + + SourceGroupImpl *parent = group.getHandle(); + if(parent == mGroup) return; + + if(mGroup) + mGroup->eraseSource(this); + mGroup = parent; + if(mGroup) + { + mGroup->insertSource(this); + mGroupPitch = mGroup->getAppliedPitch(); + mGroupGain = mGroup->getAppliedGain(); + } + else + { + mGroupPitch = 1.0f; + mGroupGain = 1.0f; + } + + if(mId) + { + alSourcef(mId, AL_PITCH, mPitch * mGroupPitch); + alSourcef(mId, AL_GAIN, mGain * mGroupGain * mFadeGain); + } +} + + bool SourceImpl::checkPending(SharedFuture &future) { if(future.wait_for(std::chrono::milliseconds::zero()) != std::future_status::ready) @@ -1411,6 +1421,7 @@ DECL_THUNK0(void, Source, resume,) DECL_THUNK0(bool, Source, isPending, const) DECL_THUNK0(bool, Source, isPlaying, const) DECL_THUNK0(bool, Source, isPaused, const) +DECL_THUNK1(void, Source, setGroup,, SourceGroup) DECL_THUNK1(void, Source, setPriority,, ALuint) DECL_THUNK0(ALuint, Source, getPriority, const) DECL_THUNK1(void, Source, setOffset,, uint64_t) diff --git a/src/source.h b/src/source.h index 2099c83..d05e9c5 100644 --- a/src/source.h +++ b/src/source.h @@ -95,7 +95,6 @@ public: bool playUpdate(); bool updateAsync(); - void setGroup(SourceGroupImpl *group); void unsetGroup(); void groupPropUpdate(ALfloat gain, ALfloat pitch); @@ -115,6 +114,8 @@ public: bool isPlaying() const; bool isPaused() const; + void setGroup(SourceGroup group); + void setPriority(ALuint priority); ALuint getPriority() const { return mPriority; } diff --git a/src/sourcegroup.cpp b/src/sourcegroup.cpp index fd90866..b81eda3 100644 --- a/src/sourcegroup.cpp +++ b/src/sourcegroup.cpp @@ -9,24 +9,21 @@ namespace alure { -void SourceGroupImpl::eraseSubGroup(SourceGroupImpl *group) +void SourceGroupImpl::insertSubGroup(SourceGroupImpl *group) { auto iter = std::lower_bound(mSubGroups.begin(), mSubGroups.end(), group); - if(iter != mSubGroups.end() && *iter == group) mSubGroups.erase(iter); + if(iter == mSubGroups.end() || *iter != group) + mSubGroups.insert(iter, group); } - -void SourceGroupImpl::setParentGroup(SourceGroupImpl *group) +void SourceGroupImpl::eraseSubGroup(SourceGroupImpl *group) { - if(mParent) - mParent->eraseSubGroup(this); - mParent = group; - SourceGroupProps props; - mParent->applyPropTree(props); - update(props.mGain, props.mPitch); + auto iter = std::lower_bound(mSubGroups.begin(), mSubGroups.end(), group); + if(iter != mSubGroups.end() && *iter == group) mSubGroups.erase(iter); } -void SourceGroupImpl::unsetParentGroup() + +void SourceGroupImpl::unsetParent() { mParent = nullptr; update(1.0f, 1.0f); @@ -51,106 +48,54 @@ bool SourceGroupImpl::findInSubGroups(SourceGroupImpl *group) const auto iter = std::lower_bound(mSubGroups.begin(), mSubGroups.end(), group); if(iter != mSubGroups.end() && *iter == group) return true; - for(SourceGroupImpl *group : mSubGroups) + for(SourceGroupImpl *grp : mSubGroups) { - if(group->findInSubGroups(group)) + if(grp->findInSubGroups(group)) return true; } return false; } -void SourceGroupImpl::addSource(Source source) +void SourceGroupImpl::insertSource(SourceImpl *source) { - SourceImpl *alsrc = source.getHandle(); - if(!alsrc) throw std::runtime_error("Source is not valid"); - CheckContext(mContext); - - auto iter = std::lower_bound(mSources.begin(), mSources.end(), alsrc); - if(iter != mSources.end() && *iter == alsrc) return; - - mSources.insert(iter, alsrc); - alsrc->setGroup(this); + auto iter = std::lower_bound(mSources.begin(), mSources.end(), source); + if(iter == mSources.end() || *iter != source) + mSources.insert(iter, source); } -void SourceGroupImpl::removeSource(Source source) +void SourceGroupImpl::eraseSource(SourceImpl *source) { - CheckContext(mContext); - auto iter = std::lower_bound(mSources.begin(), mSources.end(), source.getHandle()); - if(iter != mSources.end() && *iter == source.getHandle()) - { - (*iter)->unsetGroup(); + auto iter = std::lower_bound(mSources.begin(), mSources.end(), source); + if(iter != mSources.end() && *iter == source) mSources.erase(iter); - } } -void SourceGroupImpl::addSources(ArrayView sources) +void SourceGroupImpl::setParentGroup(SourceGroup group) { CheckContext(mContext); - if(sources.empty()) - return; - - Vector alsrcs; - alsrcs.reserve(sources.size()); - for(Source source : sources) + SourceGroupImpl *parent = group.getHandle(); + if(!parent) { - alsrcs.push_back(source.getHandle()); - if(!alsrcs.back()) throw std::runtime_error("Source is not valid"); + if(mParent) + mParent->eraseSubGroup(this); + mParent = nullptr; + update(1.0f, 1.0f); } - - Batcher batcher = mContext->getBatcher(); - for(SourceImpl *alsrc : alsrcs) + else { - auto iter = std::lower_bound(mSources.begin(), mSources.end(), alsrc); - if(iter != mSources.end() && *iter == alsrc) continue; + if(this == parent || findInSubGroups(parent)) + throw std::runtime_error("Attempted circular group chain"); - mSources.insert(iter, alsrc); - alsrc->setGroup(this); - } -} - -void SourceGroupImpl::removeSources(ArrayView sources) -{ - Batcher batcher = mContext->getBatcher(); - for(Source source : sources) - { - auto iter = std::lower_bound(mSources.begin(), mSources.end(), source.getHandle()); - if(iter != mSources.end() && *iter == source.getHandle()) - { - (*iter)->unsetGroup(); - mSources.erase(iter); - } - } -} + parent->insertSubGroup(this); - -void SourceGroupImpl::addSubGroup(SourceGroup group) -{ - SourceGroupImpl *algrp = group.getHandle(); - if(!algrp) throw std::runtime_error("SourceGroup is not valid"); - CheckContext(mContext); - - auto iter = std::lower_bound(mSubGroups.begin(), mSubGroups.end(), algrp); - if(iter != mSubGroups.end() && *iter == algrp) return; - - if(this == algrp || algrp->findInSubGroups(this)) - throw std::runtime_error("Attempted circular group chain"); - - mSubGroups.insert(iter, algrp); - Batcher batcher = mContext->getBatcher(); - algrp->setParentGroup(this); -} - -void SourceGroupImpl::removeSubGroup(SourceGroup group) -{ - auto iter = std::lower_bound(mSubGroups.begin(), mSubGroups.end(), group.getHandle()); - if(iter != mSubGroups.end() && *iter == group.getHandle()) - { Batcher batcher = mContext->getBatcher(); - (*iter)->unsetParentGroup(); - mSubGroups.erase(iter); + if(mParent) + mParent->eraseSubGroup(this); + mParent = parent; + update(mParent->getAppliedGain(), mParent->getAppliedPitch()); } } @@ -160,7 +105,7 @@ Vector SourceGroupImpl::getSources() const Vector ret; ret.reserve(mSources.size()); for(SourceImpl *src : mSources) - ret.emplace_back(Source(src)); + ret.emplace_back(src); return ret; } @@ -169,7 +114,7 @@ Vector SourceGroupImpl::getSubGroups() const Vector ret; ret.reserve(mSubGroups.size()); for(SourceGroupImpl *grp : mSubGroups) - ret.emplace_back(SourceGroup(grp)); + ret.emplace_back(grp); return ret; } @@ -326,7 +271,7 @@ void SourceGroupImpl::release() source->unsetGroup(); mSources.clear(); for(SourceGroupImpl *group : mSubGroups) - group->unsetParentGroup(); + group->unsetParent(); mSubGroups.clear(); if(mParent) mParent->eraseSubGroup(this); @@ -337,12 +282,7 @@ void SourceGroupImpl::release() DECL_THUNK0(StringView, SourceGroup, getName, const) -DECL_THUNK1(void, SourceGroup, addSource,, Source) -DECL_THUNK1(void, SourceGroup, removeSource,, Source) -DECL_THUNK1(void, SourceGroup, addSources,, ArrayView) -DECL_THUNK1(void, SourceGroup, removeSources,, ArrayView) -DECL_THUNK1(void, SourceGroup, addSubGroup,, SourceGroup) -DECL_THUNK1(void, SourceGroup, removeSubGroup,, SourceGroup) +DECL_THUNK1(void, SourceGroup, setParentGroup,, SourceGroup) DECL_THUNK0(Vector, SourceGroup, getSources, const) DECL_THUNK0(Vector, SourceGroup, getSubGroups, const) DECL_THUNK1(void, SourceGroup, setGain,, ALfloat) diff --git a/src/sourcegroup.h b/src/sourcegroup.h index 94fd00b..6f75591 100644 --- a/src/sourcegroup.h +++ b/src/sourcegroup.h @@ -25,19 +25,11 @@ class SourceGroupImpl : SourceGroupProps { const String mName; - void applyPropTree(SourceGroupProps &props) const - { - props.mGain *= mGain; - props.mPitch *= mPitch; - if(mParent) - mParent->applyPropTree(props); - } - void update(ALfloat gain, ALfloat pitch); - void setParentGroup(SourceGroupImpl *group); - void unsetParentGroup(); + void unsetParent(); + void insertSubGroup(SourceGroupImpl *group); void eraseSubGroup(SourceGroupImpl *group); bool findInSubGroups(SourceGroupImpl *group) const; @@ -59,14 +51,10 @@ public: ALfloat getAppliedGain() const { return mGain * mParentProps.mGain; } ALfloat getAppliedPitch() const { return mPitch * mParentProps.mPitch; } - void addSource(Source source); - void removeSource(Source source); - - void addSources(ArrayView sources); - void removeSources(ArrayView sources); + void insertSource(SourceImpl *source); + void eraseSource(SourceImpl *source); - void addSubGroup(SourceGroup group); - void removeSubGroup(SourceGroup group); + void setParentGroup(SourceGroup group); Vector getSources() const; -- 2.11.4.GIT