Skip to content

Commit 8a1cc32

Browse files
committed
Thread: Add hat predicate support
1 parent a30bce3 commit 8a1cc32

File tree

4 files changed

+44
-0
lines changed

4 files changed

+44
-0
lines changed

include/scratchcpp/thread.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class LIBSCRATCHCPP_EXPORT Thread
2727
Script *script() const;
2828

2929
void run();
30+
bool runPredicate();
3031
void kill();
3132
void reset();
3233

src/engine/thread.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@ Thread::Thread(Target *target, IEngine *engine, Script *script) :
1818

1919
if (impl->script) {
2020
impl->code = impl->script->code();
21+
impl->hatPredicateCode = impl->script->hatPredicateCode();
2122

2223
if (impl->code)
2324
impl->executionContext = impl->code->createExecutionContext(this);
25+
26+
if (impl->hatPredicateCode)
27+
impl->hatPredicateExecutionContext = impl->hatPredicateCode->createExecutionContext(this);
2428
}
2529
}
2630

@@ -56,6 +60,18 @@ void Thread::run()
5660
string_pool_set_thread(nullptr);
5761
}
5862

63+
/*! Runs the hat predicate and returns its return value. */
64+
bool Thread::runPredicate()
65+
{
66+
if (!impl->hatPredicateCode)
67+
return false;
68+
69+
string_pool_set_thread(this);
70+
const bool ret = impl->hatPredicateCode->runPredicate(impl->hatPredicateExecutionContext.get());
71+
string_pool_set_thread(nullptr);
72+
return ret;
73+
}
74+
5975
/*! Stops the script. */
6076
void Thread::kill()
6177
{

src/engine/thread_p.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ struct ThreadPrivate
2121
IEngine *engine = nullptr;
2222
Script *script = nullptr;
2323
ExecutableCode *code = nullptr;
24+
ExecutableCode *hatPredicateCode = nullptr;
2425
std::shared_ptr<ExecutionContext> executionContext;
26+
std::shared_ptr<ExecutionContext> hatPredicateExecutionContext;
2527
};
2628

2729
} // namespace libscratchcpp

test/thread/thread_test.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,31 @@ TEST_F(ThreadTest, Run)
5050
m_thread->run();
5151
}
5252

53+
TEST_F(ThreadTest, RunPredicate)
54+
{
55+
ASSERT_FALSE(m_thread->runPredicate());
56+
57+
auto predicateCode = std::make_shared<ExecutableCodeMock>();
58+
std::shared_ptr<ExecutionContext> predicateCtx;
59+
m_script->setHatPredicateCode(predicateCode);
60+
EXPECT_CALL(*m_code, createExecutionContext(_)).WillOnce(Invoke([this](Thread *thread) {
61+
m_ctx = std::make_shared<ExecutionContext>(thread);
62+
return m_ctx;
63+
}));
64+
EXPECT_CALL(*predicateCode, createExecutionContext(_)).WillOnce(Invoke([&predicateCtx](Thread *thread) {
65+
predicateCtx = std::make_shared<ExecutionContext>(thread);
66+
return predicateCtx;
67+
}));
68+
69+
Thread thread(&m_target, &m_engine, m_script.get());
70+
71+
EXPECT_CALL(*predicateCode, runPredicate(predicateCtx.get())).WillOnce(Return(false));
72+
ASSERT_FALSE(thread.runPredicate());
73+
74+
EXPECT_CALL(*predicateCode, runPredicate(predicateCtx.get())).WillOnce(Return(true));
75+
ASSERT_TRUE(thread.runPredicate());
76+
}
77+
5378
TEST_F(ThreadTest, Kill)
5479
{
5580
EXPECT_CALL(*m_code, kill(m_ctx.get()));

0 commit comments

Comments
 (0)