Skip to content

Commit 2787701

Browse files
committed
Call "when key pressed" scripts when keys are pressed
1 parent 22106d7 commit 2787701

File tree

4 files changed

+223
-0
lines changed

4 files changed

+223
-0
lines changed

src/engine/internal/engine.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -426,11 +426,32 @@ void Engine::setKeyState(const std::string &name, bool pressed)
426426
{
427427
KeyEvent event(name);
428428
m_keyMap[event.name()] = pressed;
429+
430+
// Start "when key pressed" scripts
431+
if (pressed) {
432+
auto it = m_whenKeyPressedScripts.find(event.name());
433+
434+
if (it != m_whenKeyPressedScripts.cend())
435+
startWhenKeyPressedScripts(it->second);
436+
437+
it = m_whenKeyPressedScripts.find("any");
438+
439+
if (it != m_whenKeyPressedScripts.cend())
440+
startWhenKeyPressedScripts(it->second);
441+
}
429442
}
430443

431444
void Engine::setAnyKeyPressed(bool pressed)
432445
{
433446
m_anyKeyPressed = pressed;
447+
448+
// Start "when key pressed" scripts
449+
if (pressed) {
450+
auto it = m_whenKeyPressedScripts.find("any");
451+
452+
if (it != m_whenKeyPressedScripts.cend())
453+
startWhenKeyPressedScripts(it->second);
454+
}
434455
}
435456

436457
double Engine::mouseX() const
@@ -948,3 +969,19 @@ void Engine::updateFrameDuration()
948969
{
949970
m_frameDuration = std::chrono::milliseconds(static_cast<long>(1000 / m_fps));
950971
}
972+
973+
void Engine::startWhenKeyPressedScripts(const std::vector<Script *> &scripts)
974+
{
975+
for (auto script : scripts) {
976+
std::shared_ptr<Block> block = nullptr;
977+
978+
for (const auto &[b, s] : m_scripts) {
979+
if (s.get() == script)
980+
block = b;
981+
}
982+
983+
assert(block);
984+
assert(std::find_if(m_targets.begin(), m_targets.end(), [script](std::shared_ptr<Target> target) { return script->target() == target.get(); }) != m_targets.end());
985+
startScript(block, *std::find_if(m_targets.begin(), m_targets.end(), [script](std::shared_ptr<Target> target) { return script->target() == target.get(); }));
986+
}
987+
}

src/engine/internal/engine.h

+1
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ class Engine : public IEngine
130130
std::shared_ptr<IBlockSection> blockSection(const std::string &opcode) const;
131131

132132
void updateFrameDuration();
133+
void startWhenKeyPressedScripts(const std::vector<Script *> &scripts);
133134

134135
std::unordered_map<std::shared_ptr<IBlockSection>, std::unique_ptr<BlockSectionContainer>> m_sections;
135136
std::vector<std::shared_ptr<Target>> m_targets;

test/engine/engine_test.cpp

+185
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,191 @@ TEST(EngineTest, KeyState)
179179
ASSERT_FALSE(engine.keyPressed("any"));
180180
}
181181

182+
TEST(EngineTest, WhenKeyPressed)
183+
{
184+
Project p("when_key_pressed.sb3");
185+
ASSERT_TRUE(p.load());
186+
187+
p.run();
188+
189+
auto engine = p.engine();
190+
191+
Stage *stage = engine->stage();
192+
ASSERT_TRUE(stage);
193+
194+
// no pressed key
195+
ASSERT_VAR(stage, "space_pressed");
196+
ASSERT_EQ(GET_VAR(stage, "space_pressed")->value().toInt(), 0);
197+
ASSERT_VAR(stage, "right_arrow_pressed");
198+
ASSERT_EQ(GET_VAR(stage, "right_arrow_pressed")->value().toInt(), 0);
199+
ASSERT_VAR(stage, "any_key_pressed");
200+
ASSERT_EQ(GET_VAR(stage, "any_key_pressed")->value().toInt(), 0);
201+
ASSERT_VAR(stage, "a_pressed");
202+
ASSERT_EQ(GET_VAR(stage, "a_pressed")->value().toInt(), 0);
203+
ASSERT_VAR(stage, "x_pressed");
204+
ASSERT_EQ(GET_VAR(stage, "x_pressed")->value().toInt(), 0);
205+
ASSERT_VAR(stage, "4_pressed");
206+
ASSERT_EQ(GET_VAR(stage, "4_pressed")->value().toInt(), 0);
207+
208+
// space
209+
engine->setKeyState("space", true);
210+
p.run();
211+
212+
ASSERT_VAR(stage, "space_pressed");
213+
ASSERT_EQ(GET_VAR(stage, "space_pressed")->value().toInt(), 1);
214+
engine->setKeyState("space", false);
215+
p.run();
216+
217+
ASSERT_VAR(stage, "space_pressed");
218+
ASSERT_EQ(GET_VAR(stage, "space_pressed")->value().toInt(), 1);
219+
ASSERT_VAR(stage, "right_arrow_pressed");
220+
ASSERT_EQ(GET_VAR(stage, "right_arrow_pressed")->value().toInt(), 0);
221+
ASSERT_VAR(stage, "any_key_pressed");
222+
ASSERT_EQ(GET_VAR(stage, "any_key_pressed")->value().toInt(), 1);
223+
ASSERT_VAR(stage, "a_pressed");
224+
ASSERT_EQ(GET_VAR(stage, "a_pressed")->value().toInt(), 0);
225+
ASSERT_VAR(stage, "x_pressed");
226+
ASSERT_EQ(GET_VAR(stage, "x_pressed")->value().toInt(), 0);
227+
ASSERT_VAR(stage, "4_pressed");
228+
ASSERT_EQ(GET_VAR(stage, "4_pressed")->value().toInt(), 0);
229+
230+
// right arrow
231+
engine->setKeyState("right arrow", true);
232+
p.run();
233+
234+
ASSERT_VAR(stage, "right_arrow_pressed");
235+
ASSERT_EQ(GET_VAR(stage, "right_arrow_pressed")->value().toInt(), 1);
236+
engine->setKeyState("right arrow", false);
237+
p.run();
238+
239+
ASSERT_VAR(stage, "space_pressed");
240+
ASSERT_EQ(GET_VAR(stage, "space_pressed")->value().toInt(), 1);
241+
ASSERT_VAR(stage, "right_arrow_pressed");
242+
ASSERT_EQ(GET_VAR(stage, "right_arrow_pressed")->value().toInt(), 1);
243+
ASSERT_VAR(stage, "any_key_pressed");
244+
ASSERT_EQ(GET_VAR(stage, "any_key_pressed")->value().toInt(), 2);
245+
ASSERT_VAR(stage, "a_pressed");
246+
ASSERT_EQ(GET_VAR(stage, "a_pressed")->value().toInt(), 0);
247+
ASSERT_VAR(stage, "x_pressed");
248+
ASSERT_EQ(GET_VAR(stage, "x_pressed")->value().toInt(), 0);
249+
ASSERT_VAR(stage, "4_pressed");
250+
ASSERT_EQ(GET_VAR(stage, "4_pressed")->value().toInt(), 0);
251+
252+
// any key
253+
engine->setAnyKeyPressed(true);
254+
p.run();
255+
256+
ASSERT_VAR(stage, "any_key_pressed");
257+
ASSERT_EQ(GET_VAR(stage, "any_key_pressed")->value().toInt(), 3);
258+
engine->setAnyKeyPressed(false);
259+
p.run();
260+
261+
ASSERT_VAR(stage, "space_pressed");
262+
ASSERT_EQ(GET_VAR(stage, "space_pressed")->value().toInt(), 1);
263+
ASSERT_VAR(stage, "right_arrow_pressed");
264+
ASSERT_EQ(GET_VAR(stage, "right_arrow_pressed")->value().toInt(), 1);
265+
ASSERT_VAR(stage, "any_key_pressed");
266+
ASSERT_EQ(GET_VAR(stage, "any_key_pressed")->value().toInt(), 3);
267+
ASSERT_VAR(stage, "a_pressed");
268+
ASSERT_EQ(GET_VAR(stage, "a_pressed")->value().toInt(), 0);
269+
ASSERT_VAR(stage, "x_pressed");
270+
ASSERT_EQ(GET_VAR(stage, "x_pressed")->value().toInt(), 0);
271+
ASSERT_VAR(stage, "4_pressed");
272+
ASSERT_EQ(GET_VAR(stage, "4_pressed")->value().toInt(), 0);
273+
274+
// a
275+
engine->setKeyState("a", true);
276+
p.run();
277+
278+
ASSERT_VAR(stage, "a_pressed");
279+
ASSERT_EQ(GET_VAR(stage, "a_pressed")->value().toInt(), 1);
280+
engine->setKeyState("a", false);
281+
p.run();
282+
283+
ASSERT_VAR(stage, "space_pressed");
284+
ASSERT_EQ(GET_VAR(stage, "space_pressed")->value().toInt(), 1);
285+
ASSERT_VAR(stage, "right_arrow_pressed");
286+
ASSERT_EQ(GET_VAR(stage, "right_arrow_pressed")->value().toInt(), 1);
287+
ASSERT_VAR(stage, "any_key_pressed");
288+
ASSERT_EQ(GET_VAR(stage, "any_key_pressed")->value().toInt(), 4);
289+
ASSERT_VAR(stage, "a_pressed");
290+
ASSERT_EQ(GET_VAR(stage, "a_pressed")->value().toInt(), 1);
291+
ASSERT_VAR(stage, "x_pressed");
292+
ASSERT_EQ(GET_VAR(stage, "x_pressed")->value().toInt(), 0);
293+
ASSERT_VAR(stage, "4_pressed");
294+
ASSERT_EQ(GET_VAR(stage, "4_pressed")->value().toInt(), 0);
295+
296+
// x
297+
engine->setKeyState("x", true);
298+
p.run();
299+
300+
ASSERT_VAR(stage, "x_pressed");
301+
ASSERT_EQ(GET_VAR(stage, "x_pressed")->value().toInt(), 1);
302+
engine->setKeyState("x", false);
303+
p.run();
304+
305+
ASSERT_VAR(stage, "space_pressed");
306+
ASSERT_EQ(GET_VAR(stage, "space_pressed")->value().toInt(), 1);
307+
ASSERT_VAR(stage, "right_arrow_pressed");
308+
ASSERT_EQ(GET_VAR(stage, "right_arrow_pressed")->value().toInt(), 1);
309+
ASSERT_VAR(stage, "any_key_pressed");
310+
ASSERT_EQ(GET_VAR(stage, "any_key_pressed")->value().toInt(), 5);
311+
ASSERT_VAR(stage, "a_pressed");
312+
ASSERT_EQ(GET_VAR(stage, "a_pressed")->value().toInt(), 1);
313+
ASSERT_VAR(stage, "x_pressed");
314+
ASSERT_EQ(GET_VAR(stage, "x_pressed")->value().toInt(), 1);
315+
ASSERT_VAR(stage, "4_pressed");
316+
ASSERT_EQ(GET_VAR(stage, "4_pressed")->value().toInt(), 0);
317+
318+
// 4
319+
engine->setKeyState("4", true);
320+
p.run();
321+
322+
ASSERT_VAR(stage, "4_pressed");
323+
ASSERT_EQ(GET_VAR(stage, "4_pressed")->value().toInt(), 1);
324+
engine->setKeyState("4", false);
325+
p.run();
326+
327+
ASSERT_VAR(stage, "space_pressed");
328+
ASSERT_EQ(GET_VAR(stage, "space_pressed")->value().toInt(), 1);
329+
ASSERT_VAR(stage, "right_arrow_pressed");
330+
ASSERT_EQ(GET_VAR(stage, "right_arrow_pressed")->value().toInt(), 1);
331+
ASSERT_VAR(stage, "any_key_pressed");
332+
ASSERT_EQ(GET_VAR(stage, "any_key_pressed")->value().toInt(), 6);
333+
ASSERT_VAR(stage, "a_pressed");
334+
ASSERT_EQ(GET_VAR(stage, "a_pressed")->value().toInt(), 1);
335+
ASSERT_VAR(stage, "x_pressed");
336+
ASSERT_EQ(GET_VAR(stage, "x_pressed")->value().toInt(), 1);
337+
ASSERT_VAR(stage, "4_pressed");
338+
ASSERT_EQ(GET_VAR(stage, "4_pressed")->value().toInt(), 1);
339+
340+
// multiple
341+
engine->setKeyState("space", true);
342+
engine->setKeyState("x", true);
343+
p.run();
344+
345+
ASSERT_VAR(stage, "space_pressed");
346+
ASSERT_EQ(GET_VAR(stage, "space_pressed")->value().toInt(), 2);
347+
ASSERT_VAR(stage, "x_pressed");
348+
ASSERT_EQ(GET_VAR(stage, "x_pressed")->value().toInt(), 2);
349+
engine->setKeyState("space", false);
350+
engine->setKeyState("x", false);
351+
p.run();
352+
353+
ASSERT_VAR(stage, "space_pressed");
354+
ASSERT_EQ(GET_VAR(stage, "space_pressed")->value().toInt(), 2);
355+
ASSERT_VAR(stage, "right_arrow_pressed");
356+
ASSERT_EQ(GET_VAR(stage, "right_arrow_pressed")->value().toInt(), 1);
357+
ASSERT_VAR(stage, "any_key_pressed");
358+
ASSERT_EQ(GET_VAR(stage, "any_key_pressed")->value().toInt(), 8);
359+
ASSERT_VAR(stage, "a_pressed");
360+
ASSERT_EQ(GET_VAR(stage, "a_pressed")->value().toInt(), 1);
361+
ASSERT_VAR(stage, "x_pressed");
362+
ASSERT_EQ(GET_VAR(stage, "x_pressed")->value().toInt(), 2);
363+
ASSERT_VAR(stage, "4_pressed");
364+
ASSERT_EQ(GET_VAR(stage, "4_pressed")->value().toInt(), 1);
365+
}
366+
182367
TEST(EngineTest, MouseX)
183368
{
184369
Engine engine;

test/when_key_pressed.sb3

1.43 KB
Binary file not shown.

0 commit comments

Comments
 (0)