avoiding reentrancy problems and congestion
[wxWidgets.git] / src / osx / sound_osx.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/sound_osx.cpp
3 // Purpose: wxSound class common osx code
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 2009-09-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #if wxUSE_SOUND
16
17 #include "wx/sound.h"
18
19 #ifndef WX_PRECOMP
20 #include "wx/object.h"
21 #include "wx/string.h"
22 #include "wx/intl.h"
23 #include "wx/log.h"
24 #include "wx/timer.h"
25 #endif
26
27 #include "wx/file.h"
28
29 #include "wx/vector.h"
30
31 class wxSoundTimer : public wxTimer
32 {
33 public:
34 wxSoundTimer(wxSoundData* snd)
35 : m_sound(snd)
36 {
37 }
38
39 virtual ~wxSoundTimer()
40 {
41 Stop();
42 if (m_sound)
43 m_sound->DoStop();
44 }
45
46 void Notify()
47 {
48 if (m_sound)
49 m_sound->SoundTask();
50 }
51
52 protected:
53 wxSoundData* m_sound;
54 };
55
56 wxVector<wxSoundData*> s_soundsPlaying;
57
58 wxSoundData::wxSoundData()
59 {
60 m_pTimer = NULL;
61 m_markedForDeletion = false;
62 }
63
64 wxSoundData::~wxSoundData()
65 {
66 }
67
68 void wxSoundData::MarkForDeletion()
69 {
70 m_markedForDeletion = true;
71 }
72
73 void wxSoundData::Stop()
74 {
75 DoStop();
76 wxDELETE(m_pTimer);
77 }
78
79 //Time between timer calls
80 #define MOVIE_DELAY 100
81
82 void wxSoundData::SoundTask()
83 {
84 }
85
86 void wxSoundData::CreateAndStartTimer()
87 {
88 //Start timer and play movie asyncronously
89 m_pTimer = new wxSoundTimer(this);
90 m_pTimer->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS);
91 }
92
93 wxSound::wxSound()
94 {
95 Init();
96 }
97
98 wxSound::wxSound(const wxString& sFileName, bool isResource)
99 {
100 Init();
101 Create(sFileName, isResource);
102 }
103
104 wxSound::wxSound(size_t size, const void* data)
105 {
106 Init();
107 Create( size, data );
108 }
109
110 wxSound::~wxSound()
111 {
112 // if the sound is in a playing state, just mark it to be deleted and
113 // delete it after it plays. Otherwise, async sounds created on the stack
114 // may never get the chance to play.
115 bool isPlaying = false;
116 for ( wxVector<wxSoundData*>::reverse_iterator s = s_soundsPlaying.rbegin();
117 s != s_soundsPlaying.rend(); ++s )
118 {
119 if (*s == m_data)
120 {
121 isPlaying = true;
122 break;
123 }
124 }
125
126 if (isPlaying)
127 m_data->MarkForDeletion();
128 else
129 delete m_data;
130 }
131
132 void wxSound::Init()
133 {
134 m_data = NULL;
135 }
136
137 bool wxSound::DoPlay(unsigned flags) const
138 {
139 if ( m_data )
140 {
141 s_soundsPlaying.push_back(m_data);
142 if ( !m_data->Play(flags) )
143 s_soundsPlaying.pop_back();
144 }
145
146 return false;
147 }
148
149 bool wxSound::IsPlaying()
150 {
151 return s_soundsPlaying.size() > 0;
152 }
153
154 void wxSound::Stop()
155 {
156 for ( wxVector<wxSoundData*>::reverse_iterator s = s_soundsPlaying.rbegin();
157 s != s_soundsPlaying.rend(); ++s )
158 {
159 (*s)->Stop();
160 }
161 }
162
163 // Notification when a sound has stopped
164 void wxSound::SoundStopped(const wxSoundData* data)
165 {
166 for ( wxVector<wxSoundData*>::iterator s = s_soundsPlaying.begin();
167 s != s_soundsPlaying.end(); ++s )
168 {
169 if ( (*s) == data )
170 {
171 s_soundsPlaying.erase(s);
172 break;
173 }
174 }
175 }
176
177 #endif //wxUSE_SOUND