Skip to content

Commit bf01dd9

Browse files
committed
Implement sensing_keypressed block
1 parent 8439b3a commit bf01dd9

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

src/blocks/sensingblocks.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ void SensingBlocks::registerBlocks(IEngine *engine)
4242
engine->addCompileFunction(this, "sensing_distanceto", &compileDistanceTo);
4343
engine->addCompileFunction(this, "sensing_askandwait", &compileAskAndWait);
4444
engine->addCompileFunction(this, "sensing_answer", &compileAnswer);
45+
engine->addCompileFunction(this, "sensing_keypressed", &compileKeyPressed);
4546
}
4647

4748
void SensingBlocks::onInit(IEngine *engine)
@@ -160,6 +161,12 @@ CompilerValue *SensingBlocks::compileAnswer(Compiler *compiler)
160161
return compiler->addFunctionCallWithCtx("sensing_answer", Compiler::StaticType::String);
161162
}
162163

164+
CompilerValue *SensingBlocks::compileKeyPressed(Compiler *compiler)
165+
{
166+
CompilerValue *key = compiler->addInput("KEY_OPTION");
167+
return compiler->addFunctionCallWithCtx("sensing_keypressed", Compiler::StaticType::Bool, { Compiler::StaticType::String }, { key });
168+
}
169+
163170
void SensingBlocks::onAnswer(const std::string &answer)
164171
{
165172
// https://github.com/scratchfoundation/scratch-vm/blob/6055823f203a696165084b873e661713806583ec/src/blocks/scratch3_sensing.js#L99-L115
@@ -314,3 +321,10 @@ extern "C" StringPtr *sensing_answer(ExecutionContext *ctx)
314321
string_assign(ret, ctx->engine()->answer());
315322
return ret;
316323
}
324+
325+
extern "C" bool sensing_keypressed(ExecutionContext *ctx, const StringPtr *key)
326+
{
327+
// TODO: Use UTF-16 in engine
328+
std::string u8name = utf8::utf16to8(std::u16string(key->data));
329+
return ctx->engine()->keyPressed(u8name);
330+
}

src/blocks/sensingblocks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class SensingBlocks : public IExtension
4848
static CompilerValue *compileDistanceTo(Compiler *compiler);
4949
static CompilerValue *compileAskAndWait(Compiler *compiler);
5050
static CompilerValue *compileAnswer(Compiler *compiler);
51+
static CompilerValue *compileKeyPressed(Compiler *compiler);
5152

5253
static void onAnswer(const std::string &answer);
5354
static void enqueueAsk(const std::string &question, Thread *thread);

test/blocks/sensing_blocks_test.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,3 +1175,57 @@ TEST_F(SensingBlocksTest, AskAndWait_KillThread)
11751175
Thread thread2(sprite.get(), &m_engineMock, &script);
11761176
thread2.run();
11771177
}
1178+
1179+
TEST_F(SensingBlocksTest, KeyPressed_Space)
1180+
{
1181+
auto targetMock = std::make_shared<TargetMock>();
1182+
targetMock->setEngine(&m_engineMock);
1183+
1184+
ScriptBuilder builder(m_extension.get(), m_engine, targetMock);
1185+
builder.addBlock("sensing_keypressed");
1186+
builder.addDropdownInput("KEY_OPTION", "space");
1187+
Block *block = builder.currentBlock();
1188+
1189+
Compiler compiler(&m_engineMock, targetMock.get());
1190+
auto code = compiler.compile(block, Compiler::CodeType::Reporter);
1191+
Script script(targetMock.get(), block, &m_engineMock);
1192+
script.setCode(code);
1193+
Thread thread(targetMock.get(), &m_engineMock, &script);
1194+
1195+
EXPECT_CALL(m_engineMock, keyPressed("space")).WillOnce(Return(true));
1196+
ValueData value = thread.runReporter();
1197+
ASSERT_TRUE(value_toBool(&value));
1198+
value_free(&value);
1199+
1200+
EXPECT_CALL(m_engineMock, keyPressed("space")).WillOnce(Return(false));
1201+
value = thread.runReporter();
1202+
ASSERT_FALSE(value_toBool(&value));
1203+
value_free(&value);
1204+
}
1205+
1206+
TEST_F(SensingBlocksTest, KeyPressed_M)
1207+
{
1208+
auto targetMock = std::make_shared<TargetMock>();
1209+
targetMock->setEngine(&m_engineMock);
1210+
1211+
ScriptBuilder builder(m_extension.get(), m_engine, targetMock);
1212+
builder.addBlock("sensing_keypressed");
1213+
builder.addDropdownInput("KEY_OPTION", "m");
1214+
Block *block = builder.currentBlock();
1215+
1216+
Compiler compiler(&m_engineMock, targetMock.get());
1217+
auto code = compiler.compile(block, Compiler::CodeType::Reporter);
1218+
Script script(targetMock.get(), block, &m_engineMock);
1219+
script.setCode(code);
1220+
Thread thread(targetMock.get(), &m_engineMock, &script);
1221+
1222+
EXPECT_CALL(m_engineMock, keyPressed("m")).WillOnce(Return(true));
1223+
ValueData value = thread.runReporter();
1224+
ASSERT_TRUE(value_toBool(&value));
1225+
value_free(&value);
1226+
1227+
EXPECT_CALL(m_engineMock, keyPressed("m")).WillOnce(Return(false));
1228+
value = thread.runReporter();
1229+
ASSERT_FALSE(value_toBool(&value));
1230+
value_free(&value);
1231+
}

0 commit comments

Comments
 (0)