Skip to content

Commit 8718296

Browse files
committed
Add a way to change monitor values
1 parent 30adc15 commit 8718296

File tree

4 files changed

+61
-1
lines changed

4 files changed

+61
-1
lines changed

include/scratchcpp/monitor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ class LIBSCRATCHCPP_EXPORT Monitor : public Entity
5656

5757
void updateValue(const VirtualMachine *vm);
5858

59+
void setValueChangeFunction(MonitorChangeFunc f);
60+
void changeValue(const Value &newValue);
61+
5962
unsigned int width() const;
6063
void setWidth(unsigned int width);
6164

src/scratch/monitor.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,32 @@ void Monitor::updateValue(const VirtualMachine *vm)
108108
impl->iface->onValueChanged(vm);
109109
}
110110

111+
/*!
112+
* Sets the function which is called to change the monitor's value.
113+
* \see changeValue()
114+
*/
115+
void Monitor::setValueChangeFunction(MonitorChangeFunc f)
116+
{
117+
impl->changeFunc = f;
118+
}
119+
120+
/*!
121+
* Calls the monitor's value update function. For example a variable
122+
* monitor's function sets the value of the monitored variable.
123+
* \note This doesn't work with list monitors.
124+
*/
125+
void Monitor::changeValue(const Value &newValue)
126+
{
127+
if (impl->changeFunc)
128+
impl->changeFunc(impl->block.get(), newValue);
129+
130+
if (impl->iface) {
131+
impl->changeValueVM.reset();
132+
impl->changeValueVM.addReturnValue(newValue);
133+
impl->iface->onValueChanged(&impl->changeValueVM);
134+
}
135+
}
136+
111137
/*! Returns the monitor's width. */
112138
unsigned int Monitor::width() const
113139
{

src/scratch/monitor_p.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#pragma once
44

55
#include <scratchcpp/monitor.h>
6-
#include <scratchcpp/script.h>
6+
#include <scratchcpp/virtualmachine.h>
77

88
namespace libscratchcpp
99
{
@@ -22,6 +22,8 @@ struct MonitorPrivate
2222
std::shared_ptr<Script> script;
2323
std::shared_ptr<IBlockSection> blockSection;
2424
std::shared_ptr<Block> block; // Compiler needs shared_ptr
25+
MonitorChangeFunc changeFunc;
26+
VirtualMachine changeValueVM;
2527
unsigned int width = 0;
2628
unsigned int height = 0;
2729
int x = 0;

test/scratch_classes/monitor_test.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <scratchcpp/sprite.h>
44
#include <scratchcpp/rect.h>
55
#include <scratchcpp/virtualmachine.h>
6+
#include <scratchcpp/script.h>
67
#include <scratch/monitor_p.h>
78
#include <monitorhandlermock.h>
89
#include <randomgeneratormock.h>
@@ -12,6 +13,8 @@
1213
using namespace libscratchcpp;
1314

1415
using ::testing::Return;
16+
using ::testing::SaveArg;
17+
using ::testing::_;
1518

1619
static const int PADDING = 5;
1720
static const int SCREEN_WIDTH = 400;
@@ -110,6 +113,32 @@ TEST(MonitorTest, UpdateValue)
110113
monitor.updateValue(&vm2);
111114
}
112115

116+
TEST(MonitorTest, ChangeValue)
117+
{
118+
Monitor monitor("", "test_block");
119+
monitor.changeValue(6.2);
120+
121+
MonitorHandlerMock handler;
122+
EXPECT_CALL(handler, init);
123+
monitor.setInterface(&handler);
124+
125+
const VirtualMachine *vm = nullptr;
126+
EXPECT_CALL(handler, onValueChanged(_)).WillOnce(SaveArg<0>(&vm));
127+
monitor.changeValue(0.25);
128+
ASSERT_TRUE(vm);
129+
ASSERT_EQ(vm->registerCount(), 1);
130+
ASSERT_EQ(vm->getInput(0, 1)->toDouble(), 0.25);
131+
132+
monitor.setValueChangeFunction([](Block *block, const Value &newValue) { std::cout << block->opcode() + " " + newValue.toString() << std::endl; });
133+
EXPECT_CALL(handler, onValueChanged(_)).WillOnce(SaveArg<0>(&vm));
134+
testing::internal::CaptureStdout();
135+
monitor.changeValue("test");
136+
ASSERT_TRUE(vm);
137+
ASSERT_EQ(vm->registerCount(), 1);
138+
ASSERT_EQ(vm->getInput(0, 1)->toString(), "test");
139+
ASSERT_EQ(testing::internal::GetCapturedStdout(), "test_block test\n");
140+
}
141+
113142
TEST(MonitorTest, Width)
114143
{
115144
Monitor monitor("", "");

0 commit comments

Comments
 (0)