Skip to content

Commit 8912b60

Browse files
committed
Add stopSounds method to IEngine
1 parent 4376d7b commit 8912b60

File tree

6 files changed

+52
-0
lines changed

6 files changed

+52
-0
lines changed

include/scratchcpp/iengine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ class LIBSCRATCHCPP_EXPORT IEngine
8181
/*! Automatically called from clones that are being deleted. */
8282
virtual void deinitClone(std::shared_ptr<Sprite> clone) = 0;
8383

84+
/*! Stops all currently playing sounds. */
85+
virtual void stopSounds() = 0;
86+
8487
/*! Steps all currently running threads. Use this to implement a custom event loop. */
8588
virtual void step() = 0;
8689

src/engine/internal/engine.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <scratchcpp/comment.h>
1717
#include <scratchcpp/costume.h>
1818
#include <scratchcpp/keyevent.h>
19+
#include <scratchcpp/sound.h>
1920
#include <cassert>
2021
#include <iostream>
2122

@@ -189,6 +190,7 @@ void Engine::stop()
189190
{
190191
// https://github.com/scratchfoundation/scratch-vm/blob/f1aa92fad79af17d9dd1c41eeeadca099339a9f1/src/engine/runtime.js#L2057-L2081
191192
deleteClones();
193+
stopSounds();
192194

193195
if (m_activeThread) {
194196
stopThread(m_activeThread.get());
@@ -276,6 +278,19 @@ void Engine::deinitClone(std::shared_ptr<Sprite> clone)
276278
m_executableTargets.erase(std::remove(m_executableTargets.begin(), m_executableTargets.end(), clone.get()), m_executableTargets.end());
277279
}
278280

281+
void Engine::stopSounds()
282+
{
283+
// TODO: Loop through clones
284+
for (auto target : m_targets) {
285+
const auto &sounds = target->sounds();
286+
287+
for (auto sound : sounds) {
288+
if (sound->isPlaying())
289+
sound->stop();
290+
}
291+
}
292+
}
293+
279294
void Engine::step()
280295
{
281296
// https://github.com/scratchfoundation/scratch-vm/blob/f1aa92fad79af17d9dd1c41eeeadca099339a9f1/src/engine/runtime.js#L2087C6-L2155

src/engine/internal/engine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class Engine : public IEngine
4141
void stopTarget(Target *target, VirtualMachine *exceptScript) override;
4242
void initClone(std::shared_ptr<Sprite> clone) override;
4343
void deinitClone(std::shared_ptr<Sprite> clone) override;
44+
void stopSounds() override;
4445

4546
void step() override;
4647
void run() override;

test/engine/engine_test.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66
#include <scratchcpp/variable.h>
77
#include <scratchcpp/list.h>
88
#include <scratchcpp/keyevent.h>
9+
#include <scratch/sound_p.h>
910
#include <timermock.h>
1011
#include <clockmock.h>
12+
#include <audioplayerfactorymock.h>
13+
#include <audioplayermock.h>
1114
#include <thread>
1215

1316
#include "../common.h"
@@ -70,6 +73,35 @@ TEST(EngineTest, IsRunning)
7073
ASSERT_FALSE(engine.isRunning());
7174
}
7275

76+
TEST(EngineTest, StopSounds)
77+
{
78+
AudioPlayerFactoryMock factory;
79+
auto player1 = std::make_shared<AudioPlayerMock>();
80+
auto player2 = std::make_shared<AudioPlayerMock>();
81+
auto player3 = std::make_shared<AudioPlayerMock>();
82+
SoundPrivate::playerFactory = &factory;
83+
EXPECT_CALL(factory, create()).WillOnce(Return(player1)).WillOnce(Return(player2)).WillOnce(Return(player3));
84+
EXPECT_CALL(*player1, load).WillOnce(Return(true));
85+
EXPECT_CALL(*player2, load).WillOnce(Return(true));
86+
EXPECT_CALL(*player3, load).WillOnce(Return(true));
87+
EXPECT_CALL(*player1, setVolume).Times(2);
88+
EXPECT_CALL(*player2, setVolume).Times(2);
89+
EXPECT_CALL(*player3, setVolume).Times(2);
90+
Project p("sounds.sb3");
91+
ASSERT_TRUE(p.load());
92+
93+
auto engine = p.engine();
94+
95+
EXPECT_CALL(*player1, isPlaying()).WillOnce(Return(false));
96+
EXPECT_CALL(*player2, isPlaying()).WillOnce(Return(true));
97+
EXPECT_CALL(*player3, isPlaying()).WillOnce(Return(true));
98+
EXPECT_CALL(*player2, stop());
99+
EXPECT_CALL(*player3, stop());
100+
engine->stopSounds();
101+
102+
SoundPrivate::playerFactory = nullptr;
103+
}
104+
73105
TEST(EngineTest, Step)
74106
{
75107
Project p("step.sb3");

test/mocks/enginemock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class EngineMock : public IEngine
2424
MOCK_METHOD(void, stopTarget, (Target *, VirtualMachine *), (override));
2525
MOCK_METHOD(void, initClone, (std::shared_ptr<Sprite>), (override));
2626
MOCK_METHOD(void, deinitClone, (std::shared_ptr<Sprite>), (override));
27+
MOCK_METHOD(void, stopSounds, (), (override));
2728

2829
MOCK_METHOD(void, step, (), (override));
2930
MOCK_METHOD(void, run, (), (override));

test/sounds.sb3

183 KB
Binary file not shown.

0 commit comments

Comments
 (0)