Skip to content

Commit 52855ea

Browse files
committed
Implement pen_stamp block
1 parent 98b0ead commit 52855ea

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

src/blocks/penblocks.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
#include <scratchcpp/iengine.h>
22
#include <scratchcpp/compiler.h>
33
#include <scratchcpp/executioncontext.h>
4+
#include <scratchcpp/target.h>
5+
#include <scratchcpp/ispritehandler.h>
6+
#include <scratchcpp/istagehandler.h>
47

58
#include "penblocks.h"
69
#include "penlayer.h"
10+
#include "spritemodel.h"
11+
#include "stagemodel.h"
712

813
using namespace scratchcpprender;
914
using namespace libscratchcpp;
@@ -26,6 +31,7 @@ Rgb PenBlocks::color() const
2631
void PenBlocks::registerBlocks(IEngine *engine)
2732
{
2833
engine->addCompileFunction(this, "pen_clear", &compileClear);
34+
engine->addCompileFunction(this, "pen_stamp", &compileStamp);
2935
}
3036

3137
CompilerValue *PenBlocks::compileClear(Compiler *compiler)
@@ -34,6 +40,12 @@ CompilerValue *PenBlocks::compileClear(Compiler *compiler)
3440
return nullptr;
3541
}
3642

43+
CompilerValue *PenBlocks::compileStamp(Compiler *compiler)
44+
{
45+
compiler->addTargetFunctionCall("pen_stamp");
46+
return nullptr;
47+
}
48+
3749
BLOCK_EXPORT void pen_clear(ExecutionContext *ctx)
3850
{
3951
IEngine *engine = ctx->engine();
@@ -44,3 +56,24 @@ BLOCK_EXPORT void pen_clear(ExecutionContext *ctx)
4456
engine->requestRedraw();
4557
}
4658
}
59+
60+
BLOCK_EXPORT void pen_stamp(Target *target)
61+
{
62+
IEngine *engine = target->engine();
63+
IPenLayer *penLayer = PenLayer::getProjectPenLayer(engine);
64+
65+
if (penLayer) {
66+
IRenderedTarget *renderedTarget = nullptr;
67+
68+
if (target->isStage()) {
69+
IStageHandler *iface = static_cast<Stage *>(target)->getInterface();
70+
renderedTarget = static_cast<StageModel *>(iface)->renderedTarget();
71+
} else {
72+
ISpriteHandler *iface = static_cast<Sprite *>(target)->getInterface();
73+
renderedTarget = static_cast<SpriteModel *>(iface)->renderedTarget();
74+
}
75+
76+
penLayer->stamp(renderedTarget);
77+
engine->requestRedraw();
78+
}
79+
}

src/blocks/penblocks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class PenBlocks : public libscratchcpp::IExtension
1414

1515
private:
1616
static libscratchcpp::CompilerValue *compileClear(libscratchcpp::Compiler *compiler);
17+
static libscratchcpp::CompilerValue *compileStamp(libscratchcpp::Compiler *compiler);
1718
};
1819

1920
} // namespace scratchcpprender

test/blocks/pen_blocks_test.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <scratchcpp/project.h>
22
#include <scratchcpp/sprite.h>
3+
#include <scratchcpp/stage.h>
34
#include <scratchcpp/compiler.h>
45
#include <scratchcpp/script.h>
56
#include <scratchcpp/thread.h>
@@ -9,6 +10,9 @@
910
#include <gtest/gtest.h>
1011

1112
#include "penlayer.h"
13+
#include "spritemodel.h"
14+
#include "stagemodel.h"
15+
#include "renderedtarget.h"
1216
#include "blocks/penblocks.h"
1317

1418
using namespace scratchcpprender;
@@ -70,3 +74,45 @@ TEST_F(PenBlocksTest, Clear)
7074
EXPECT_CALL(m_engineMock, requestRedraw());
7175
thread->run();
7276
}
77+
78+
TEST_F(PenBlocksTest, Stamp_Sprite)
79+
{
80+
auto sprite = std::make_shared<Sprite>();
81+
sprite->setEngine(&m_engineMock);
82+
83+
RenderedTarget renderedTarget;
84+
SpriteModel model;
85+
model.init(sprite.get());
86+
model.setRenderedTarget(&renderedTarget);
87+
sprite->setInterface(&model);
88+
89+
ScriptBuilder builder(m_extension.get(), m_engine, sprite);
90+
builder.addBlock("pen_stamp");
91+
92+
auto thread = buildScript(builder, sprite.get());
93+
94+
EXPECT_CALL(m_penLayer, stamp(&renderedTarget));
95+
EXPECT_CALL(m_engineMock, requestRedraw());
96+
thread->run();
97+
}
98+
99+
TEST_F(PenBlocksTest, Stamp_Stage)
100+
{
101+
auto stage = std::make_shared<Stage>();
102+
stage->setEngine(&m_engineMock);
103+
104+
RenderedTarget renderedTarget;
105+
StageModel model;
106+
model.init(stage.get());
107+
model.setRenderedTarget(&renderedTarget);
108+
stage->setInterface(&model);
109+
110+
ScriptBuilder builder(m_extension.get(), m_engine, stage);
111+
builder.addBlock("pen_stamp");
112+
113+
auto thread = buildScript(builder, stage.get());
114+
115+
EXPECT_CALL(m_penLayer, stamp(&renderedTarget));
116+
EXPECT_CALL(m_engineMock, requestRedraw());
117+
thread->run();
118+
}

0 commit comments

Comments
 (0)