Skip to content
Prev Previous commit
Next Next commit
Implement pen_clear block
  • Loading branch information
adazem009 committed Jan 22, 2024
commit 004182775200ec15b5686108a88004a077a93872
24 changes: 24 additions & 0 deletions src/blocks/penblocks.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
// SPDX-License-Identifier: LGPL-3.0-or-later

#include <scratchcpp/compiler.h>
#include <scratchcpp/sprite.h>

#include "penblocks.h"
#include "penlayer.h"
#include "spritemodel.h"

using namespace scratchcpprender;
using namespace libscratchcpp;
Expand All @@ -12,4 +17,23 @@ std::string PenBlocks::name() const

void PenBlocks::registerBlocks(IEngine *engine)
{
// Blocks
engine->addCompileFunction(this, "pen_clear", &compileClear);
}

void PenBlocks::compileClear(Compiler *compiler)
{
compiler->addFunctionCall(&clear);
}

unsigned int PenBlocks::clear(VirtualMachine *vm)
{
IPenLayer *penLayer = PenLayer::getProjectPenLayer(vm->engine());

if (penLayer) {
penLayer->clear();
vm->engine()->requestRedraw();
}

return 0;
}
4 changes: 4 additions & 0 deletions src/blocks/penblocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ class PenBlocks : public libscratchcpp::IBlockSection
std::string name() const override;

void registerBlocks(libscratchcpp::IEngine *engine) override;

static void compileClear(libscratchcpp::Compiler *compiler);

static unsigned int clear(libscratchcpp::VirtualMachine *vm);
};

} // namespace scratchcpprender
44 changes: 44 additions & 0 deletions test/blocks/pen_blocks_test.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
#include <scratchcpp/compiler.h>
#include <scratchcpp/block.h>
#include <scratchcpp/input.h>
#include <penlayer.h>
#include <blocks/penblocks.h>
#include <enginemock.h>
#include <penlayermock.h>

#include "../common.h"

using namespace scratchcpprender;
using namespace libscratchcpp;

using ::testing::Return;

class PenBlocksTest : public testing::Test
{
public:
Expand Down Expand Up @@ -38,5 +42,45 @@ TEST_F(PenBlocksTest, CategoryVisible)

TEST_F(PenBlocksTest, RegisterBlocks)
{
// Blocks
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "pen_clear", &PenBlocks::compileClear));

m_section->registerBlocks(&m_engineMock);
}

TEST_F(PenBlocksTest, Clear)
{
Compiler compiler(&m_engineMock);

auto block = std::make_shared<Block>("a", "pen_clear");

EXPECT_CALL(m_engineMock, functionIndex(&PenBlocks::clear)).WillOnce(Return(2));
compiler.init();
compiler.setBlock(block);
PenBlocks::compileClear(&compiler);
compiler.end();

ASSERT_EQ(compiler.bytecode(), std::vector<unsigned int>({ vm::OP_START, vm::OP_EXEC, 2, vm::OP_HALT }));
ASSERT_TRUE(compiler.constValues().empty());
ASSERT_TRUE(compiler.variables().empty());
ASSERT_TRUE(compiler.lists().empty());
}

TEST_F(PenBlocksTest, ClearImpl)
{
static unsigned int bytecode[] = { vm::OP_START, vm::OP_EXEC, 0, vm::OP_HALT };
static BlockFunc functions[] = { &PenBlocks::clear };

PenLayerMock penLayer;
PenLayer::addPenLayer(&m_engineMock, &penLayer);

VirtualMachine vm(nullptr, &m_engineMock, nullptr);
vm.setBytecode(bytecode);
vm.setFunctions(functions);

EXPECT_CALL(penLayer, clear());
EXPECT_CALL(m_engineMock, requestRedraw());
vm.run();

ASSERT_EQ(vm.registerCount(), 0);
}