Skip to content

Commit e98718e

Browse files
authored
Merge pull request #577 from scratchcpp/thread_class
Add Thread class
2 parents 9481957 + d361850 commit e98718e

32 files changed

+732
-504
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ target_sources(scratchcpp
3232
include/scratchcpp/iengine.h
3333
include/scratchcpp/iextension.h
3434
include/scratchcpp/iblocksection.h
35+
include/scratchcpp/thread.h
3536
include/scratchcpp/asset.h
3637
include/scratchcpp/costume.h
3738
include/scratchcpp/sound.h

include/scratchcpp/iengine.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class Stage;
2323
class Variable;
2424
class List;
2525
class Script;
26+
class Thread;
2627
class ITimer;
2728
class KeyEvent;
2829
class Monitor;
@@ -58,26 +59,26 @@ class LIBSCRATCHCPP_EXPORT IEngine
5859
virtual void stop() = 0;
5960

6061
/*! Starts a script with the given top level block as the given Target (a sprite or the stage). */
61-
virtual VirtualMachine *startScript(std::shared_ptr<Block> topLevelBlock, Target *) = 0;
62+
virtual Thread *startScript(std::shared_ptr<Block> topLevelBlock, Target *) = 0;
6263

6364
/*! Starts the scripts of the broadcast with the given index. */
64-
virtual void broadcast(int index, VirtualMachine *sender) = 0;
65+
virtual void broadcast(int index, Thread *sender) = 0;
6566

6667
/*! Starts the scripts of the given broadcast. */
67-
virtual void broadcastByPtr(Broadcast *broadcast, VirtualMachine *sender) = 0;
68+
virtual void broadcastByPtr(Broadcast *broadcast, Thread *sender) = 0;
6869

6970
/*! Starts the "when backdrop switches to" scripts for the given backdrop broadcast. */
70-
virtual void startBackdropScripts(Broadcast *broadcast, VirtualMachine *sender) = 0;
71+
virtual void startBackdropScripts(Broadcast *broadcast, Thread *sender) = 0;
7172

7273
/*! Stops the given script. */
73-
virtual void stopScript(VirtualMachine *vm) = 0;
74+
virtual void stopScript(Thread *vm) = 0;
7475

7576
/*!
7677
* Stops all scripts in the given target.
7778
* \param[in] target The Target to stop.
7879
* \param[in] exceptScript Sets this parameter to stop all scripts except the given script.
7980
*/
80-
virtual void stopTarget(Target *target, VirtualMachine *exceptScript) = 0;
81+
virtual void stopTarget(Target *target, Thread *exceptScript) = 0;
8182

8283
/*! Calls the "when I start as a clone" blocks of the given sprite. */
8384
virtual void initClone(std::shared_ptr<Sprite> clone) = 0;
@@ -121,7 +122,7 @@ class LIBSCRATCHCPP_EXPORT IEngine
121122
virtual sigslot::signal<> &aboutToRender() = 0;
122123

123124
/*! Emits when a script is about to stop. */
124-
virtual sigslot::signal<VirtualMachine *> &threadAboutToStop() = 0;
125+
virtual sigslot::signal<Thread *> &threadAboutToStop() = 0;
125126

126127
/*! Emits when the project is stopped by calling stop(). */
127128
virtual sigslot::signal<> &stopped() = 0;

include/scratchcpp/script.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Target;
1515
class Block;
1616
class IEngine;
1717
class Value;
18-
class VirtualMachine;
18+
class Thread;
1919
class Variable;
2020
class List;
2121
class ScriptPrivate;
@@ -42,8 +42,8 @@ class LIBSCRATCHCPP_EXPORT Script
4242
void setVariables(const std::vector<Variable *> &variables);
4343
void setLists(const std::vector<List *> &lists);
4444

45-
std::shared_ptr<VirtualMachine> start();
46-
std::shared_ptr<VirtualMachine> start(Target *target);
45+
std::shared_ptr<Thread> start();
46+
std::shared_ptr<Thread> start(Target *target);
4747

4848
private:
4949
BlockFunc *getFunctions() const;

include/scratchcpp/thread.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#pragma once
4+
5+
#include "global.h"
6+
#include "spimpl.h"
7+
8+
namespace libscratchcpp
9+
{
10+
11+
class VirtualMachine;
12+
class Target;
13+
class IEngine;
14+
class Script;
15+
class ThreadPrivate;
16+
17+
/*! \brief The Thread class represents a running Scratch script. */
18+
class LIBSCRATCHCPP_EXPORT Thread
19+
{
20+
public:
21+
Thread(Target *target, IEngine *engine, Script *script);
22+
Thread(const Thread &) = delete;
23+
24+
VirtualMachine *vm() const;
25+
Target *target() const;
26+
IEngine *engine() const;
27+
Script *script() const;
28+
29+
void run();
30+
void kill();
31+
void reset();
32+
33+
bool isFinished() const;
34+
35+
void promise();
36+
void resolvePromise();
37+
38+
private:
39+
spimpl::unique_impl_ptr<ThreadPrivate> impl;
40+
};
41+
42+
} // namespace libscratchcpp

include/scratchcpp/virtualmachine.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,15 @@ enum Opcode
8888
class Target;
8989
class IEngine;
9090
class Script;
91+
class Thread;
9192
class List;
9293

9394
/*! \brief The VirtualMachine class is a virtual machine for compiled Scratch scripts. */
9495
class LIBSCRATCHCPP_EXPORT VirtualMachine
9596
{
9697
public:
9798
VirtualMachine();
98-
VirtualMachine(Target *target, IEngine *engine, Script *script);
99+
VirtualMachine(Target *target, IEngine *engine, Script *script, Thread *thread = nullptr);
99100
VirtualMachine(const VirtualMachine &) = delete;
100101

101102
void setProcedures(unsigned int **procedures);
@@ -121,6 +122,7 @@ class LIBSCRATCHCPP_EXPORT VirtualMachine
121122
Target *target() const;
122123
IEngine *engine() const;
123124
Script *script() const;
125+
Thread *thread() const;
124126

125127
const Value *getInput(unsigned int index, unsigned int argCount) const;
126128

src/blocks/controlblocks.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ unsigned int ControlBlocks::stopAll(VirtualMachine *vm)
204204

205205
unsigned int ControlBlocks::stopOtherScriptsInSprite(VirtualMachine *vm)
206206
{
207-
vm->engine()->stopTarget(vm->target(), vm);
207+
vm->engine()->stopTarget(vm->target(), vm->thread());
208208
return 0;
209209
}
210210

src/blocks/eventblocks.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ unsigned int EventBlocks::broadcast(VirtualMachine *vm)
181181
std::vector<int> broadcasts = vm->engine()->findBroadcasts(vm->getInput(0, 1)->toString());
182182

183183
for (int index : broadcasts)
184-
vm->engine()->broadcast(index, vm);
184+
vm->engine()->broadcast(index, vm->thread());
185185

186186
return 1;
187187
}
@@ -191,7 +191,7 @@ unsigned int EventBlocks::broadcastAndWait(VirtualMachine *vm)
191191
std::vector<int> broadcasts = vm->engine()->findBroadcasts(vm->getInput(0, 1)->toString());
192192

193193
for (int index : broadcasts)
194-
vm->engine()->broadcast(index, vm);
194+
vm->engine()->broadcast(index, vm->thread());
195195

196196
vm->promise();
197197

src/blocks/looksblocks.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <scratchcpp/iengine.h>
44
#include <scratchcpp/compiler.h>
5+
#include <scratchcpp/thread.h>
56
#include <scratchcpp/sprite.h>
67
#include <scratchcpp/stage.h>
78
#include <scratchcpp/input.h>
@@ -99,9 +100,9 @@ void LooksBlocks::registerBlocks(IEngine *engine)
99100

100101
void LooksBlocks::onInit(IEngine *engine)
101102
{
102-
engine->threadAboutToStop().connect([](VirtualMachine *vm) {
103-
m_timeMap.erase(vm);
104-
erase_if(m_waitingBubbles, [vm](const std::pair<Target *, VirtualMachine *> &pair) { return pair.second == vm; });
103+
engine->threadAboutToStop().connect([](Thread *thread) {
104+
m_timeMap.erase(thread->vm());
105+
erase_if(m_waitingBubbles, [thread](const std::pair<Target *, VirtualMachine *> &pair) { return pair.second == thread->vm(); });
105106
});
106107

107108
engine->stopped().connect([engine]() {
@@ -892,7 +893,7 @@ void LooksBlocks::startBackdropScripts(VirtualMachine *vm, bool wait)
892893
{
893894
if (Stage *stage = vm->engine()->stage()) {
894895
if (stage->costumes().size() > 0)
895-
vm->engine()->startBackdropScripts(stage->currentCostume()->broadcast(), vm);
896+
vm->engine()->startBackdropScripts(stage->currentCostume()->broadcast(), vm->thread());
896897
}
897898
}
898899

src/blocks/motionblocks.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <scratchcpp/iengine.h>
44
#include <scratchcpp/compiler.h>
5+
#include <scratchcpp/thread.h>
56
#include <scratchcpp/sprite.h>
67
#include <scratchcpp/input.h>
78
#include <scratchcpp/field.h>
@@ -73,9 +74,9 @@ void MotionBlocks::registerBlocks(IEngine *engine)
7374

7475
void MotionBlocks::onInit(IEngine *engine)
7576
{
76-
engine->threadAboutToStop().connect([](VirtualMachine *vm) {
77-
m_timeMap.erase(vm);
78-
m_glideMap.erase(vm);
77+
engine->threadAboutToStop().connect([](Thread *thread) {
78+
m_timeMap.erase(thread->vm());
79+
m_glideMap.erase(thread->vm());
7980
});
8081
}
8182

src/blocks/sensingblocks.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: Apache-2.0
22

33
#include <scratchcpp/virtualmachine.h>
4+
#include <scratchcpp/thread.h>
45
#include <scratchcpp/compiler.h>
56
#include <scratchcpp/iengine.h>
67
#include <scratchcpp/itimer.h>
@@ -99,16 +100,17 @@ void SensingBlocks::registerBlocks(IEngine *engine)
99100

100101
void SensingBlocks::onInit(IEngine *engine)
101102
{
102-
engine->threadAboutToStop().connect([engine](VirtualMachine *thread) {
103+
engine->threadAboutToStop().connect([engine](Thread *thread) {
103104
if (!m_questionList.empty()) {
104105
// Abort the question of this thread if it's currently being displayed
105-
if (m_questionList.front()->vm == thread) {
106+
if (m_questionList.front()->vm == thread->vm()) {
106107
thread->target()->setBubbleText("");
107108
engine->questionAborted()();
108109
}
109110

110-
m_questionList
111-
.erase(std::remove_if(m_questionList.begin(), m_questionList.end(), [thread](const std::unique_ptr<Question> &question) { return question->vm == thread; }), m_questionList.end());
111+
m_questionList.erase(
112+
std::remove_if(m_questionList.begin(), m_questionList.end(), [thread](const std::unique_ptr<Question> &question) { return question->vm == thread->vm(); }),
113+
m_questionList.end());
112114
}
113115
});
114116
}

0 commit comments

Comments
 (0)