@@ -19,6 +19,7 @@ void SoundBlocks::registerBlocks(IEngine *engine)
1919{
2020 // Blocks
2121 engine->addCompileFunction (this , " sound_play" , &compilePlay);
22+ engine->addCompileFunction (this , " sound_playuntildone" , &compilePlayUntilDone);
2223 engine->addCompileFunction (this , " sound_changevolumeby" , &compileChangeVolumeBy);
2324 engine->addCompileFunction (this , " sound_setvolumeto" , &compileSetVolumeTo);
2425 engine->addCompileFunction (this , " sound_volume" , &compileVolume);
@@ -28,13 +29,13 @@ void SoundBlocks::registerBlocks(IEngine *engine)
2829 engine->addInput (this , " VOLUME" , VOLUME);
2930}
3031
31- void SoundBlocks::compilePlay (Compiler *compiler)
32+ bool SoundBlocks::compilePlayCommon (Compiler *compiler, bool untilDone, bool *byIndex )
3233{
3334 Target *target = compiler->target ();
3435 assert (target);
3536
3637 if (!target)
37- return ;
38+ return false ;
3839
3940 Input *input = compiler->input (SOUND_MENU);
4041
@@ -49,16 +50,46 @@ void SoundBlocks::compilePlay(Compiler *compiler)
4950
5051 if (v.type () == Value::Type::Integer) {
5152 compiler->addConstValue (v.toLong () - 1 );
52- compiler->addFunctionCall (&playByIndex);
53+ compiler->addFunctionCall (untilDone ? &playByIndexUntilDone : &playByIndex);
54+
55+ if (byIndex)
56+ *byIndex = true ;
57+
58+ return true ;
5359 }
5460 } else {
5561 compiler->addConstValue (index);
56- compiler->addFunctionCall (&playByIndex);
62+ compiler->addFunctionCall (untilDone ? &playByIndexUntilDone : &playByIndex);
63+
64+ if (byIndex)
65+ *byIndex = true ;
66+
67+ return true ;
5768 }
5869 } else {
5970 compiler->addInput (input);
60- compiler->addFunctionCall (&play);
71+ compiler->addFunctionCall (untilDone ? &playUntilDone : &play);
72+
73+ if (byIndex)
74+ *byIndex = false ;
75+
76+ return true ;
6177 }
78+
79+ return false ;
80+ }
81+
82+ void SoundBlocks::compilePlay (Compiler *compiler)
83+ {
84+ compilePlayCommon (compiler, false );
85+ }
86+
87+ void SoundBlocks::compilePlayUntilDone (Compiler *compiler)
88+ {
89+ bool byIndex = false ;
90+
91+ if (compilePlayCommon (compiler, true , &byIndex))
92+ compiler->addFunctionCall (byIndex ? &checkSoundByIndex : &checkSound);
6293}
6394
6495void SoundBlocks::compileChangeVolumeBy (Compiler *compiler)
@@ -92,7 +123,7 @@ Sound *SoundBlocks::getSoundByIndex(Target *target, long index)
92123 return target->soundAt (index).get ();
93124}
94125
95- unsigned int SoundBlocks::play (VirtualMachine *vm)
126+ Sound * SoundBlocks::playCommon (VirtualMachine *vm)
96127{
97128 Target *target = vm->target ();
98129 assert (target);
@@ -101,30 +132,128 @@ unsigned int SoundBlocks::play(VirtualMachine *vm)
101132 if (target) {
102133 Sound *sound = target->soundAt (target->findSound (name->toString ())).get ();
103134
104- if (sound)
135+ if (sound) {
105136 sound->start ();
137+ return sound;
138+ }
139+
106140 else if (name->type () == Value::Type::Integer) {
107141 sound = getSoundByIndex (target, name->toLong () - 1 );
108142
109- if (sound)
143+ if (sound) {
110144 sound->start ();
145+ return sound;
146+ }
111147 }
112148 }
113149
150+ return nullptr ;
151+ }
152+
153+ Sound *SoundBlocks::playByIndexCommon (VirtualMachine *vm)
154+ {
155+ Target *target = vm->target ();
156+ assert (target);
157+
158+ if (target) {
159+ Sound *sound = getSoundByIndex (target, vm->getInput (0 , 1 )->toInt ());
160+
161+ if (sound) {
162+ sound->start ();
163+ return sound;
164+ }
165+ }
166+
167+ return nullptr ;
168+ }
169+
170+ unsigned int SoundBlocks::play (VirtualMachine *vm)
171+ {
172+ Sound *sound = playCommon (vm);
173+
174+ if (sound)
175+ m_waitingSounds.erase (sound);
176+
114177 return 1 ;
115178}
116179
117180unsigned int SoundBlocks::playByIndex (VirtualMachine *vm)
181+ {
182+ Sound *sound = playByIndexCommon (vm);
183+
184+ if (sound)
185+ m_waitingSounds.erase (sound);
186+
187+ return 1 ;
188+ }
189+
190+ unsigned int SoundBlocks::playUntilDone (VirtualMachine *vm)
191+ {
192+ Sound *sound = playCommon (vm);
193+
194+ if (sound)
195+ m_waitingSounds[sound] = vm;
196+
197+ return 0 ; // leave the register for checkSound()
198+ }
199+
200+ unsigned int SoundBlocks::playByIndexUntilDone (VirtualMachine *vm)
201+ {
202+ Sound *sound = playByIndexCommon (vm);
203+
204+ if (sound)
205+ m_waitingSounds[sound] = vm;
206+
207+ return 0 ; // leave the register for checkSoundByIndex()
208+ }
209+
210+ unsigned int SoundBlocks::checkSound (VirtualMachine *vm)
211+ {
212+ Target *target = vm->target ();
213+ assert (target);
214+ const Value *name = vm->getInput (0 , 1 );
215+
216+ if (target) {
217+ Sound *sound = target->soundAt (target->findSound (name->toString ())).get ();
218+
219+ if (!sound && name->type () == Value::Type::Integer)
220+ sound = getSoundByIndex (target, name->toLong () - 1 );
221+
222+ if (sound) {
223+ auto it = m_waitingSounds.find (sound);
224+
225+ if (it != m_waitingSounds.cend () && it->second == vm) {
226+ if (sound->isPlaying ())
227+ vm->stop (true , true , true );
228+ else
229+ m_waitingSounds.erase (sound);
230+ }
231+ }
232+ }
233+
234+ return 1 ;
235+ }
236+
237+ unsigned int SoundBlocks::checkSoundByIndex (VirtualMachine *vm)
118238{
119239 Target *target = vm->target ();
120240 assert (target);
121241
122242 if (target) {
123243 auto sound = getSoundByIndex (target, vm->getInput (0 , 1 )->toInt ());
124244
125- if (sound)
126- sound->start ();
245+ if (sound) {
246+ auto it = m_waitingSounds.find (sound);
247+
248+ if (it != m_waitingSounds.cend () && it->second == vm) {
249+ if (sound->isPlaying ())
250+ vm->stop (true , true , true );
251+ else
252+ m_waitingSounds.erase (sound);
253+ }
254+ }
127255 }
256+
128257 return 1 ;
129258}
130259
0 commit comments