virtual void Stop();
// can be called by a timer for repeated tasks during playback
virtual void SoundTask();
+ // mark this to be deleted
+ virtual void MarkForDeletion();
+ virtual bool IsMarkedForDeletion() const { return m_markedForDeletion; }
// does the true work of stopping and cleaning up
virtual void DoStop() = 0;
unsigned int m_flags;
wxSoundTimer* m_pTimer;
+ bool m_markedForDeletion;
} ;
class WXDLLIMPEXP_ADV wxSound : public wxSoundBase
m_pSndChannel = NULL;
wxSound::SoundStopped(this);
}
+
+ if (IsMarkedForDeletion())
+ delete this;
}
bool wxOSXSoundManagerSoundData::Play(unsigned flags)
wxOSXAudioToolboxSoundData* data = (wxOSXAudioToolboxSoundData*) soundRef;
data->SoundCompleted();
+
+ if (data->IsMarkedForDeletion())
+ delete data;
}
void wxOSXAudioToolboxSoundData::SoundCompleted()
virtual ~wxSoundTimer()
{
Stop();
- m_sound->DoStop();
+ if (m_sound)
+ m_sound->DoStop();
}
void Notify()
{
- m_sound->SoundTask();
+ if (m_sound)
+ m_sound->SoundTask();
}
protected:
wxSoundData::wxSoundData()
{
m_pTimer = NULL;
+ m_markedForDeletion = false;
}
wxSoundData::~wxSoundData()
{
}
+void wxSoundData::MarkForDeletion()
+{
+ m_markedForDeletion = true;
+}
+
void wxSoundData::Stop()
{
DoStop();
wxSound::~wxSound()
{
- delete m_data;
+ // if the sound is in a playing state, just mark it to be deleted and
+ // delete it after it plays. Otherwise, async sounds created on the stack
+ // may never get the chance to play.
+ bool isPlaying = false;
+ for ( wxVector<wxSoundData*>::reverse_iterator s = s_soundsPlaying.rbegin();
+ s != s_soundsPlaying.rend(); ++s )
+ {
+ if (*s == m_data)
+ {
+ isPlaying = true;
+ break;
+ }
+ }
+
+ if (isPlaying)
+ m_data->MarkForDeletion();
+ else
+ delete m_data;
}
void wxSound::Init()