sound: SoundPlexWave shall self-delete when the corresponding voice has stopped, and voice deletion is enabled by maintainance of the VoiceCollection linked list

This commit is contained in:
Adam Jensen 2022-12-22 22:45:22 +00:00
parent b5f2657ede
commit 8cf711f634
4 changed files with 134 additions and 5 deletions

View File

@ -20,9 +20,27 @@ SoundPlexWave::SoundPlexWave(
}
}
SoundPlexWave::~SoundPlexWave() {
// TODO
if (m_voice)
delete m_voice;
}
SoundPlex *SoundPlexWave::Update(float time) {
// TODO
return nullptr;
if (auto voice = static_cast<VoiceImpl*>(m_voice)) {
if (voice->m_bStoppedFMOD) {
delete voice;
m_voice = nullptr;
}
}
if (m_voice) {
// TODO
return this;
} else {
delete this;
return nullptr;
}
}
void SoundPlexWave::End(SoundPlexWave::EndType end) {

View File

@ -16,7 +16,7 @@ public:
Controls3d *controls3d,
SoundOwner *owner);
~SoundPlexWave() = default;
~SoundPlexWave() override;
SoundPlex *Update(float) override;
void End(EndType) override;
};

View File

@ -81,13 +81,109 @@ VoiceImpl::~VoiceImpl() {
}
void VoiceCollection::Add(VoiceImpl *voice) { // line 1239
m_nVoices++;
m_voices.push_front(voice);
// TODO
if (m_voices.empty()) {
// head [BEFORE]
// | `---.
// v \
// link1 -> voice1
// ...
m_voices.push_front(voice);
voice->it = m_voices.begin();
// head [BETWEEN]
// | `----------.
// v \ \
// link2 -> voice2 )
// | /
// v /
// link1 -> voice1
// ...
auto it = m_voices.begin(); ++it;
it->it = it;
// head [AFTER]
// | `---.
// v \
// link2 -> voice2
// | `---.
// v \
// link1 -> voice1
// ...
} else {
// head [BEFORE]
// |
// v
// nullptr
m_voices.push_front(voice);
voice->it = m_voices.begin();
// head [AFTER]
// | `---.
// v \
// link1 -> voice1
// |
// v
// nullptr
}
}
void VoiceCollection::Remove(VoiceImpl *voice) { // line 1260
// TODO: remove voice from linked list
auto nextIt = voice->it; ++nextIt;
if (nextIt == m_voices.end()) {
// iterator
// | `---.
// v \
// link1 -> voice1
// |
// v
// nullptr
m_voices.erase(voice->it);
// iterator
// |
// v (voice1)
// nullptr
} else {
// iterator
// | `---.
// v \
// link1 -> voice1
// | `---.
// v \
// link0 -> voice0
// ...
m_voices.erase(voice->it);
// iterator <- (voice1)
// |
// v
// link0 -> voice0
// ...
nextIt->it = voice->it;
// iterator <- (voice1)
// | `---.
// v \
// link0 -> voice0
// ...
}
}
void VoiceCollection::Update(float seconds) { // line 1283

View File

@ -13,7 +13,9 @@ struct SList {
struct iterator {
Node **link;
inline T& operator*() { return (*link)->item; }
inline T& operator->() { return (*link)->item; }
inline void operator++() { link = &(*link)->next; }
inline bool operator==(iterator const& other) { return *link == *other.link; }
inline bool operator!=(iterator const& other) { return *link != *other.link; }
};
@ -26,6 +28,19 @@ struct SList {
inline iterator begin() { return {&head}; }
inline iterator end() { return {&endPtr}; }
inline bool empty() { return head != nullptr; }
inline void erase(iterator it) {
if (auto link = it.link) {
Node *erasedLink = *link;
if (erasedLink) {
*link = erasedLink->next;
delete erasedLink;
} else {
*link = nullptr;
}
}
}
};
}