Skip to content

Commit 08b233f

Browse files
committed
Implement data_replaceitemoflist
1 parent fbc2643 commit 08b233f

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

src/dev/blocks/listblocks.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ void ListBlocks::registerBlocks(IEngine *engine)
2626
engine->addCompileFunction(this, "data_deleteoflist", &compileDeleteOfList);
2727
engine->addCompileFunction(this, "data_deletealloflist", &compileDeleteAllOfList);
2828
engine->addCompileFunction(this, "data_insertatlist", &compileInsertAtList);
29+
engine->addCompileFunction(this, "data_replaceitemoflist", &compileReplaceItemOfList);
2930
}
3031

3132
CompilerValue *ListBlocks::compileAddToList(Compiler *compiler)
@@ -126,3 +127,26 @@ CompilerValue *ListBlocks::compileInsertAtList(Compiler *compiler)
126127

127128
return nullptr;
128129
}
130+
131+
CompilerValue *ListBlocks::compileReplaceItemOfList(Compiler *compiler)
132+
{
133+
List *list = static_cast<List *>(compiler->field("LIST")->valuePtr().get());
134+
assert(list);
135+
136+
if (list) {
137+
CompilerValue *index = compiler->addInput("INDEX");
138+
CompilerValue *min = compiler->addConstValue(-1);
139+
CompilerValue *max = compiler->addListSize(list);
140+
index = getListIndex(compiler, index, list, max);
141+
index = compiler->createSub(index, compiler->addConstValue(1));
142+
CompilerValue *cond = compiler->createAnd(compiler->createCmpGT(index, min), compiler->createCmpLT(index, max));
143+
compiler->beginIfStatement(cond);
144+
{
145+
CompilerValue *item = compiler->addInput("ITEM");
146+
compiler->createListReplace(list, index, item);
147+
}
148+
compiler->endIf();
149+
}
150+
151+
return nullptr;
152+
}

src/dev/blocks/listblocks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class ListBlocks : public IExtension
2323
static CompilerValue *compileDeleteOfList(Compiler *compiler);
2424
static CompilerValue *compileDeleteAllOfList(Compiler *compiler);
2525
static CompilerValue *compileInsertAtList(Compiler *compiler);
26+
static CompilerValue *compileReplaceItemOfList(Compiler *compiler);
2627
};
2728

2829
} // namespace libscratchcpp

test/dev/blocks/list_blocks_test.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,59 @@ TEST_F(ListBlocksTest, InsertAtList)
211211
ASSERT_EQ(list1->toString(), "Lorem ipsum dolor sit 123 true false");
212212
ASSERT_EQ(list2->toString(), "Hello world dolor false -543.5 abc 52.4 lorem ipsum");
213213
}
214+
215+
TEST_F(ListBlocksTest, ReplaceItemOfList)
216+
{
217+
auto target = std::make_shared<Sprite>();
218+
219+
auto list1 = std::make_shared<List>("", "");
220+
list1->append("Lorem");
221+
list1->append("ipsum");
222+
list1->append("dolor");
223+
list1->append(123);
224+
list1->append(true);
225+
target->addList(list1);
226+
227+
auto list2 = std::make_shared<List>("", "");
228+
list2->append("Hello");
229+
list2->append("world");
230+
list2->append(false);
231+
list2->append(-543.5);
232+
list2->append("abc");
233+
list2->append(52.4);
234+
target->addList(list2);
235+
236+
ScriptBuilder builder(m_extension.get(), m_engine, target);
237+
238+
auto addTest = [&builder](const Value &index, const Value &item, std::shared_ptr<List> list) {
239+
builder.addBlock("data_replaceitemoflist");
240+
builder.addValueInput("INDEX", index);
241+
builder.addEntityField("LIST", list);
242+
builder.addValueInput("ITEM", item);
243+
return builder.currentBlock();
244+
};
245+
246+
auto block = addTest(4, "sit", list1);
247+
addTest(5, -53.18, list1);
248+
addTest(0, "test", list1);
249+
addTest(6, "test", list1);
250+
251+
addTest("last", "lorem", list2);
252+
addTest("random", "ipsum", list2);
253+
addTest("any", "dolor", list2);
254+
255+
builder.build();
256+
257+
Compiler compiler(&m_engineMock, target.get());
258+
auto code = compiler.compile(block);
259+
Script script(target.get(), block, &m_engineMock);
260+
script.setCode(code);
261+
Thread thread(target.get(), &m_engineMock, &script);
262+
auto ctx = code->createExecutionContext(&thread);
263+
ctx->setRng(&m_rng);
264+
265+
EXPECT_CALL(m_rng, randint(1, 6)).WillOnce(Return(4)).WillOnce(Return(1));
266+
code->run(ctx.get());
267+
ASSERT_EQ(list1->toString(), "Lorem ipsum dolor sit -53.18");
268+
ASSERT_EQ(list2->toString(), "dolor world false ipsum abc lorem");
269+
}

0 commit comments

Comments
 (0)