Skip to content

Commit f12f7e2

Browse files
authored
Merge pull request #302 from scratchcpp/sprite_fencing_option
Add sprite fencing option
2 parents f16cd17 + 5ad8672 commit f12f7e2

File tree

8 files changed

+80
-5
lines changed

8 files changed

+80
-5
lines changed

include/scratchcpp/iengine.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ class LIBSCRATCHCPP_EXPORT IEngine
146146
/*! Sets the maximum number of clones (use -1 or any negative number to disable the limit). */
147147
virtual void setCloneLimit(int limit) = 0;
148148

149+
/*! Returns true if sprite fencing is enabled. */
150+
virtual bool spriteFencingEnabled() const = 0;
151+
152+
/*! Toggles sprite fencing. */
153+
virtual void setSpriteFencingEnabled(bool enable) = 0;
154+
149155
/*! Returns true if there are any running script of the broadcast with the given index. */
150156
virtual bool broadcastRunning(unsigned int index, VirtualMachine *sourceScript) = 0;
151157

src/engine/internal/engine.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,16 @@ void Engine::setCloneLimit(int limit)
491491
m_cloneLimit = limit < 0 ? -1 : limit;
492492
}
493493

494+
bool Engine::spriteFencingEnabled() const
495+
{
496+
return m_spriteFencingEnabled;
497+
}
498+
499+
void Engine::setSpriteFencingEnabled(bool enable)
500+
{
501+
m_spriteFencingEnabled = enable;
502+
}
503+
494504
bool Engine::broadcastRunning(unsigned int index, VirtualMachine *sourceScript)
495505
{
496506
if (index < 0 || index >= m_broadcasts.size())

src/engine/internal/engine.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ class Engine : public IEngine
6666
int cloneLimit() const override;
6767
void setCloneLimit(int limit) override;
6868

69+
bool spriteFencingEnabled() const override;
70+
void setSpriteFencingEnabled(bool enable) override;
71+
6972
bool broadcastRunning(unsigned int index, VirtualMachine *sourceScript) override;
7073
bool broadcastByPtrRunning(Broadcast *broadcast, VirtualMachine *sourceScript) override;
7174

@@ -151,6 +154,7 @@ class Engine : public IEngine
151154
unsigned int m_stageHeight = 360;
152155
int m_cloneLimit = 300;
153156
std::vector<Sprite *> m_clones;
157+
bool m_spriteFencingEnabled = true;
154158

155159
bool m_running = false;
156160
bool m_breakFrame = false;

src/scratch/sprite.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,5 +316,11 @@ Target *Sprite::dataSource() const
316316

317317
void Sprite::setXY(double x, double y)
318318
{
319-
impl->getFencedPosition(x, y, &impl->x, &impl->y);
319+
IEngine *eng = engine();
320+
321+
if (eng && !eng->spriteFencingEnabled()) {
322+
impl->x = x;
323+
impl->y = y;
324+
} else
325+
impl->getFencedPosition(x, y, &impl->x, &impl->y);
320326
}

test/engine/engine_test.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,18 @@ TEST(EngineTest, StageHeight)
190190
ASSERT_EQ(engine.stageHeight(), 515);
191191
}
192192

193+
TEST(EngineTest, SpriteFencingEnabled)
194+
{
195+
Engine engine;
196+
ASSERT_TRUE(engine.spriteFencingEnabled());
197+
198+
engine.setSpriteFencingEnabled(false);
199+
ASSERT_FALSE(engine.spriteFencingEnabled());
200+
201+
engine.setSpriteFencingEnabled(true);
202+
ASSERT_TRUE(engine.spriteFencingEnabled());
203+
}
204+
193205
TEST(EngineTest, BreakFrame)
194206
{
195207
Engine engine;

test/mocks/enginemock.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ class EngineMock : public IEngine
5353
MOCK_METHOD(int, cloneLimit, (), (const, override));
5454
MOCK_METHOD(void, setCloneLimit, (int), (override));
5555

56+
MOCK_METHOD(bool, spriteFencingEnabled, (), (const, override));
57+
MOCK_METHOD(void, setSpriteFencingEnabled, (bool), (override));
58+
5659
MOCK_METHOD(bool, broadcastRunning, (unsigned int, VirtualMachine *), (override));
5760
MOCK_METHOD(bool, broadcastByPtrRunning, (Broadcast *, VirtualMachine *), (override));
5861

test/scratch_classes/sprite_test.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,14 +217,14 @@ TEST(SpriteTest, XY)
217217
sprite.setX(-53.25);
218218
ASSERT_EQ(sprite.x(), -53.25);
219219

220-
sprite.setX(239.999);
221-
ASSERT_EQ(sprite.x(), 239.999);
220+
sprite.setX(259.999);
221+
ASSERT_EQ(sprite.x(), 259.999);
222222

223223
sprite.setY(-53.25);
224224
ASSERT_EQ(sprite.y(), -53.25);
225225

226-
sprite.setY(179.999);
227-
ASSERT_EQ(sprite.y(), 179.999);
226+
sprite.setY(189.999);
227+
ASSERT_EQ(sprite.y(), 189.999);
228228

229229
auto imageFormatFactory = std::make_shared<ImageFormatFactoryMock>();
230230
auto imageFormat = std::make_shared<ImageFormatMock>();
@@ -265,60 +265,84 @@ TEST(SpriteTest, XY)
265265

266266
EXPECT_CALL(*imageFormat, width()).WillOnce(Return(4));
267267
EXPECT_CALL(*imageFormat, height()).WillOnce(Return(3));
268+
EXPECT_CALL(engine, spriteFencingEnabled()).WillOnce(Return(true));
268269
EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480));
269270
EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360));
270271
sprite.setX(230);
271272
ASSERT_EQ(sprite.x(), 230);
272273

273274
EXPECT_CALL(*imageFormat, width()).WillOnce(Return(4));
274275
EXPECT_CALL(*imageFormat, height()).WillOnce(Return(3));
276+
EXPECT_CALL(engine, spriteFencingEnabled()).WillOnce(Return(true));
275277
EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480));
276278
EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360));
277279
sprite.setX(-230);
278280
ASSERT_EQ(sprite.x(), -230);
279281

280282
EXPECT_CALL(*imageFormat, width()).WillOnce(Return(4));
281283
EXPECT_CALL(*imageFormat, height()).WillOnce(Return(3));
284+
EXPECT_CALL(engine, spriteFencingEnabled()).WillOnce(Return(true));
282285
EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480));
283286
EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360));
284287
sprite.setX(250);
285288
ASSERT_EQ(sprite.x(), 241);
286289

290+
EXPECT_CALL(engine, spriteFencingEnabled()).WillOnce(Return(false));
291+
sprite.setX(250);
292+
ASSERT_EQ(sprite.x(), 250);
293+
287294
EXPECT_CALL(*imageFormat, width()).WillOnce(Return(4));
288295
EXPECT_CALL(*imageFormat, height()).WillOnce(Return(3));
296+
EXPECT_CALL(engine, spriteFencingEnabled()).WillOnce(Return(true));
289297
EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480));
290298
EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360));
291299
sprite.setX(-250);
292300
ASSERT_EQ(sprite.x(), -241);
293301

302+
EXPECT_CALL(engine, spriteFencingEnabled()).WillOnce(Return(false));
303+
sprite.setX(-250);
304+
ASSERT_EQ(sprite.x(), -250);
305+
294306
EXPECT_CALL(*imageFormat, width()).WillOnce(Return(4));
295307
EXPECT_CALL(*imageFormat, height()).WillOnce(Return(3));
308+
EXPECT_CALL(engine, spriteFencingEnabled()).WillOnce(Return(true));
296309
EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480));
297310
EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360));
298311
sprite.setY(170);
299312
ASSERT_EQ(sprite.y(), 170);
300313

301314
EXPECT_CALL(*imageFormat, width()).WillOnce(Return(4));
302315
EXPECT_CALL(*imageFormat, height()).WillOnce(Return(3));
316+
EXPECT_CALL(engine, spriteFencingEnabled()).WillOnce(Return(true));
303317
EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480));
304318
EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360));
305319
sprite.setY(-170);
306320
ASSERT_EQ(sprite.y(), -170);
307321

308322
EXPECT_CALL(*imageFormat, width()).WillOnce(Return(4));
309323
EXPECT_CALL(*imageFormat, height()).WillOnce(Return(3));
324+
EXPECT_CALL(engine, spriteFencingEnabled()).WillOnce(Return(true));
310325
EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480));
311326
EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360));
312327
sprite.setY(190);
313328
ASSERT_EQ(sprite.y(), 181);
314329

330+
EXPECT_CALL(engine, spriteFencingEnabled()).WillOnce(Return(false));
331+
sprite.setY(190);
332+
ASSERT_EQ(sprite.y(), 190);
333+
315334
EXPECT_CALL(*imageFormat, width()).WillOnce(Return(4));
316335
EXPECT_CALL(*imageFormat, height()).WillOnce(Return(3));
336+
EXPECT_CALL(engine, spriteFencingEnabled()).WillOnce(Return(true));
317337
EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480));
318338
EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360));
319339
sprite.setY(-190);
320340
ASSERT_EQ(sprite.y(), -180);
321341

342+
EXPECT_CALL(engine, spriteFencingEnabled()).WillOnce(Return(false));
343+
sprite.setY(-190);
344+
ASSERT_EQ(sprite.y(), -190);
345+
322346
ScratchConfiguration::removeImageFormat("test");
323347
}
324348

test/target_interfaces/ispritehandler_test.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,27 @@ TEST_F(ISpriteHandlerTest, Visible)
5252
TEST_F(ISpriteHandlerTest, X)
5353
{
5454
EXPECT_CALL(m_handler, onXChanged(189.46)).Times(1);
55+
EXPECT_CALL(m_engine, spriteFencingEnabled()).WillOnce(Return(true));
5556
EXPECT_CALL(m_engine, stageWidth()).WillOnce(Return(480));
5657
EXPECT_CALL(m_engine, stageHeight()).WillOnce(Return(360));
5758
m_sprite.setX(189.46);
59+
60+
EXPECT_CALL(m_handler, onXChanged(284.61)).Times(1);
61+
EXPECT_CALL(m_engine, spriteFencingEnabled()).WillOnce(Return(false));
62+
m_sprite.setX(284.61);
5863
}
5964

6065
TEST_F(ISpriteHandlerTest, Y)
6166
{
6267
EXPECT_CALL(m_handler, onYChanged(-153.7)).Times(1);
68+
EXPECT_CALL(m_engine, spriteFencingEnabled()).WillOnce(Return(true));
6369
EXPECT_CALL(m_engine, stageWidth()).WillOnce(Return(480));
6470
EXPECT_CALL(m_engine, stageHeight()).WillOnce(Return(360));
6571
m_sprite.setY(-153.7);
72+
73+
EXPECT_CALL(m_handler, onYChanged(207.08)).Times(1);
74+
EXPECT_CALL(m_engine, spriteFencingEnabled()).WillOnce(Return(false));
75+
m_sprite.setY(207.08);
6676
}
6777

6878
TEST_F(ISpriteHandlerTest, Size)

0 commit comments

Comments
 (0)