From 98d49747ee5cff55cddcc3b588a8829d15876dc0 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sat, 1 Feb 2025 23:55:01 +0100 Subject: [PATCH 1/3] Add TargetModel class --- src/CMakeLists.txt | 2 + src/spritemodel.cpp | 183 ++++++-------------- src/spritemodel.h | 50 +----- src/stagemodel.cpp | 105 ++++-------- src/stagemodel.h | 34 +--- src/targetmodel.cpp | 215 ++++++++++++++++++++++++ src/targetmodel.h | 98 +++++++++++ test/target_models/CMakeLists.txt | 20 +++ test/target_models/spritemodel_test.cpp | 49 +++--- test/target_models/stagemodel_test.cpp | 29 ++-- test/target_models/targetmodel_test.cpp | 49 ++++++ 11 files changed, 514 insertions(+), 320 deletions(-) create mode 100644 src/targetmodel.cpp create mode 100644 src/targetmodel.h create mode 100644 test/target_models/targetmodel_test.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e812296..af50238 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -24,6 +24,8 @@ qt_add_qml_module(scratchcpp-render projectloader.h projectscene.cpp projectscene.h + targetmodel.cpp + targetmodel.h stagemodel.cpp stagemodel.h spritemodel.cpp diff --git a/src/spritemodel.cpp b/src/spritemodel.cpp index 9189d1d..569ea96 100644 --- a/src/spritemodel.cpp +++ b/src/spritemodel.cpp @@ -6,15 +6,12 @@ #include #include "spritemodel.h" -#include "renderedtarget.h" -#include "ipenlayer.h" -#include "graphicseffect.h" +#include "penlayer.h" -namespace scratchcpprender -{ +using namespace scratchcpprender; SpriteModel::SpriteModel(QObject *parent) : - QObject(parent) + TargetModel(parent) { } @@ -22,36 +19,8 @@ void SpriteModel::init(libscratchcpp::Sprite *sprite) { m_sprite = sprite; - if (m_sprite) { - libscratchcpp::TextBubble *bubble = m_sprite->bubble(); - - bubble->typeChanged().connect([this](libscratchcpp::TextBubble::Type type) { - if (type == libscratchcpp::TextBubble::Type::Say) { - if (m_bubbleType == TextBubbleShape::Type::Say) - return; - - m_bubbleType = TextBubbleShape::Type::Say; - } else { - if (m_bubbleType == TextBubbleShape::Type::Think) - return; - - m_bubbleType = TextBubbleShape::Type::Think; - } - - emit bubbleTypeChanged(); - }); - - bubble->textChanged().connect([this](const std::string &text) { - QString newText = QString::fromStdString(text); - - if (m_bubbleText != newText) { - m_bubbleText = newText; - emit bubbleTextChanged(); - } - }); - - bubble->layerOrderChanged().connect([this](int) { emit bubbleLayerChanged(); }); - } + if (m_sprite) + setupTextBubble(m_sprite->bubble()); } void SpriteModel::deinitClone() @@ -66,123 +35,109 @@ void SpriteModel::onCloned(libscratchcpp::Sprite *clone) SpriteModel *cloneModel = new SpriteModel(m_cloneRoot); cloneModel->m_cloneRoot = m_cloneRoot; - cloneModel->m_penLayer = m_penLayer; - cloneModel->m_penState = m_penState; + cloneModel->setPenLayer(penLayer()); + cloneModel->penState() = penState(); clone->setInterface(cloneModel); emit cloned(cloneModel); } void SpriteModel::onCostumeChanged(libscratchcpp::Costume *costume) { - if (m_renderedTarget) - m_renderedTarget->updateCostume(costume); + updateCostume(costume); } void SpriteModel::onVisibleChanged(bool visible) { - if (m_renderedTarget) - m_renderedTarget->updateVisibility(visible); + updateVisibility(visible); } void SpriteModel::onXChanged(double x) { - if (m_renderedTarget) - m_renderedTarget->updateX(x); + updateX(x); } void SpriteModel::onYChanged(double y) { - if (m_renderedTarget) - m_renderedTarget->updateY(y); + updateY(y); } void SpriteModel::onMoved(double oldX, double oldY, double newX, double newY) { - if (m_penState.penDown && m_penLayer) { - m_penLayer->drawLine(m_penState.penAttributes, oldX, oldY, newX, newY); - libscratchcpp::IEngine *engine = m_sprite->engine(); - - if (engine) - engine->requestRedraw(); - } + TargetModel::onMoved(oldX, oldY, newX, newY); } void SpriteModel::onSizeChanged(double size) { - if (m_renderedTarget) - m_renderedTarget->updateSize(size); + updateSize(size); } void SpriteModel::onDirectionChanged(double direction) { - if (m_renderedTarget) - m_renderedTarget->updateDirection(direction); + updateDirection(direction); } void SpriteModel::onRotationStyleChanged(libscratchcpp::Sprite::RotationStyle rotationStyle) { - if (m_renderedTarget) - m_renderedTarget->updateRotationStyle(rotationStyle); + updateRotationStyle(rotationStyle); } void SpriteModel::onLayerOrderChanged(int layerOrder) { - if (m_renderedTarget) - m_renderedTarget->updateLayerOrder(layerOrder); + updateLayerOrder(layerOrder); } void SpriteModel::onGraphicsEffectChanged(libscratchcpp::IGraphicsEffect *effect, double value) { - GraphicsEffect *graphicsEffect = dynamic_cast(effect); - - if (graphicsEffect && m_renderedTarget) - m_renderedTarget->setGraphicEffect(graphicsEffect->effect(), value); + setGraphicEffect(effect, value); } void SpriteModel::onGraphicsEffectsCleared() { - if (m_renderedTarget) - m_renderedTarget->clearGraphicEffects(); + clearGraphicEffects(); } int SpriteModel::costumeWidth() const { - return m_renderedTarget->costumeWidth(); + return TargetModel::costumeWidth(); } int SpriteModel::costumeHeight() const { - return m_renderedTarget->costumeHeight(); + return TargetModel::costumeHeight(); } libscratchcpp::Rect SpriteModel::boundingRect() const { - return m_renderedTarget->getBounds(); + libscratchcpp::Rect ret; + getBoundingRect(ret); + return ret; } libscratchcpp::Rect SpriteModel::fastBoundingRect() const { - return m_renderedTarget->getFastBounds(); + libscratchcpp::Rect ret; + getFastBoundingRect(ret); + return ret; } bool SpriteModel::touchingClones(const std::vector &clones) const { - return m_renderedTarget->touchingClones(clones); + return TargetModel::touchingClones(clones); } bool SpriteModel::touchingPoint(double x, double y) const { - return m_renderedTarget->containsScratchPoint(x, y); + return TargetModel::touchingPoint(x, y); } bool SpriteModel::touchingColor(libscratchcpp::Rgb color) const { - return m_renderedTarget->touchingColor(color); + return TargetModel::touchingColor(color); } bool SpriteModel::touchingColor(libscratchcpp::Rgb color, libscratchcpp::Rgb mask) const { - return m_renderedTarget->touchingColor(color, mask); + return TargetModel::touchingColor(color, mask); } libscratchcpp::Sprite *SpriteModel::sprite() const @@ -190,60 +145,9 @@ libscratchcpp::Sprite *SpriteModel::sprite() const return m_sprite; } -IRenderedTarget *SpriteModel::renderedTarget() const -{ - return m_renderedTarget; -} - -void SpriteModel::setRenderedTarget(IRenderedTarget *newRenderedTarget) -{ - if (m_renderedTarget == newRenderedTarget) - return; - - m_renderedTarget = newRenderedTarget; - emit renderedTargetChanged(); -} - -IPenLayer *SpriteModel::penLayer() const -{ - return m_penLayer; -} - -void SpriteModel::setPenLayer(IPenLayer *newPenLayer) -{ - if (m_penLayer == newPenLayer) - return; - - m_penLayer = newPenLayer; - emit penLayerChanged(); -} - -PenState &SpriteModel::penState() -{ - return m_penState; -} - -PenAttributes &SpriteModel::penAttributes() -{ - return m_penState.penAttributes; -} - -bool SpriteModel::penDown() const -{ - return m_penState.penDown; -} - -void SpriteModel::setPenDown(bool newPenDown) +int SpriteModel::bubbleLayer() const { - m_penState.penDown = newPenDown; - - if (m_penState.penDown && m_penLayer && m_sprite) { - m_penLayer->drawPoint(m_penState.penAttributes, m_sprite->x(), m_sprite->y()); - libscratchcpp::IEngine *engine = m_sprite->engine(); - - if (engine) - engine->requestRedraw(); - } + return m_sprite ? m_sprite->bubble()->layerOrder() : 0; } SpriteModel *SpriteModel::cloneRoot() const @@ -254,19 +158,26 @@ SpriteModel *SpriteModel::cloneRoot() const return m_cloneRoot; } -const TextBubbleShape::Type &SpriteModel::bubbleType() const +void SpriteModel::loadCostume() { - return m_bubbleType; + if (m_sprite) + updateCostume(m_sprite->currentCostume().get()); } -const QString &SpriteModel::bubbleText() const +void SpriteModel::drawPenPoint(IPenLayer *penLayer, const PenAttributes &penAttributes) { - return m_bubbleText; + penLayer->drawPoint(penAttributes, m_sprite->x(), m_sprite->y()); + libscratchcpp::IEngine *engine = m_sprite->engine(); + + if (engine) + engine->requestRedraw(); } -int SpriteModel::bubbleLayer() const +void SpriteModel::drawPenLine(IPenLayer *penLayer, const PenAttributes &penAttributes, double x0, double y0, double x1, double y1) { - return m_sprite ? m_sprite->bubble()->layerOrder() : 0; -} + penLayer->drawLine(penAttributes, x0, y0, x1, y1); + libscratchcpp::IEngine *engine = m_sprite->engine(); -} // namespace scratchcpprender + if (engine) + engine->requestRedraw(); +} diff --git a/src/spritemodel.h b/src/spritemodel.h index 4c3e6bb..6428396 100644 --- a/src/spritemodel.h +++ b/src/spritemodel.h @@ -2,33 +2,19 @@ #pragma once -#include -#include #include -#include "penstate.h" -#include "textbubbleshape.h" - -Q_MOC_INCLUDE("renderedtarget.h"); -Q_MOC_INCLUDE("ipenlayer.h"); +#include "targetmodel.h" namespace scratchcpprender { -class IRenderedTarget; -class IPenLayer; - class SpriteModel - : public QObject + : public TargetModel , public libscratchcpp::ISpriteHandler { Q_OBJECT QML_ELEMENT - Q_PROPERTY(IRenderedTarget *renderedTarget READ renderedTarget WRITE setRenderedTarget NOTIFY renderedTargetChanged) - Q_PROPERTY(IPenLayer *penLayer READ penLayer WRITE setPenLayer NOTIFY penLayerChanged) - Q_PROPERTY(TextBubbleShape::Type bubbleType READ bubbleType NOTIFY bubbleTypeChanged) - Q_PROPERTY(QString bubbleText READ bubbleText NOTIFY bubbleTextChanged) - Q_PROPERTY(int bubbleLayer READ bubbleLayer NOTIFY bubbleLayerChanged) public: SpriteModel(QObject *parent = nullptr); @@ -65,43 +51,23 @@ class SpriteModel libscratchcpp::Sprite *sprite() const; - IRenderedTarget *renderedTarget() const; - void setRenderedTarget(IRenderedTarget *newRenderedTarget); - - IPenLayer *penLayer() const; - void setPenLayer(IPenLayer *newPenLayer); - - PenState &penState(); - PenAttributes &penAttributes(); - - bool penDown() const; - void setPenDown(bool newPenDown); + int bubbleLayer() const override; SpriteModel *cloneRoot() const; - const TextBubbleShape::Type &bubbleType() const; - - const QString &bubbleText() const; - - int bubbleLayer() const; + Q_INVOKABLE void loadCostume() override; signals: - void renderedTargetChanged(); - void penLayerChanged(); - void bubbleTypeChanged(); - void bubbleTextChanged(); void cloned(SpriteModel *cloneModel); void cloneDeleted(SpriteModel *clone); - void bubbleLayerChanged(); + + protected: + void drawPenPoint(IPenLayer *penLayer, const PenAttributes &penAttributes) override; + void drawPenLine(IPenLayer *penLayer, const PenAttributes &penAttributes, double x0, double y0, double x1, double y1) override; private: libscratchcpp::Sprite *m_sprite = nullptr; - IRenderedTarget *m_renderedTarget = nullptr; - IPenLayer *m_penLayer = nullptr; - PenState m_penState; SpriteModel *m_cloneRoot = nullptr; - TextBubbleShape::Type m_bubbleType = TextBubbleShape::Type::Say; - QString m_bubbleText; }; } // namespace scratchcpprender diff --git a/src/stagemodel.cpp b/src/stagemodel.cpp index cc4c724..4aa3f5b 100644 --- a/src/stagemodel.cpp +++ b/src/stagemodel.cpp @@ -1,16 +1,16 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include +#include #include #include "stagemodel.h" -#include "renderedtarget.h" -#include "graphicseffect.h" +#include "penlayer.h" using namespace scratchcpprender; StageModel::StageModel(QObject *parent) : - QObject(parent) + TargetModel(parent) { } @@ -18,42 +18,13 @@ void StageModel::init(libscratchcpp::Stage *stage) { m_stage = stage; - if (m_stage) { - libscratchcpp::TextBubble *bubble = m_stage->bubble(); - - bubble->typeChanged().connect([this](libscratchcpp::TextBubble::Type type) { - if (type == libscratchcpp::TextBubble::Type::Say) { - if (m_bubbleType == TextBubbleShape::Type::Say) - return; - - m_bubbleType = TextBubbleShape::Type::Say; - } else { - if (m_bubbleType == TextBubbleShape::Type::Think) - return; - - m_bubbleType = TextBubbleShape::Type::Think; - } - - emit bubbleTypeChanged(); - }); - - bubble->textChanged().connect([this](const std::string &text) { - QString newText = QString::fromStdString(text); - - if (m_bubbleText != newText) { - m_bubbleText = newText; - emit bubbleTextChanged(); - } - }); - - bubble->layerOrderChanged().connect([this](int) { emit bubbleLayerChanged(); }); - } + if (m_stage) + setupTextBubble(m_stage->bubble()); } void StageModel::onCostumeChanged(libscratchcpp::Costume *costume) { - if (m_renderedTarget) - m_renderedTarget->updateCostume(costume); + updateCostume(costume); } void StageModel::onTempoChanged(int tempo) @@ -70,62 +41,56 @@ void StageModel::onVideoTransparencyChanged(int videoTransparency) void StageModel::onGraphicsEffectChanged(libscratchcpp::IGraphicsEffect *effect, double value) { - GraphicsEffect *graphicsEffect = dynamic_cast(effect); - - if (graphicsEffect && m_renderedTarget) - m_renderedTarget->setGraphicEffect(graphicsEffect->effect(), value); + setGraphicEffect(effect, value); } void StageModel::onGraphicsEffectsCleared() { - if (m_renderedTarget) - m_renderedTarget->clearGraphicEffects(); + clearGraphicEffects(); } int StageModel::costumeWidth() const { - return m_renderedTarget->costumeWidth(); + return TargetModel::costumeWidth(); } int StageModel::costumeHeight() const { - return m_renderedTarget->costumeHeight(); + return TargetModel::costumeHeight(); } libscratchcpp::Rect StageModel::boundingRect() const { - return libscratchcpp::Rect(); + libscratchcpp::Rect ret; + getBoundingRect(ret); + return ret; } libscratchcpp::Rect StageModel::fastBoundingRect() const { - return libscratchcpp::Rect(); + libscratchcpp::Rect ret; + getFastBoundingRect(ret); + return ret; } bool StageModel::touchingClones(const std::vector &clones) const { - return m_renderedTarget->touchingClones(clones); + return TargetModel::touchingClones(clones); } bool StageModel::touchingPoint(double x, double y) const { - return m_renderedTarget->containsScratchPoint(x, y); + return TargetModel::touchingPoint(x, y); } bool StageModel::touchingColor(libscratchcpp::Rgb color) const { - return m_renderedTarget->touchingColor(color); + return TargetModel::touchingColor(color); } bool StageModel::touchingColor(libscratchcpp::Rgb color, libscratchcpp::Rgb mask) const { - return m_renderedTarget->touchingColor(color, mask); -} - -void StageModel::loadCostume() -{ - if (m_renderedTarget && m_stage) - m_renderedTarget->updateCostume(m_stage->currentCostume().get()); + return TargetModel::touchingColor(color, mask); } libscratchcpp::Stage *StageModel::stage() const @@ -133,32 +98,22 @@ libscratchcpp::Stage *StageModel::stage() const return m_stage; } -IRenderedTarget *StageModel::renderedTarget() const -{ - return m_renderedTarget; -} - -void StageModel::setRenderedTarget(IRenderedTarget *newRenderedTarget) +int StageModel::bubbleLayer() const { - if (m_renderedTarget == newRenderedTarget) - return; - - m_renderedTarget = newRenderedTarget; - - emit renderedTargetChanged(); + return m_stage ? m_stage->bubble()->layerOrder() : 0; } -const TextBubbleShape::Type &StageModel::bubbleType() const +void StageModel::loadCostume() { - return m_bubbleType; + if (m_stage) + updateCostume(m_stage->currentCostume().get()); } -const QString &StageModel::bubbleText() const +void StageModel::drawPenPoint(IPenLayer *penLayer, const PenAttributes &penAttributes) { - return m_bubbleText; -} + penLayer->drawLine(penAttributes, 0, 0, 0, 0); + libscratchcpp::IEngine *engine = m_stage->engine(); -int StageModel::bubbleLayer() const -{ - return m_stage ? m_stage->bubble()->layerOrder() : 0; + if (engine) + engine->requestRedraw(); } diff --git a/src/stagemodel.h b/src/stagemodel.h index 47d3e8b..e7512de 100644 --- a/src/stagemodel.h +++ b/src/stagemodel.h @@ -2,27 +2,18 @@ #pragma once -#include #include -#include "textbubbleshape.h" - -Q_MOC_INCLUDE("renderedtarget.h"); +#include "targetmodel.h" namespace scratchcpprender { -class IRenderedTarget; - class StageModel - : public QObject + : public TargetModel , public libscratchcpp::IStageHandler { Q_OBJECT - Q_PROPERTY(IRenderedTarget *renderedTarget READ renderedTarget WRITE setRenderedTarget NOTIFY renderedTargetChanged) - Q_PROPERTY(TextBubbleShape::Type bubbleType READ bubbleType NOTIFY bubbleTypeChanged) - Q_PROPERTY(QString bubbleText READ bubbleText NOTIFY bubbleTextChanged) - Q_PROPERTY(int bubbleLayer READ bubbleLayer NOTIFY bubbleLayerChanged) public: explicit StageModel(QObject *parent = nullptr); @@ -49,30 +40,17 @@ class StageModel bool touchingColor(libscratchcpp::Rgb color) const override; bool touchingColor(libscratchcpp::Rgb color, libscratchcpp::Rgb mask) const override; - Q_INVOKABLE void loadCostume(); - libscratchcpp::Stage *stage() const; - IRenderedTarget *renderedTarget() const; - void setRenderedTarget(IRenderedTarget *newRenderedTarget); - - const TextBubbleShape::Type &bubbleType() const; - - const QString &bubbleText() const; + int bubbleLayer() const override; - int bubbleLayer() const; + Q_INVOKABLE void loadCostume() override; - signals: - void renderedTargetChanged(); - void bubbleTypeChanged(); - void bubbleTextChanged(); - void bubbleLayerChanged(); + protected: + void drawPenPoint(IPenLayer *penLayer, const PenAttributes &penAttributes) override; private: libscratchcpp::Stage *m_stage = nullptr; - IRenderedTarget *m_renderedTarget = nullptr; - TextBubbleShape::Type m_bubbleType = TextBubbleShape::Type::Say; - QString m_bubbleText; }; } // namespace scratchcpprender diff --git a/src/targetmodel.cpp b/src/targetmodel.cpp new file mode 100644 index 0000000..82e28db --- /dev/null +++ b/src/targetmodel.cpp @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include + +#include "targetmodel.h" +#include "renderedtarget.h" +#include "penlayer.h" +#include "graphicseffect.h" + +using namespace scratchcpprender; + +TargetModel::TargetModel(QObject *parent) : + QObject(parent) +{ +} + +IRenderedTarget *TargetModel::renderedTarget() const +{ + return m_renderedTarget; +} + +void TargetModel::setRenderedTarget(IRenderedTarget *newRenderedTarget) +{ + if (m_renderedTarget == newRenderedTarget) + return; + + m_renderedTarget = newRenderedTarget; + + emit renderedTargetChanged(); +} + +IPenLayer *TargetModel::penLayer() const +{ + return m_penLayer; +} + +void TargetModel::setPenLayer(IPenLayer *newPenLayer) +{ + if (m_penLayer == newPenLayer) + return; + + m_penLayer = newPenLayer; + emit penLayerChanged(); +} + +PenState &TargetModel::penState() +{ + return m_penState; +} + +PenAttributes &TargetModel::penAttributes() +{ + return m_penState.penAttributes; +} + +bool TargetModel::penDown() const +{ + return m_penState.penDown; +} + +void TargetModel::setPenDown(bool newPenDown) +{ + m_penState.penDown = newPenDown; + + if (m_penState.penDown && m_penLayer) + drawPenPoint(m_penLayer, m_penState.penAttributes); +} + +const TextBubbleShape::Type &TargetModel::bubbleType() const +{ + return m_bubbleType; +} + +const QString &TargetModel::bubbleText() const +{ + return m_bubbleText; +} + +void TargetModel::setupTextBubble(libscratchcpp::TextBubble *bubble) +{ + bubble->typeChanged().connect([this](libscratchcpp::TextBubble::Type type) { + if (type == libscratchcpp::TextBubble::Type::Say) { + if (m_bubbleType == TextBubbleShape::Type::Say) + return; + + m_bubbleType = TextBubbleShape::Type::Say; + } else { + if (m_bubbleType == TextBubbleShape::Type::Think) + return; + + m_bubbleType = TextBubbleShape::Type::Think; + } + + emit bubbleTypeChanged(); + }); + + bubble->textChanged().connect([this](const std::string &text) { + QString newText = QString::fromStdString(text); + + if (m_bubbleText != newText) { + m_bubbleText = newText; + emit bubbleTextChanged(); + } + }); + + bubble->layerOrderChanged().connect([this](int) { emit bubbleLayerChanged(); }); +} + +void TargetModel::updateVisibility(bool visible) +{ + if (m_renderedTarget) + m_renderedTarget->updateVisibility(visible); +} + +void TargetModel::updateX(double x) +{ + if (m_renderedTarget) + m_renderedTarget->updateX(x); +} + +void TargetModel::updateY(double y) +{ + if (m_renderedTarget) + m_renderedTarget->updateY(y); +} + +void TargetModel::updateSize(double size) +{ + if (m_renderedTarget) + m_renderedTarget->updateSize(size); +} + +void TargetModel::updateDirection(double direction) +{ + if (m_renderedTarget) + m_renderedTarget->updateDirection(direction); +} + +void TargetModel::updateRotationStyle(libscratchcpp::Sprite::RotationStyle style) +{ + if (m_renderedTarget) + m_renderedTarget->updateRotationStyle(style); +} + +void TargetModel::updateLayerOrder(int layerOrder) +{ + if (m_renderedTarget) + m_renderedTarget->updateLayerOrder(layerOrder); +} + +void TargetModel::updateCostume(libscratchcpp::Costume *costume) +{ + if (m_renderedTarget) + m_renderedTarget->updateCostume(costume); +} + +void TargetModel::onMoved(double oldX, double oldY, double newX, double newY) +{ + if (m_penState.penDown && m_penLayer) + drawPenLine(m_penLayer, m_penState.penAttributes, oldX, oldY, newX, newY); +} + +void TargetModel::setGraphicEffect(libscratchcpp::IGraphicsEffect *effect, double value) +{ + GraphicsEffect *graphicsEffect = dynamic_cast(effect); + + if (graphicsEffect && m_renderedTarget) + m_renderedTarget->setGraphicEffect(graphicsEffect->effect(), value); +} + +void TargetModel::clearGraphicEffects() +{ + if (m_renderedTarget) + m_renderedTarget->clearGraphicEffects(); +} + +int TargetModel::costumeWidth() const +{ + return m_renderedTarget->costumeWidth(); +} + +int TargetModel::costumeHeight() const +{ + return m_renderedTarget->costumeHeight(); +} + +void TargetModel::getBoundingRect(libscratchcpp::Rect &dst) const +{ + dst = m_renderedTarget->getBounds(); +} + +void TargetModel::getFastBoundingRect(libscratchcpp::Rect &dst) const +{ + dst = m_renderedTarget->getFastBounds(); +} + +bool TargetModel::touchingClones(const std::vector &clones) const +{ + return m_renderedTarget->touchingClones(clones); +} + +bool TargetModel::touchingPoint(double x, double y) const +{ + return m_renderedTarget->containsScratchPoint(x, y); +} + +bool TargetModel::touchingColor(libscratchcpp::Rgb color) const +{ + return m_renderedTarget->touchingColor(color); +} + +bool TargetModel::touchingColor(libscratchcpp::Rgb color, libscratchcpp::Rgb mask) const +{ + return m_renderedTarget->touchingColor(color, mask); +} diff --git a/src/targetmodel.h b/src/targetmodel.h new file mode 100644 index 0000000..2be3e1f --- /dev/null +++ b/src/targetmodel.h @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later + +#pragma once + +#include +#include + +#include "penstate.h" +#include "textbubbleshape.h" + +Q_MOC_INCLUDE("renderedtarget.h"); +Q_MOC_INCLUDE("ipenlayer.h"); + +namespace scratchcpprender +{ + +class IRenderedTarget; +class IPenLayer; + +class TargetModel : public QObject +{ + Q_OBJECT + Q_PROPERTY(IRenderedTarget *renderedTarget READ renderedTarget WRITE setRenderedTarget NOTIFY renderedTargetChanged) + Q_PROPERTY(IPenLayer *penLayer READ penLayer WRITE setPenLayer NOTIFY penLayerChanged) + Q_PROPERTY(TextBubbleShape::Type bubbleType READ bubbleType NOTIFY bubbleTypeChanged) + Q_PROPERTY(QString bubbleText READ bubbleText NOTIFY bubbleTextChanged) + Q_PROPERTY(int bubbleLayer READ bubbleLayer NOTIFY bubbleLayerChanged) + + public: + explicit TargetModel(QObject *parent = nullptr); + + IRenderedTarget *renderedTarget() const; + void setRenderedTarget(IRenderedTarget *newRenderedTarget); + + IPenLayer *penLayer() const; + void setPenLayer(IPenLayer *newPenLayer); + + PenState &penState(); + PenAttributes &penAttributes(); + + bool penDown() const; + void setPenDown(bool newPenDown); + + const TextBubbleShape::Type &bubbleType() const; + + const QString &bubbleText() const; + + virtual int bubbleLayer() const { return 0; } + + Q_INVOKABLE virtual void loadCostume() { } + + signals: + void renderedTargetChanged(); + void penLayerChanged(); + void bubbleTypeChanged(); + void bubbleTextChanged(); + void bubbleLayerChanged(); + + protected: + void setupTextBubble(libscratchcpp::TextBubble *bubble); + + void updateVisibility(bool visible); + void updateX(double x); + void updateY(double y); + void updateSize(double size); + void updateDirection(double direction); + void updateRotationStyle(libscratchcpp::Sprite::RotationStyle style); + void updateLayerOrder(int layerOrder); + void updateCostume(libscratchcpp::Costume *costume); + + void onMoved(double oldX, double oldY, double newX, double newY); + + void setGraphicEffect(libscratchcpp::IGraphicsEffect *effect, double value); + void clearGraphicEffects(); + + int costumeWidth() const; + int costumeHeight() const; + + void getBoundingRect(libscratchcpp::Rect &dst) const; + void getFastBoundingRect(libscratchcpp::Rect &dst) const; + + bool touchingClones(const std::vector &clones) const; + bool touchingPoint(double x, double y) const; + bool touchingColor(libscratchcpp::Rgb color) const; + bool touchingColor(libscratchcpp::Rgb color, libscratchcpp::Rgb mask) const; + + virtual void drawPenPoint(IPenLayer *penLayer, const PenAttributes &penAttributes) { } // stage and sprites can draw points + virtual void drawPenLine(IPenLayer *penLayer, const PenAttributes &penAttributes, double x0, double y0, double x1, double y1) { } // only sprites can draw lines + + private: + IRenderedTarget *m_renderedTarget = nullptr; + IPenLayer *m_penLayer = nullptr; + PenState m_penState; + TextBubbleShape::Type m_bubbleType = TextBubbleShape::Type::Say; + QString m_bubbleText; +}; + +} // namespace scratchcpprender diff --git a/test/target_models/CMakeLists.txt b/test/target_models/CMakeLists.txt index bf565a2..0ff7efe 100644 --- a/test/target_models/CMakeLists.txt +++ b/test/target_models/CMakeLists.txt @@ -1,3 +1,23 @@ +# targetmodel_test +add_executable( + targetmodel_test + targetmodel_test.cpp +) + +target_link_libraries( + targetmodel_test + GTest::gtest_main + GTest::gmock_main + scratchcpp-render + scratchcpprender_mocks + qnanopainter + ${QT_LIBS} + Qt6::Test +) + +add_test(targetmodel_test) +gtest_discover_tests(targetmodel_test) + # stagemodel_test add_executable( stagemodel_test diff --git a/test/target_models/spritemodel_test.cpp b/test/target_models/spritemodel_test.cpp index 035744d..501213e 100644 --- a/test/target_models/spritemodel_test.cpp +++ b/test/target_models/spritemodel_test.cpp @@ -407,30 +407,6 @@ TEST(SpriteModelTest, TouchingColor) ASSERT_TRUE(model.touchingColor(color1, color2)); } -TEST(SpriteModelTest, RenderedTarget) -{ - SpriteModel model; - ASSERT_EQ(model.renderedTarget(), nullptr); - - RenderedTargetMock renderedTarget; - QSignalSpy spy(&model, &SpriteModel::renderedTargetChanged); - model.setRenderedTarget(&renderedTarget); - ASSERT_EQ(spy.count(), 1); - ASSERT_EQ(model.renderedTarget(), &renderedTarget); -} - -TEST(SpriteModelTest, PenLayer) -{ - SpriteModel model; - ASSERT_EQ(model.penLayer(), nullptr); - - PenLayerMock penLayer; - QSignalSpy spy(&model, &SpriteModel::penLayerChanged); - model.setPenLayer(&penLayer); - ASSERT_EQ(spy.count(), 1); - ASSERT_EQ(model.penLayer(), &penLayer); -} - TEST(SpriteModelTest, PenDown) { SpriteModel model; @@ -478,3 +454,28 @@ TEST(SpriteModelTest, BubbleLayer) ASSERT_EQ(model.bubbleLayer(), 5); ASSERT_EQ(spy.count(), 1); } + +TEST(SpriteModelTest, LoadCostume) +{ + SpriteModel model; + Sprite sprite; + model.init(&sprite); + + auto c1 = std::make_shared("", "", ""); + auto c2 = std::make_shared("", "", ""); + auto c3 = std::make_shared("", "", ""); + sprite.addCostume(c1); + sprite.addCostume(c2); + sprite.addCostume(c3); + sprite.setCostumeIndex(1); + + RenderedTargetMock renderedTarget; + QSignalSpy spy(&model, &TargetModel::renderedTargetChanged); + model.setRenderedTarget(&renderedTarget); + ASSERT_EQ(spy.count(), 1); + ASSERT_EQ(model.renderedTarget(), &renderedTarget); + + EXPECT_CALL(renderedTarget, updateCostume(c3.get())); + sprite.setCostumeIndex(2); + model.loadCostume(); +} diff --git a/test/target_models/stagemodel_test.cpp b/test/target_models/stagemodel_test.cpp index 8e63826..b949476 100644 --- a/test/target_models/stagemodel_test.cpp +++ b/test/target_models/stagemodel_test.cpp @@ -200,10 +200,21 @@ TEST(StageModelTest, TouchingColor) ASSERT_TRUE(model.touchingColor(color1, color2)); } -TEST(StageModelTest, RenderedTarget) +TEST(StageModelTest, BubbleLayer) +{ + StageModel model; + Stage stage; + model.init(&stage); + QSignalSpy spy(&model, &StageModel::bubbleLayerChanged); + + stage.bubble()->setLayerOrder(5); + ASSERT_EQ(model.bubbleLayer(), 5); + ASSERT_EQ(spy.count(), 1); +} + +TEST(StageModelTest, LoadCostume) { StageModel model; - ASSERT_EQ(model.renderedTarget(), nullptr); Stage stage; model.init(&stage); @@ -216,7 +227,7 @@ TEST(StageModelTest, RenderedTarget) stage.setCostumeIndex(1); RenderedTargetMock renderedTarget; - QSignalSpy spy(&model, &StageModel::renderedTargetChanged); + QSignalSpy spy(&model, &TargetModel::renderedTargetChanged); model.setRenderedTarget(&renderedTarget); ASSERT_EQ(spy.count(), 1); ASSERT_EQ(model.renderedTarget(), &renderedTarget); @@ -225,15 +236,3 @@ TEST(StageModelTest, RenderedTarget) stage.setCostumeIndex(2); model.loadCostume(); } - -TEST(StageModelTest, BubbleLayer) -{ - StageModel model; - Stage stage; - model.init(&stage); - QSignalSpy spy(&model, &StageModel::bubbleLayerChanged); - - stage.bubble()->setLayerOrder(5); - ASSERT_EQ(model.bubbleLayer(), 5); - ASSERT_EQ(spy.count(), 1); -} diff --git a/test/target_models/targetmodel_test.cpp b/test/target_models/targetmodel_test.cpp new file mode 100644 index 0000000..1be0a14 --- /dev/null +++ b/test/target_models/targetmodel_test.cpp @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../common.h" + +using namespace scratchcpprender; +using namespace libscratchcpp; + +using ::testing::Return; +using ::testing::WithArgs; +using ::testing::Invoke; +using ::testing::_; + +TEST(TargetModelTest, Constructors) +{ + QObject parent; + TargetModel model(&parent); + ASSERT_EQ(model.parent(), &parent); +} + +TEST(TargetModelTest, RenderedTarget) +{ + TargetModel model; + ASSERT_EQ(model.renderedTarget(), nullptr); + + RenderedTargetMock renderedTarget; + QSignalSpy spy(&model, &TargetModel::renderedTargetChanged); + model.setRenderedTarget(&renderedTarget); + ASSERT_EQ(spy.count(), 1); + ASSERT_EQ(model.renderedTarget(), &renderedTarget); +} + +TEST(TargetModelTest, PenLayer) +{ + TargetModel model; + ASSERT_EQ(model.penLayer(), nullptr); + + PenLayerMock penLayer; + QSignalSpy spy(&model, &TargetModel::penLayerChanged); + model.setPenLayer(&penLayer); + ASSERT_EQ(spy.count(), 1); + ASSERT_EQ(model.penLayer(), &penLayer); +} From 43e90f70dec603e58a53dc93adf4df39cfbf31bf Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sun, 2 Feb 2025 11:08:12 +0100 Subject: [PATCH 2/3] ProjectPlayer: Set stage pen layer --- src/ProjectPlayer.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ProjectPlayer.qml b/src/ProjectPlayer.qml index cb4f3d3..87f8f7e 100644 --- a/src/ProjectPlayer.qml +++ b/src/ProjectPlayer.qml @@ -173,6 +173,7 @@ ProjectScene { mouseArea: sceneMouseArea stageScale: root.stageScale onStageModelChanged: stageModel.renderedTarget = this + Component.onCompleted: stageModel.penLayer = projectPenLayer } Loader { From 5e5ec4fc163f48104b1f46c82bac0d296d635353 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sun, 2 Feb 2025 11:13:25 +0100 Subject: [PATCH 3/3] Add support for stage pen rendering --- src/blocks/penblocks.cpp | 52 +- src/blocks/penblocks.h | 4 +- test/blocks/pen_blocks_test.cpp | 1322 +++++++++++++++++-------------- 3 files changed, 757 insertions(+), 621 deletions(-) diff --git a/src/blocks/penblocks.cpp b/src/blocks/penblocks.cpp index e368e54..2d77b79 100644 --- a/src/blocks/penblocks.cpp +++ b/src/blocks/penblocks.cpp @@ -220,7 +220,7 @@ unsigned int PenBlocks::stamp(libscratchcpp::VirtualMachine *vm) unsigned int PenBlocks::penDown(VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) model->setPenDown(true); @@ -230,7 +230,7 @@ unsigned int PenBlocks::penDown(VirtualMachine *vm) unsigned int PenBlocks::penUp(libscratchcpp::VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) model->setPenDown(false); @@ -240,7 +240,7 @@ unsigned int PenBlocks::penUp(libscratchcpp::VirtualMachine *vm) unsigned int PenBlocks::changePenSizeBy(libscratchcpp::VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) model->penAttributes().diameter = std::clamp(model->penAttributes().diameter + vm->getInput(0, 1)->toDouble(), PEN_SIZE_MIN, PEN_SIZE_MAX); @@ -250,7 +250,7 @@ unsigned int PenBlocks::changePenSizeBy(libscratchcpp::VirtualMachine *vm) unsigned int PenBlocks::setPenSizeTo(libscratchcpp::VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) model->penAttributes().diameter = std::clamp(vm->getInput(0, 1)->toDouble(), PEN_SIZE_MIN, PEN_SIZE_MAX); @@ -260,7 +260,7 @@ unsigned int PenBlocks::setPenSizeTo(libscratchcpp::VirtualMachine *vm) unsigned int PenBlocks::changePenShadeBy(libscratchcpp::VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) { PenState &penState = model->penState(); @@ -272,7 +272,7 @@ unsigned int PenBlocks::changePenShadeBy(libscratchcpp::VirtualMachine *vm) unsigned int PenBlocks::setPenShadeToNumber(libscratchcpp::VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) setPenShade(vm->getInput(0, 1)->toInt(), model->penState()); @@ -282,7 +282,7 @@ unsigned int PenBlocks::setPenShadeToNumber(libscratchcpp::VirtualMachine *vm) unsigned int PenBlocks::changePenHueBy(libscratchcpp::VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) { PenState &penState = model->penState(); @@ -296,7 +296,7 @@ unsigned int PenBlocks::changePenHueBy(libscratchcpp::VirtualMachine *vm) unsigned int PenBlocks::setPenHueToNumber(libscratchcpp::VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) { PenState &penState = model->penState(); @@ -311,7 +311,7 @@ unsigned int PenBlocks::setPenHueToNumber(libscratchcpp::VirtualMachine *vm) unsigned int PenBlocks::setPenColorToColor(libscratchcpp::VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) { const Value *value = vm->getInput(0, 1); @@ -358,7 +358,7 @@ unsigned int PenBlocks::setPenColorToColor(libscratchcpp::VirtualMachine *vm) unsigned int PenBlocks::changePenColorParamBy(VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) { const auto it = COLOR_PARAM_MAP.find(vm->getInput(0, 2)->toString()); @@ -374,7 +374,7 @@ unsigned int PenBlocks::changePenColorParamBy(VirtualMachine *vm) unsigned int PenBlocks::changePenColorBy(VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) setOrChangeColorParam(ColorParam::COLOR, vm->getInput(0, 1)->toDouble(), model->penState(), true); @@ -384,7 +384,7 @@ unsigned int PenBlocks::changePenColorBy(VirtualMachine *vm) unsigned int PenBlocks::changePenSaturationBy(VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) setOrChangeColorParam(ColorParam::SATURATION, vm->getInput(0, 1)->toDouble(), model->penState(), true); @@ -394,7 +394,7 @@ unsigned int PenBlocks::changePenSaturationBy(VirtualMachine *vm) unsigned int PenBlocks::changePenBrightnessBy(VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) setOrChangeColorParam(ColorParam::BRIGHTNESS, vm->getInput(0, 1)->toDouble(), model->penState(), true); @@ -404,7 +404,7 @@ unsigned int PenBlocks::changePenBrightnessBy(VirtualMachine *vm) unsigned int PenBlocks::changePenTransparencyBy(VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) setOrChangeColorParam(ColorParam::TRANSPARENCY, vm->getInput(0, 1)->toDouble(), model->penState(), true); @@ -414,7 +414,7 @@ unsigned int PenBlocks::changePenTransparencyBy(VirtualMachine *vm) unsigned int PenBlocks::setPenColorParamTo(VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) { const auto it = COLOR_PARAM_MAP.find(vm->getInput(0, 2)->toString()); @@ -430,7 +430,7 @@ unsigned int PenBlocks::setPenColorParamTo(VirtualMachine *vm) unsigned int PenBlocks::setPenColorTo(VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) setOrChangeColorParam(ColorParam::COLOR, vm->getInput(0, 1)->toDouble(), model->penState(), false); @@ -440,7 +440,7 @@ unsigned int PenBlocks::setPenColorTo(VirtualMachine *vm) unsigned int PenBlocks::setPenSaturationTo(VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) setOrChangeColorParam(ColorParam::SATURATION, vm->getInput(0, 1)->toDouble(), model->penState(), false); @@ -450,7 +450,7 @@ unsigned int PenBlocks::setPenSaturationTo(VirtualMachine *vm) unsigned int PenBlocks::setPenBrightnessTo(VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) setOrChangeColorParam(ColorParam::BRIGHTNESS, vm->getInput(0, 1)->toDouble(), model->penState(), false); @@ -460,7 +460,7 @@ unsigned int PenBlocks::setPenBrightnessTo(VirtualMachine *vm) unsigned int PenBlocks::setPenTransparencyTo(VirtualMachine *vm) { - SpriteModel *model = getSpriteModel(vm); + TargetModel *model = getTargetModel(vm); if (model) setOrChangeColorParam(ColorParam::TRANSPARENCY, vm->getInput(0, 1)->toDouble(), model->penState(), false); @@ -468,16 +468,20 @@ unsigned int PenBlocks::setPenTransparencyTo(VirtualMachine *vm) return 1; } -SpriteModel *PenBlocks::getSpriteModel(libscratchcpp::VirtualMachine *vm) +TargetModel *PenBlocks::getTargetModel(libscratchcpp::VirtualMachine *vm) { Target *target = vm->target(); - if (!target || target->isStage()) + if (!target) return nullptr; - Sprite *sprite = static_cast(target); - SpriteModel *model = static_cast(sprite->getInterface()); - return model; + if (target->isStage()) { + Stage *stage = static_cast(target); + return static_cast(stage->getInterface()); + } else { + Sprite *sprite = static_cast(target); + return static_cast(sprite->getInterface()); + } } void PenBlocks::setOrChangeColorParam(ColorParam param, double value, PenState &penState, bool change) diff --git a/src/blocks/penblocks.h b/src/blocks/penblocks.h index e611310..61e147b 100644 --- a/src/blocks/penblocks.h +++ b/src/blocks/penblocks.h @@ -8,7 +8,7 @@ namespace scratchcpprender { -class SpriteModel; +class TargetModel; class PenState; class PenBlocks : public libscratchcpp::IExtension @@ -78,7 +78,7 @@ class PenBlocks : public libscratchcpp::IExtension TRANSPARENCY }; - static SpriteModel *getSpriteModel(libscratchcpp::VirtualMachine *vm); + static TargetModel *getTargetModel(libscratchcpp::VirtualMachine *vm); static void setOrChangeColorParam(ColorParam param, double value, PenState &penState, bool change); static void setPenShade(int shade, PenState &penState); static void legacyUpdatePenColor(PenState &penState); diff --git a/test/blocks/pen_blocks_test.cpp b/test/blocks/pen_blocks_test.cpp index 8428c82..900ede2 100644 --- a/test/blocks/pen_blocks_test.cpp +++ b/test/blocks/pen_blocks_test.cpp @@ -234,22 +234,34 @@ TEST_F(PenBlocksTest, PenDownImpl) static unsigned int bytecode[] = { vm::OP_START, vm::OP_EXEC, 0, vm::OP_HALT }; static BlockFunc functions[] = { &PenBlocks::penDown }; - SpriteModel model; - Sprite sprite; - sprite.setInterface(&model); - - VirtualMachine vm(&sprite, &m_engineMock, nullptr); - vm.setBytecode(bytecode); - vm.setFunctions(functions); - - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_TRUE(model.penDown()); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_TRUE(model.penDown()); + std::vector> models; + std::vector> targets; + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + for (int i = 0; i < targets.size(); i++) { + auto target = targets[i]; + auto model = models[i]; + + VirtualMachine vm(target.get(), &m_engineMock, nullptr); + vm.setBytecode(bytecode); + vm.setFunctions(functions); + + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_TRUE(model->penDown()); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_TRUE(model->penDown()); + } } TEST_F(PenBlocksTest, PenUp) @@ -275,23 +287,35 @@ TEST_F(PenBlocksTest, PenUpImpl) static unsigned int bytecode[] = { vm::OP_START, vm::OP_EXEC, 0, vm::OP_HALT }; static BlockFunc functions[] = { &PenBlocks::penUp }; - SpriteModel model; - model.setPenDown(true); - Sprite sprite; - sprite.setInterface(&model); + std::vector> models; + std::vector> targets; - VirtualMachine vm(&sprite, &m_engineMock, nullptr); - vm.setBytecode(bytecode); - vm.setFunctions(functions); + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_FALSE(model.penDown()); + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_FALSE(model.penDown()); + for (int i = 0; i < targets.size(); i++) { + auto target = targets[i]; + auto model = models[i]; + model->setPenDown(true); + + VirtualMachine vm(target.get(), &m_engineMock, nullptr); + vm.setBytecode(bytecode); + vm.setFunctions(functions); + + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_FALSE(model->penDown()); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_FALSE(model->penDown()); + } } TEST_F(PenBlocksTest, SetPenColorToColor) @@ -337,54 +361,66 @@ TEST_F(PenBlocksTest, SetPenColorToColorImpl) static BlockFunc functions[] = { &PenBlocks::setPenColorToColor }; static Value constValues[] = { "#AABbCC", "#03F", "#FFGFFF", "#AABBCCDD", "FFFFFF", 1228097602, 255 }; - SpriteModel model; - Sprite sprite; - sprite.setInterface(&model); - - VirtualMachine vm(&sprite, &m_engineMock, nullptr); - vm.setBytecode(bytecode1); - vm.setFunctions(functions); - vm.setConstValues(constValues); - - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(210, 42, 204))); - - vm.reset(); - vm.setBytecode(bytecode2); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(228, 255, 255))); - - vm.reset(); - vm.setBytecode(bytecode3); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(359, 0, 0))); - - vm.reset(); - vm.setBytecode(bytecode4); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(359, 0, 0))); - - vm.reset(); - vm.setBytecode(bytecode5); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(359, 0, 0))); - - vm.reset(); - vm.setBytecode(bytecode6); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(162, 74, 72, 73))); - - vm.reset(); - vm.setBytecode(bytecode7); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(239, 255, 255))); + std::vector> models; + std::vector> targets; + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + for (int i = 0; i < targets.size(); i++) { + auto target = targets[i]; + auto model = models[i]; + + VirtualMachine vm(target.get(), &m_engineMock, nullptr); + vm.setBytecode(bytecode1); + vm.setFunctions(functions); + vm.setConstValues(constValues); + + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(210, 42, 204))); + + vm.reset(); + vm.setBytecode(bytecode2); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(228, 255, 255))); + + vm.reset(); + vm.setBytecode(bytecode3); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(359, 0, 0))); + + vm.reset(); + vm.setBytecode(bytecode4); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(359, 0, 0))); + + vm.reset(); + vm.setBytecode(bytecode5); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(359, 0, 0))); + + vm.reset(); + vm.setBytecode(bytecode6); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(162, 74, 72, 73))); + + vm.reset(); + vm.setBytecode(bytecode7); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(239, 255, 255))); + } } TEST_F(PenBlocksTest, ChangePenColorParamBy) @@ -481,172 +517,184 @@ TEST_F(PenBlocksTest, ChangePenColorParamByImpl) functions[] = { &PenBlocks::changePenColorParamBy, &PenBlocks::changePenColorBy, &PenBlocks::changePenSaturationBy, &PenBlocks::changePenBrightnessBy, &PenBlocks::changePenTransparencyBy }; static Value constValues[] = { "color", "saturation", "brightness", "transparency", "invalid", 53.2, -120.8 }; - SpriteModel model; - model.penState().transparency = 100 * (1 - 150 / 255.0); - Sprite sprite; - sprite.setInterface(&model); - - VirtualMachine vm(&sprite, &m_engineMock, nullptr); - vm.setBytecode(bytecode1); - vm.setFunctions(functions); - vm.setConstValues(constValues); - - // color - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(71, 255, 255, 150))); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(263, 255, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode2); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 255, 255, 150))); - - // saturation - model.penState().saturation = 32.4; - vm.reset(); - vm.setBytecode(bytecode3); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 218, 255, 150))); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 255, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode4); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 255, 150))); - - // brightness - model.penState().brightness = 12.5; - vm.reset(); - vm.setBytecode(bytecode5); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 167, 150))); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode6); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 150))); - - // transparency - model.penState().transparency = 6.28; - vm.reset(); - vm.setBytecode(bytecode7); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 103))); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 0))); - - vm.reset(); - vm.setBytecode(bytecode8); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 255))); - - // invalid parameter - vm.reset(); - vm.setBytecode(bytecode9); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 255))); - - // color (optimized) - model.penState() = PenState(); - model.penState().transparency = 100 * (1 - 150 / 255.0); - vm.reset(); - vm.setBytecode(bytecode10); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(71, 255, 255, 150))); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(263, 255, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode11); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 255, 255, 150))); - - // saturation (optimized) - model.penState().saturation = 32.4; - vm.reset(); - vm.setBytecode(bytecode12); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 218, 255, 150))); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 255, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode13); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 255, 150))); - - // brightness (optimized) - model.penState().brightness = 12.5; - vm.reset(); - vm.setBytecode(bytecode14); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 167, 150))); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode15); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 150))); - - // transparency (optimized) - model.penState().transparency = 6.28; - vm.reset(); - vm.setBytecode(bytecode16); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 103))); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 0))); - - vm.reset(); - vm.setBytecode(bytecode17); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 255))); + std::vector> models; + std::vector> targets; + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + for (int i = 0; i < targets.size(); i++) { + auto target = targets[i]; + auto model = models[i]; + model->penState().transparency = 100 * (1 - 150 / 255.0); + + VirtualMachine vm(target.get(), &m_engineMock, nullptr); + vm.setBytecode(bytecode1); + vm.setFunctions(functions); + vm.setConstValues(constValues); + + // color + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(71, 255, 255, 150))); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(263, 255, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode2); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 255, 255, 150))); + + // saturation + model->penState().saturation = 32.4; + vm.reset(); + vm.setBytecode(bytecode3); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 218, 255, 150))); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 255, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode4); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 255, 150))); + + // brightness + model->penState().brightness = 12.5; + vm.reset(); + vm.setBytecode(bytecode5); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 167, 150))); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode6); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 150))); + + // transparency + model->penState().transparency = 6.28; + vm.reset(); + vm.setBytecode(bytecode7); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 103))); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 0))); + + vm.reset(); + vm.setBytecode(bytecode8); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 255))); + + // invalid parameter + vm.reset(); + vm.setBytecode(bytecode9); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 255))); + + // color (optimized) + model->penState() = PenState(); + model->penState().transparency = 100 * (1 - 150 / 255.0); + vm.reset(); + vm.setBytecode(bytecode10); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(71, 255, 255, 150))); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(263, 255, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode11); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 255, 255, 150))); + + // saturation (optimized) + model->penState().saturation = 32.4; + vm.reset(); + vm.setBytecode(bytecode12); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 218, 255, 150))); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 255, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode13); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 255, 150))); + + // brightness (optimized) + model->penState().brightness = 12.5; + vm.reset(); + vm.setBytecode(bytecode14); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 167, 150))); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode15); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 150))); + + // transparency (optimized) + model->penState().transparency = 6.28; + vm.reset(); + vm.setBytecode(bytecode16); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 103))); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 0))); + + vm.reset(); + vm.setBytecode(bytecode17); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(188, 0, 0, 255))); + } } TEST_F(PenBlocksTest, SetPenColorParamTo) @@ -750,182 +798,194 @@ TEST_F(PenBlocksTest, SetPenColorParamToImpl) static BlockFunc functions[] = { &PenBlocks::setPenColorParamTo, &PenBlocks::setPenColorTo, &PenBlocks::setPenSaturationTo, &PenBlocks::setPenBrightnessTo, &PenBlocks::setPenTransparencyTo }; static Value constValues[] = { "color", "saturation", "brightness", "transparency", "invalid", 53.2, -234.9, 287.1 }; - SpriteModel model; - model.penState().color = 78.6; - model.penState().transparency = 100 * (1 - 150 / 255.0); - Sprite sprite; - sprite.setInterface(&model); - - VirtualMachine vm(&sprite, &m_engineMock, nullptr); - vm.setBytecode(bytecode1); - vm.setFunctions(functions); - vm.setConstValues(constValues); - - // color - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(191, 255, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode2); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(234, 255, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode3); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 150))); - - // saturation - model.penState().saturation = 32.4; - vm.reset(); - vm.setBytecode(bytecode4); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 135, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode5); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 0, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode6); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 150))); - - // brightness - model.penState().brightness = 12.5; - vm.reset(); - vm.setBytecode(bytecode7); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 135, 150))); - - vm.reset(); - vm.setBytecode(bytecode8); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 0, 150))); - - vm.reset(); - vm.setBytecode(bytecode9); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 150))); - - // transparency - model.penState().transparency = 12.5; - vm.reset(); - vm.setBytecode(bytecode10); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 119))); - - vm.reset(); - vm.setBytecode(bytecode11); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 255))); - - vm.reset(); - vm.setBytecode(bytecode12); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 0))); - - // invalid parameter - vm.reset(); - vm.setBytecode(bytecode13); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 0))); - - // color (optimized) - model.penState() = PenState(); - model.penState().color = 78.6; - model.penState().transparency = 100 * (1 - 150 / 255.0); - vm.reset(); - vm.setBytecode(bytecode14); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(191, 255, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode15); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(234, 255, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode16); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 150))); - - // saturation (optimized) - model.penState().saturation = 32.4; - vm.reset(); - vm.setBytecode(bytecode17); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 135, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode18); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 0, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode19); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 150))); - - // brightness (optimized) - model.penState().brightness = 12.5; - vm.reset(); - vm.setBytecode(bytecode20); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 135, 150))); - - vm.reset(); - vm.setBytecode(bytecode21); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 0, 150))); - - vm.reset(); - vm.setBytecode(bytecode22); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 150))); - - // transparency (optimized) - model.penState().transparency = 12.5; - vm.reset(); - vm.setBytecode(bytecode23); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 119))); - - vm.reset(); - vm.setBytecode(bytecode24); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 255))); - - vm.reset(); - vm.setBytecode(bytecode25); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 0))); + std::vector> models; + std::vector> targets; + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + for (int i = 0; i < targets.size(); i++) { + auto target = targets[i]; + auto model = models[i]; + model->penState().color = 78.6; + model->penState().transparency = 100 * (1 - 150 / 255.0); + + VirtualMachine vm(target.get(), &m_engineMock, nullptr); + vm.setBytecode(bytecode1); + vm.setFunctions(functions); + vm.setConstValues(constValues); + + // color + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(191, 255, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode2); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(234, 255, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode3); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 150))); + + // saturation + model->penState().saturation = 32.4; + vm.reset(); + vm.setBytecode(bytecode4); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 135, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode5); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 0, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode6); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 150))); + + // brightness + model->penState().brightness = 12.5; + vm.reset(); + vm.setBytecode(bytecode7); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 135, 150))); + + vm.reset(); + vm.setBytecode(bytecode8); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 0, 150))); + + vm.reset(); + vm.setBytecode(bytecode9); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 150))); + + // transparency + model->penState().transparency = 12.5; + vm.reset(); + vm.setBytecode(bytecode10); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 119))); + + vm.reset(); + vm.setBytecode(bytecode11); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 255))); + + vm.reset(); + vm.setBytecode(bytecode12); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 0))); + + // invalid parameter + vm.reset(); + vm.setBytecode(bytecode13); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 0))); + + // color (optimized) + model->penState() = PenState(); + model->penState().color = 78.6; + model->penState().transparency = 100 * (1 - 150 / 255.0); + vm.reset(); + vm.setBytecode(bytecode14); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(191, 255, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode15); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(234, 255, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode16); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 150))); + + // saturation (optimized) + model->penState().saturation = 32.4; + vm.reset(); + vm.setBytecode(bytecode17); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 135, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode18); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 0, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode19); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 150))); + + // brightness (optimized) + model->penState().brightness = 12.5; + vm.reset(); + vm.setBytecode(bytecode20); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 135, 150))); + + vm.reset(); + vm.setBytecode(bytecode21); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 0, 150))); + + vm.reset(); + vm.setBytecode(bytecode22); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 150))); + + // transparency (optimized) + model->penState().transparency = 12.5; + vm.reset(); + vm.setBytecode(bytecode23); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 119))); + + vm.reset(); + vm.setBytecode(bytecode24); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 255))); + + vm.reset(); + vm.setBytecode(bytecode25); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(313, 255, 255, 0))); + } } TEST_F(PenBlocksTest, ChangePenSizeBy) @@ -966,39 +1026,51 @@ TEST_F(PenBlocksTest, ChangePenSizeByImpl) static BlockFunc functions[] = { &PenBlocks::changePenSizeBy }; static Value constValues[] = { 511.5, -650.08 }; - SpriteModel model; - Sprite sprite; - sprite.setInterface(&model); - - VirtualMachine vm(&sprite, &m_engineMock, nullptr); - vm.setBytecode(bytecode1); - vm.setFunctions(functions); - vm.setConstValues(constValues); - - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().diameter, 512.5); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().diameter, 1024); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().diameter, 1200); - - vm.reset(); - vm.setBytecode(bytecode2); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().diameter, 549.92); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().diameter, 1); + std::vector> models; + std::vector> targets; + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + for (int i = 0; i < targets.size(); i++) { + auto target = targets[i]; + auto model = models[i]; + + VirtualMachine vm(target.get(), &m_engineMock, nullptr); + vm.setBytecode(bytecode1); + vm.setFunctions(functions); + vm.setConstValues(constValues); + + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().diameter, 512.5); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().diameter, 1024); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().diameter, 1200); + + vm.reset(); + vm.setBytecode(bytecode2); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().diameter, 549.92); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().diameter, 1); + } } TEST_F(PenBlocksTest, SetPenSizeTo) @@ -1040,30 +1112,42 @@ TEST_F(PenBlocksTest, SetPenSizeToImpl) static BlockFunc functions[] = { &PenBlocks::setPenSizeTo }; static Value constValues[] = { 511.5, -650.08, 1500 }; - SpriteModel model; - Sprite sprite; - sprite.setInterface(&model); - - VirtualMachine vm(&sprite, &m_engineMock, nullptr); - vm.setBytecode(bytecode1); - vm.setFunctions(functions); - vm.setConstValues(constValues); - - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().diameter, 511.5); - - vm.reset(); - vm.setBytecode(bytecode2); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().diameter, 1); - - vm.reset(); - vm.setBytecode(bytecode3); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().diameter, 1200); + std::vector> models; + std::vector> targets; + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + for (int i = 0; i < targets.size(); i++) { + auto target = targets[i]; + auto model = models[i]; + + VirtualMachine vm(target.get(), &m_engineMock, nullptr); + vm.setBytecode(bytecode1); + vm.setFunctions(functions); + vm.setConstValues(constValues); + + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().diameter, 511.5); + + vm.reset(); + vm.setBytecode(bytecode2); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().diameter, 1); + + vm.reset(); + vm.setBytecode(bytecode3); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().diameter, 1200); + } } TEST_F(PenBlocksTest, ChangePenShadeBy) @@ -1104,40 +1188,52 @@ TEST_F(PenBlocksTest, ChangePenShadeByImpl) static BlockFunc functions[] = { &PenBlocks::changePenShadeBy }; static Value constValues[] = { 134.09, -124.45 }; - SpriteModel model; - model.penState().transparency = 100 * (1 - 150 / 255.0); - Sprite sprite; - sprite.setInterface(&model); - - VirtualMachine vm(&sprite, &m_engineMock, nullptr); - vm.setBytecode(bytecode1); - vm.setFunctions(functions); - vm.setConstValues(constValues); - - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 255, 110, 150))); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 119, 255, 150))); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 247, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode2); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 162, 255, 150))); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 255, 55, 150))); + std::vector> models; + std::vector> targets; + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + for (int i = 0; i < targets.size(); i++) { + auto target = targets[i]; + auto model = models[i]; + model->penState().transparency = 100 * (1 - 150 / 255.0); + + VirtualMachine vm(target.get(), &m_engineMock, nullptr); + vm.setBytecode(bytecode1); + vm.setFunctions(functions); + vm.setConstValues(constValues); + + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 255, 110, 150))); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 119, 255, 150))); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 247, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode2); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 162, 255, 150))); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 255, 55, 150))); + } } TEST_F(PenBlocksTest, SetPenShadeToNumber) @@ -1179,31 +1275,43 @@ TEST_F(PenBlocksTest, SetPenShadeToNumberImpl) static BlockFunc functions[] = { &PenBlocks::setPenShadeToNumber }; static Value constValues[] = { 125.7, -114.09, 489.4 }; - SpriteModel model; - model.penState().transparency = 100 * (1 - 150 / 255.0); - Sprite sprite; - sprite.setInterface(&model); - - VirtualMachine vm(&sprite, &m_engineMock, nullptr); - vm.setBytecode(bytecode1); - vm.setFunctions(functions); - vm.setConstValues(constValues); - - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 148, 253, 150))); - - vm.reset(); - vm.setBytecode(bytecode2); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 102, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode3); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 89, 255, 150))); + std::vector> models; + std::vector> targets; + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + for (int i = 0; i < targets.size(); i++) { + auto target = targets[i]; + auto model = models[i]; + model->penState().transparency = 100 * (1 - 150 / 255.0); + + VirtualMachine vm(target.get(), &m_engineMock, nullptr); + vm.setBytecode(bytecode1); + vm.setFunctions(functions); + vm.setConstValues(constValues); + + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 148, 253, 150))); + + vm.reset(); + vm.setBytecode(bytecode2); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 102, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode3); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(240, 89, 255, 150))); + } } TEST_F(PenBlocksTest, ChangePenHueBy) @@ -1244,40 +1352,52 @@ TEST_F(PenBlocksTest, ChangePenHueByImpl) static BlockFunc functions[] = { &PenBlocks::changePenHueBy }; static Value constValues[] = { 125.7, -114.09 }; - SpriteModel model; - model.penState().transparency = 100 * (1 - 150 / 255.0); - Sprite sprite; - sprite.setInterface(&model); - - VirtualMachine vm(&sprite, &m_engineMock, nullptr); - vm.setBytecode(bytecode1); - vm.setFunctions(functions); - vm.setConstValues(constValues); - - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(106, 255, 255, 150))); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(332, 255, 255, 150))); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(199, 255, 255, 150))); - - vm.reset(); - vm.setBytecode(bytecode2); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(353, 255, 255, 150))); - - vm.reset(); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(148, 255, 255, 150))); + std::vector> models; + std::vector> targets; + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + for (int i = 0; i < targets.size(); i++) { + auto target = targets[i]; + auto model = models[i]; + model->penState().transparency = 100 * (1 - 150 / 255.0); + + VirtualMachine vm(target.get(), &m_engineMock, nullptr); + vm.setBytecode(bytecode1); + vm.setFunctions(functions); + vm.setConstValues(constValues); + + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(106, 255, 255, 150))); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(332, 255, 255, 150))); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(199, 255, 255, 150))); + + vm.reset(); + vm.setBytecode(bytecode2); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(353, 255, 255, 150))); + + vm.reset(); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(148, 255, 255, 150))); + } } TEST_F(PenBlocksTest, SetPenHueToNumber) @@ -1319,29 +1439,41 @@ TEST_F(PenBlocksTest, SetPenHueToNumberImpl) static BlockFunc functions[] = { &PenBlocks::setPenHueToNumber }; static Value constValues[] = { 125.7, -114.09, 489.4 }; - SpriteModel model; - model.penState().transparency = 100 * (1 - 150 / 255.0); - Sprite sprite; - sprite.setInterface(&model); - - VirtualMachine vm(&sprite, &m_engineMock, nullptr); - vm.setBytecode(bytecode1); - vm.setFunctions(functions); - vm.setConstValues(constValues); - - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(226, 255, 255, 255))); - - vm.reset(); - vm.setBytecode(bytecode2); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(154, 255, 255, 255))); - - vm.reset(); - vm.setBytecode(bytecode3); - vm.run(); - ASSERT_EQ(vm.registerCount(), 0); - ASSERT_EQ(model.penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(160, 255, 255, 255))); + std::vector> models; + std::vector> targets; + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + models.push_back(std::make_shared()); + targets.push_back(std::make_shared()); + static_cast(targets.back().get())->setInterface(static_cast(models.back().get())); + + for (int i = 0; i < targets.size(); i++) { + auto target = targets[i]; + auto model = models[i]; + model->penState().transparency = 100 * (1 - 150 / 255.0); + + VirtualMachine vm(target.get(), &m_engineMock, nullptr); + vm.setBytecode(bytecode1); + vm.setFunctions(functions); + vm.setConstValues(constValues); + + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(226, 255, 255, 255))); + + vm.reset(); + vm.setBytecode(bytecode2); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(154, 255, 255, 255))); + + vm.reset(); + vm.setBytecode(bytecode3); + vm.run(); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_EQ(model->penAttributes().color, QNanoColor::fromQColor(QColor::fromHsv(160, 255, 255, 255))); + } }