Skip to content

Commit ba5604c

Browse files
committed
Implement looks_thinkforsecs block
1 parent d25e968 commit ba5604c

File tree

3 files changed

+126
-103
lines changed

3 files changed

+126
-103
lines changed

src/blocks/looksblocks.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ void LooksBlocks::registerBlocks(IEngine *engine)
3434
{
3535
engine->addCompileFunction(this, "looks_sayforsecs", &compileSayForSecs);
3636
engine->addCompileFunction(this, "looks_say", &compileSay);
37+
engine->addCompileFunction(this, "looks_thinkforsecs", &compileThinkForSecs);
3738
}
3839

3940
void LooksBlocks::onInit(IEngine *engine)
@@ -90,6 +91,12 @@ CompilerValue *LooksBlocks::compileSay(Compiler *compiler)
9091
return nullptr;
9192
}
9293

94+
CompilerValue *LooksBlocks::compileThinkForSecs(Compiler *compiler)
95+
{
96+
compileSayOrThinkForSecs(compiler, "looks_think");
97+
return nullptr;
98+
}
99+
93100
extern "C" void looks_start_stack_timer(ExecutionContext *ctx, double duration)
94101
{
95102
ctx->stackTimer()->start(duration);
@@ -128,3 +135,8 @@ extern "C" void looks_say(ExecutionContext *ctx, const StringPtr *message, bool
128135
{
129136
looks_show_bubble(ctx->thread(), TextBubble::Type::Say, message, saveThread);
130137
}
138+
139+
extern "C" void looks_think(ExecutionContext *ctx, const StringPtr *message, bool saveThread)
140+
{
141+
looks_show_bubble(ctx->thread(), TextBubble::Type::Think, message, saveThread);
142+
}

src/blocks/looksblocks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class LooksBlocks : public IExtension
2626
static void compileSayOrThinkForSecs(Compiler *compiler, const std::string function);
2727
static CompilerValue *compileSayForSecs(Compiler *compiler);
2828
static CompilerValue *compileSay(Compiler *compiler);
29+
static CompilerValue *compileThinkForSecs(Compiler *compiler);
2930
};
3031

3132
} // namespace libscratchcpp

test/blocks/looks_blocks_test.cpp

Lines changed: 113 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -57,110 +57,120 @@ TEST_F(LooksBlocksTest, StopProject)
5757
ASSERT_EQ(sprite->graphicsEffectValue(&effect), 0);
5858
}
5959

60-
TEST_F(LooksBlocksTest, SayForSecs)
60+
TEST_F(LooksBlocksTest, SayAndThinkForSecs)
6161
{
62-
auto sprite = std::make_shared<Sprite>();
63-
sprite->setEngine(&m_engineMock);
64-
ScriptBuilder builder(m_extension.get(), m_engine, sprite);
65-
66-
builder.addBlock("looks_sayforsecs");
67-
builder.addValueInput("MESSAGE", "Hello world");
68-
builder.addValueInput("SECS", 2.5);
69-
auto block = builder.currentBlock();
70-
71-
Compiler compiler(&m_engineMock, sprite.get());
72-
auto code = compiler.compile(block);
73-
Script script(sprite.get(), block, &m_engineMock);
74-
script.setCode(code);
75-
Thread thread(sprite.get(), &m_engineMock, &script);
76-
auto ctx = code->createExecutionContext(&thread);
77-
StackTimerMock timer;
78-
ctx->setStackTimer(&timer);
79-
80-
EXPECT_CALL(timer, start(2.5));
81-
EXPECT_CALL(m_engineMock, requestRedraw());
82-
code->run(ctx.get());
83-
ASSERT_FALSE(code->isFinished(ctx.get()));
84-
ASSERT_EQ(sprite->bubble()->text(), "Hello world");
85-
ASSERT_EQ(sprite->bubble()->type(), TextBubble::Type::Say);
86-
87-
EXPECT_CALL(timer, elapsed()).WillOnce(Return(false));
88-
EXPECT_CALL(m_engineMock, requestRedraw).Times(0);
89-
code->run(ctx.get());
90-
ASSERT_FALSE(code->isFinished(ctx.get()));
91-
ASSERT_EQ(sprite->bubble()->text(), "Hello world");
92-
ASSERT_EQ(sprite->bubble()->type(), TextBubble::Type::Say);
93-
94-
EXPECT_CALL(timer, elapsed()).WillOnce(Return(true));
95-
EXPECT_CALL(m_engineMock, requestRedraw).Times(0);
96-
code->run(ctx.get());
97-
ASSERT_TRUE(code->isFinished(ctx.get()));
98-
ASSERT_TRUE(sprite->bubble()->text().empty());
99-
100-
// Change text while waiting
101-
code->reset(ctx.get());
102-
103-
EXPECT_CALL(timer, start(2.5));
104-
EXPECT_CALL(m_engineMock, requestRedraw());
105-
code->run(ctx.get());
106-
ASSERT_FALSE(code->isFinished(ctx.get()));
107-
108-
EXPECT_CALL(m_engineMock, requestRedraw());
109-
sprite->bubble()->setText("test");
110-
111-
EXPECT_CALL(timer, elapsed()).WillOnce(Return(true));
112-
EXPECT_CALL(m_engineMock, requestRedraw).Times(0);
113-
code->run(ctx.get());
114-
ASSERT_TRUE(code->isFinished(ctx.get()));
115-
ASSERT_EQ(sprite->bubble()->text(), "test");
116-
ASSERT_EQ(sprite->bubble()->type(), TextBubble::Type::Say);
117-
118-
code->reset(ctx.get());
119-
120-
EXPECT_CALL(timer, start(2.5));
121-
EXPECT_CALL(m_engineMock, requestRedraw());
122-
code->run(ctx.get());
123-
ASSERT_FALSE(code->isFinished(ctx.get()));
124-
125-
EXPECT_CALL(m_engineMock, requestRedraw());
126-
sprite->bubble()->setText("Hello world");
127-
128-
EXPECT_CALL(timer, elapsed()).WillOnce(Return(true));
129-
EXPECT_CALL(m_engineMock, requestRedraw).Times(0);
130-
code->run(ctx.get());
131-
ASSERT_TRUE(code->isFinished(ctx.get()));
132-
ASSERT_EQ(sprite->bubble()->text(), "Hello world");
133-
ASSERT_EQ(sprite->bubble()->type(), TextBubble::Type::Say);
134-
135-
// Kill waiting thread
136-
code->reset(ctx.get());
137-
138-
EXPECT_CALL(timer, start(2.5));
139-
EXPECT_CALL(m_engineMock, requestRedraw());
140-
code->run(ctx.get());
141-
ASSERT_FALSE(code->isFinished(ctx.get()));
142-
143-
m_engine->threadAboutToStop()(&thread);
144-
code->kill(ctx.get());
145-
ASSERT_EQ(sprite->bubble()->owner(), nullptr);
146-
ASSERT_TRUE(sprite->bubble()->text().empty());
147-
148-
// Kill waiting thread after changing text
149-
code->reset(ctx.get());
150-
151-
EXPECT_CALL(timer, start(2.5));
152-
EXPECT_CALL(m_engineMock, requestRedraw());
153-
code->run(ctx.get());
154-
ASSERT_FALSE(code->isFinished(ctx.get()));
155-
156-
EXPECT_CALL(m_engineMock, requestRedraw());
157-
sprite->bubble()->setText("test");
158-
159-
m_engine->threadAboutToStop()(&thread);
160-
code->kill(ctx.get());
161-
ASSERT_EQ(sprite->bubble()->owner(), nullptr);
162-
ASSERT_EQ(sprite->bubble()->text(), "test");
163-
ASSERT_EQ(sprite->bubble()->type(), TextBubble::Type::Say);
62+
std::vector<TextBubble::Type> types = { TextBubble::Type::Say, TextBubble::Type::Think };
63+
std::vector<std::string> opcodes = { "looks_sayforsecs", "looks_thinkforsecs" };
64+
65+
for (int i = 0; i < types.size(); i++) {
66+
TextBubble::Type type = types[i];
67+
const std::string &opcode = opcodes[i];
68+
69+
auto sprite = std::make_shared<Sprite>();
70+
sprite->setEngine(&m_engineMock);
71+
m_engine->clear();
72+
73+
ScriptBuilder builder(m_extension.get(), m_engine, sprite);
74+
75+
builder.addBlock(opcode);
76+
builder.addValueInput("MESSAGE", "Hello world");
77+
builder.addValueInput("SECS", 2.5);
78+
auto block = builder.currentBlock();
79+
80+
Compiler compiler(&m_engineMock, sprite.get());
81+
auto code = compiler.compile(block);
82+
Script script(sprite.get(), block, &m_engineMock);
83+
script.setCode(code);
84+
Thread thread(sprite.get(), &m_engineMock, &script);
85+
auto ctx = code->createExecutionContext(&thread);
86+
StackTimerMock timer;
87+
ctx->setStackTimer(&timer);
88+
89+
EXPECT_CALL(timer, start(2.5));
90+
EXPECT_CALL(m_engineMock, requestRedraw());
91+
code->run(ctx.get());
92+
ASSERT_FALSE(code->isFinished(ctx.get()));
93+
ASSERT_EQ(sprite->bubble()->text(), "Hello world");
94+
ASSERT_EQ(sprite->bubble()->type(), type);
95+
96+
EXPECT_CALL(timer, elapsed()).WillOnce(Return(false));
97+
EXPECT_CALL(m_engineMock, requestRedraw).Times(0);
98+
code->run(ctx.get());
99+
ASSERT_FALSE(code->isFinished(ctx.get()));
100+
ASSERT_EQ(sprite->bubble()->text(), "Hello world");
101+
ASSERT_EQ(sprite->bubble()->type(), type);
102+
103+
EXPECT_CALL(timer, elapsed()).WillOnce(Return(true));
104+
EXPECT_CALL(m_engineMock, requestRedraw).Times(0);
105+
code->run(ctx.get());
106+
ASSERT_TRUE(code->isFinished(ctx.get()));
107+
ASSERT_TRUE(sprite->bubble()->text().empty());
108+
109+
// Change text while waiting
110+
code->reset(ctx.get());
111+
112+
EXPECT_CALL(timer, start(2.5));
113+
EXPECT_CALL(m_engineMock, requestRedraw());
114+
code->run(ctx.get());
115+
ASSERT_FALSE(code->isFinished(ctx.get()));
116+
117+
EXPECT_CALL(m_engineMock, requestRedraw());
118+
sprite->bubble()->setText("test");
119+
120+
EXPECT_CALL(timer, elapsed()).WillOnce(Return(true));
121+
EXPECT_CALL(m_engineMock, requestRedraw).Times(0);
122+
code->run(ctx.get());
123+
ASSERT_TRUE(code->isFinished(ctx.get()));
124+
ASSERT_EQ(sprite->bubble()->text(), "test");
125+
ASSERT_EQ(sprite->bubble()->type(), type);
126+
127+
code->reset(ctx.get());
128+
129+
EXPECT_CALL(timer, start(2.5));
130+
EXPECT_CALL(m_engineMock, requestRedraw());
131+
code->run(ctx.get());
132+
ASSERT_FALSE(code->isFinished(ctx.get()));
133+
134+
EXPECT_CALL(m_engineMock, requestRedraw());
135+
sprite->bubble()->setText("Hello world");
136+
137+
EXPECT_CALL(timer, elapsed()).WillOnce(Return(true));
138+
EXPECT_CALL(m_engineMock, requestRedraw).Times(0);
139+
code->run(ctx.get());
140+
ASSERT_TRUE(code->isFinished(ctx.get()));
141+
ASSERT_EQ(sprite->bubble()->text(), "Hello world");
142+
ASSERT_EQ(sprite->bubble()->type(), type);
143+
144+
// Kill waiting thread
145+
code->reset(ctx.get());
146+
147+
EXPECT_CALL(timer, start(2.5));
148+
EXPECT_CALL(m_engineMock, requestRedraw());
149+
code->run(ctx.get());
150+
ASSERT_FALSE(code->isFinished(ctx.get()));
151+
152+
m_engine->threadAboutToStop()(&thread);
153+
code->kill(ctx.get());
154+
ASSERT_EQ(sprite->bubble()->owner(), nullptr);
155+
ASSERT_TRUE(sprite->bubble()->text().empty());
156+
157+
// Kill waiting thread after changing text
158+
code->reset(ctx.get());
159+
160+
EXPECT_CALL(timer, start(2.5));
161+
EXPECT_CALL(m_engineMock, requestRedraw());
162+
code->run(ctx.get());
163+
ASSERT_FALSE(code->isFinished(ctx.get()));
164+
165+
EXPECT_CALL(m_engineMock, requestRedraw());
166+
sprite->bubble()->setText("test");
167+
168+
m_engine->threadAboutToStop()(&thread);
169+
code->kill(ctx.get());
170+
ASSERT_EQ(sprite->bubble()->owner(), nullptr);
171+
ASSERT_EQ(sprite->bubble()->text(), "test");
172+
ASSERT_EQ(sprite->bubble()->type(), type);
173+
}
164174
}
165175

166176
TEST_F(LooksBlocksTest, Say)

0 commit comments

Comments
 (0)