Skip to content

Commit aeb022c

Browse files
committed
Update docs
1 parent 53bb465 commit aeb022c

File tree

4 files changed

+136
-205
lines changed

4 files changed

+136
-205
lines changed

docs/Block sections.md

Lines changed: 0 additions & 158 deletions
This file was deleted.

docs/Extensions.md

Lines changed: 134 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,152 @@
11
\page extensions Extensions
22

3-
An extension is a group of block sections (see [Block sections](blockSections.html)).
3+
An extension is a group of Scratch blocks, for example motion blocks.
44

55
## Creating an extension
66
To create a custom extension, subclass \link libscratchcpp::IExtension IExtension \endlink and override
77
\link libscratchcpp::IExtension::name() name() \endlink and \link libscratchcpp::IExtension::description() description() \endlink
8-
functions to return the name and the description of the extension.
9-
10-
There's also an \link libscratchcpp::IExtension::includeByDefault() includeByDefault() \endlink function which returns `true`
11-
if the extension is intended to be hidden from the block palette and included in a Scratch project by default.
12-
13-
The default implementation returns `false`.
8+
functions to return the name and the description of the extension. Then override \link libscratchcpp::IExtension::registerBlocks() registerBlocks() \endlink
9+
where you'll register the compile functions for blocks.
1410

1511
It's recommended to use the libscratchcpp namespace like this in your extension class:
1612
```cpp
1713
using namespace libscratchcpp;
1814
```
1915

20-
### Registering block sections
21-
Block sections can be registered by overriding the \link libscratchcpp::IExtension::registerSections() registerSections() \endlink function:
16+
### Adding blocks
17+
See the [Scratch Wiki](https://en.scratch-wiki.info/wiki/Scratch_File_Format#Blocks) for more information about blocks.
18+
19+
Scratch projects are compiled by the \link libscratchcpp::Compiler Compiler \endlink class.
20+
To add a block, you have to let the compiler know how to compile it.
21+
Start by defining a **compile function**.
22+
For example, the compile function for a `hello world` block would look like this:
23+
```cpp
24+
class MyExtension : public IExtension {
25+
public:
26+
...
27+
static void compileHelloWorld(Compiler *compiler);
28+
static unsigned int helloWorld(VirtualMachine *vm);
29+
};
30+
31+
void MySection::compileHelloWorld(Compiler *compiler) {
32+
compiler->addFunctionCall(&helloWorld);
33+
}
34+
35+
unsigned int MySection::helloWorld(VirtualMachine *vm) {
36+
std::cout << "Hello, world!" << std::endl;
37+
return 0;
38+
}
39+
```
40+
\note Make sure the functions are **static**.
41+
42+
Register the compile function using the \link libscratchcpp::IEngine::addCompileFunction() addCompileFunction() \endlink method in link libscratchcpp::IExtension::registerBlocks() registerBlocks() \endlink:
43+
```cpp
44+
MyExtension::registerBlocks(IEngine *engine) {
45+
engine->addCompileFunction(this, "myextension_helloworld", &MySection::compileHelloWorld);
46+
}
47+
```
48+
Where `myextension_helloworld` is the opcode of the `hello world` block.
49+
50+
### Adding inputs
51+
To add inputs, create an `Inputs` enumeration in your extension:
52+
```hpp
53+
class MyExtension : public IExtension {
54+
enum Inputs {
55+
TEXT
56+
};
57+
...
58+
};
59+
```
60+
Then add inputs in link libscratchcpp::IExtension::registerBlocks() registerBlocks() \endlink:
61+
```cpp
62+
MyExtension::registerBlocks(IEngine *engine) {
63+
...
64+
engine->addInput(this, "TEXT", TEXT);
65+
}
66+
```
67+
The compiler will assign the input name with the `TEXT` ID. In this case, the ID is 0 because it's the first member of the enumeration.
68+
69+
To add the input to the compiled code, call the \link libscratchcpp::Compiler::addInput() addInput() \endlink function:
70+
```cpp
71+
void MyExtension::compileHelloWorld(Compiler *compiler) {
72+
compiler->addInput(TEXT);
73+
compiler->addFunctionCall(&helloWorld);
74+
}
75+
```
76+
77+
The value of the input can be read during runtime using the \link libscratchcpp::VirtualMachine::getInput() getInput() \endlink function:
78+
```cpp
79+
unsigned int MyExtension::helloWorld(VirtualMachine *vm) {
80+
std::cout << "Hello, " << vm->getInput(0, 1)->toString() << "!" << std::endl;
81+
return 1;
82+
}
83+
```
84+
\note The order of the inputs is the same as in the compile function. Do not use the `Inputs` enumeration in runtime functions.
85+
86+
```cpp
87+
vm->getInput(0, 1)
88+
```
89+
The first argument is the index of the input and the second argument is the amount of inputs.
90+
\note Make sure to return the amount of inputs in the `helloWorld` function.
91+
92+
### Adding fields
93+
**Fields** are drop-down menus into which one cannot drop a reporter.
94+
Fields have a predefined set of values.
95+
```cpp
96+
class MyExtension : public IExtension {
97+
...
98+
enum Fields {
99+
ANIMAL
100+
};
101+
102+
enum FieldValues {
103+
Cat,
104+
Dog
105+
};
106+
...
107+
};
108+
109+
MyExtension::registerBlocks(IEngine *engine) {
110+
...
111+
engine->addField(this, "ANIMAL", ANIMAL);
112+
engine->addFieldValue(this, "Cat", Cat);
113+
engine->addFieldValue(this, "Dog", Dog);
114+
}
115+
```
116+
117+
Because fields are handled at compile time, you can read them from the compile function:
22118
```cpp
23-
void MyExtension::registerSections(IEngine *engine) {
24-
engine->registerSection(std::make_shared<MySection>());
119+
void MyExtension::compileHelloWorld(Compiler *compiler) {
120+
int id = compiler->field(ANIMAL)->specialValueId();
121+
122+
switch(id) {
123+
case Cat:
124+
compiler->addFunctionCall(&helloCat);
125+
break;
126+
127+
case Dog:
128+
compiler->addFunctionCall(&helloDog);
129+
break;
130+
131+
default:
132+
break;
133+
}
134+
}
135+
136+
unsigned int MySection::helloCat(VirtualMachine *vm) {
137+
std::cout << "Hello, cat!" << std::endl;
138+
return 0;
139+
}
140+
141+
unsigned int MySection::helloDog(VirtualMachine *vm) {
142+
std::cout << "Hello, dog!" << std::endl;
143+
return 0;
25144
}
26145
```
27-
See the [Block sections](blockSections.html) page for instructions on how to create a block section.
146+
\note Don't confuse \link libscratchcpp::Field::specialValueId() specialValueId() \endlink with \link libscratchcpp::Field::valueId() valueId() \endlink
147+
because \link libscratchcpp::Field::valueId() valueId() \endlink stores the ID of the block, variable, list or broadcast selected in the dropdown list.
148+
149+
To get a pointer to the block, variable, list or broadcast selected in the dropdown list, use \link libscratchcpp::Field::valuePtr() valuePtr() \endlink.
28150
29151
### Registering the extension
30152
Register the extension **before** loading a project, using the \link libscratchcpp::ScratchConfiguration ScratchConfiguration \endlink class:

docs/Getting started.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,5 @@ int main(int argc, char **argv) {
2424
The \link libscratchcpp::Project::run() run() \endlink method runs an event loop which stops after all scripts finish.
2525
2626
For CLI project players, using \link libscratchcpp::Project::run() run() \endlink is enough. If you are developing
27-
a GUI project player and need to receive input events such as key presses, you'll need to use \link libscratchcpp::Project::runEventLoop() runEventLoop() \endlink
28-
and run it in another thread (to keep the UI responsive).
27+
a GUI project player and need to receive input events such as key presses, you'll need to use \link libscratchcpp::IEngine::step() step() \endlink
28+
for ticks and \link libscratchcpp::Project::start() start() \endlink and \link libscratchcpp::Project::stop() stop() \endlink

docs/Image formats.md

Lines changed: 0 additions & 33 deletions
This file was deleted.

0 commit comments

Comments
 (0)