Skip to content

Commit 56f740a

Browse files
committed
Update block section docs
1 parent 42752e3 commit 56f740a

File tree

1 file changed

+70
-54
lines changed

1 file changed

+70
-54
lines changed

docs/Block sections.md

Lines changed: 70 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,39 @@ using namespace libscratchcpp;
1616
### Adding blocks
1717
See the [Scratch Wiki](https://en.scratch-wiki.info/wiki/Scratch_File_Format#Blocks) for more information about blocks.
1818

19-
To add a block, create a block implementation function.
20-
For example, a `print` block would look like this:
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:
2123
```cpp
2224
class MySection : public IBlockSection {
2325
public:
2426
...
25-
static Value print(const BlockArgs &args);
27+
static void compileHelloWorld(Compiler *compiler);
28+
static unsigned int helloWorld(VirtualMachine *vm);
2629
};
2730

28-
Value MySection::print(const BlockArgs &args) {
29-
std::cout << args.input("TEXT").value().toStdString() << std::endl;
30-
return Value();
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;
3138
}
3239
```
33-
\note You shouldn't find inputs by name because it affects performance. See the "Adding inputs" section below for more information.
34-
\par
35-
\note Make sure the function is **static**.
40+
\note Make sure the functions are **static**.
3641
37-
Register the block using the \link libscratchcpp::IBlockSection::addBlock() addBlock() \endlink method in the constructor:
42+
Register the compile function using the \link libscratchcpp::IBlockSection::addCompileFunction() addCompileFunction() \endlink method in the constructor:
3843
```cpp
3944
MySection::MySection() {
40-
addBlock("mysection_print", &MySection::print);
45+
addCompileFunction("mysection_helloworld", &MySection::compileHelloWorld);
4146
}
4247
```
43-
Where `mysection_print` is the opcode of the `print` block.
48+
Where `mysection_helloworld` is the opcode of the `hello world` block.
4449

4550
### Adding inputs
46-
To add inputs, create an Inputs enumeration in your block section:
51+
To add inputs, create an `Inputs` enumeration in your block section:
4752
```hpp
4853
class MySection : public IBlockSection {
4954
enum Inputs {
@@ -59,77 +64,88 @@ MySection::MySection() {
5964
addInput("TEXT", TEXT);
6065
}
6166
```
62-
The compiler will assign the input with the `TEXT` ID. In this case, the ID is 0 because it's the first member of the enumeration.
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.
6368

64-
To use the input, get it using the \link libscratchcpp::BlockArgs::input() input() \endlink function in the block implementation:
69+
To add the input to the compiled code, call the \link libscratchcpp::Compiler::addInput() addInput() \endlink function:
6570
```cpp
66-
Value MySection::print(const BlockArgs &args) {
67-
std::cout << args.input(TEXT).value().toStdString() << std::endl;
68-
return Value();
71+
void MySection::compileHelloWorld(Compiler *compiler) {
72+
compiler->addInput(TEXT);
73+
compiler->addFunctionCall(&helloWorld);
6974
}
7075
```
71-
This improves performance because the input is no longer being found by its name, but only by an integer.
7276
73-
### Adding fields
74-
Fields can be added using the same way as inputs:
77+
The value of the input can be read during runtime using the \link libscratchcpp::VirtualMachine::getArg() getArg() \endlink function:
7578
```cpp
76-
class MySection : public IBlockSection {
77-
...
78-
enum Fields {
79-
SOME_MENU
80-
};
81-
...
82-
};
83-
84-
MySection::MySection() {
85-
...
86-
addField("SOME_MENU", SOME_MENU);
79+
unsigned int MySection::helloWorld(VirtualMachine *vm) {
80+
std::cout << "Hello, " << vm->getArg(0, 1)->toString() << "!" << std::endl;
81+
return 1;
8782
}
8883
```
89-
Get the value of the field using the \link libscratchcpp::BlockArgs::field() field() \endlink function:
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+
9086
```cpp
91-
Value MySection::someBlock(const BlockArgs &args) {
92-
std::cout << args.field(SOME_MENU).value().toStdString() << std::endl;
93-
return Value();
94-
}
87+
vm->getArg(0, 1)
9588
```
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.
9691
97-
### Adding field values
98-
If a field uses a predefined set of string values, for example rotation style `left-right`, `all around` and `don't rotate`,
99-
you can assign integer IDs to them to speed up the execution of scripts.
92+
### Adding fields
93+
**Fields** are drop-down menus into which one cannot drop a reporter.
94+
Fields have a predefined set of values.
10095
```cpp
10196
class MySection : public IBlockSection {
10297
...
98+
enum Fields {
99+
ANIMAL
100+
};
101+
103102
enum FieldValues {
104-
RotateLeftRight,
105-
RotateAllAround,
106-
DoNotRotate
103+
Cat,
104+
Dog
107105
};
108106
...
109107
};
110108
111109
MySection::MySection() {
112110
...
113-
addField("SOME_MENU", SOME_MENU);
114-
addFieldValue("left-right", RotateLeftRight);
115-
addFieldValue("all around", RotateAllAround);
116-
addFieldValue("don't rotate", DoNotRotate);
111+
addField("ANIMAL", ANIMAL);
117112
}
118113
```
119-
Use the \link libscratchcpp::Field::specialValueId() specialValueId() \endlink function to get the ID of the value:
114+
115+
Because fields are handled at compile time, you can read them from the compile function:
120116
```cpp
121-
Value MySection::someBlock(const BlockArgs &args) {
122-
switch(args.field(SOME_MENU)->specialValueId()) {
123-
case RotateLeftRight:
124-
...
125-
...
117+
void MySection::compileHelloWorld(Compiler *compiler) {
118+
int id = compiler->field(ANIMAL)->specialValueId();
119+
120+
switch(id) {
121+
case Cat:
122+
compiler->addFunctionCall(&helloCat);
123+
break;
124+
125+
case Dog:
126+
compiler->addFunctionCall(&helloDog);
127+
break;
128+
129+
default:
130+
break;
126131
}
127-
return Value();
132+
}
133+
134+
unsigned int MySection::helloCat(VirtualMachine *vm) {
135+
std::cout << "Hello, cat!" << std::endl;
136+
return 0;
137+
}
138+
139+
unsigned int MySection::helloDog(VirtualMachine *vm) {
140+
std::cout << "Hello, dog!" << std::endl;
141+
return 0;
128142
}
129143
```
130144
\note Don't confuse \link libscratchcpp::Field::specialValueId() specialValueId() \endlink with \link libscratchcpp::Field::valueId() valueId() \endlink
131145
because \link libscratchcpp::Field::valueId() valueId() \endlink stores the ID of the block, variable, list or broadcast selected in the dropdown list.
132146
147+
To get a pointer to the block, variable, list or broadcast selected in the dropdown list, use \link libscratchcpp::Field::valuePtr() valuePtr() \endlink.
148+
133149
### Registering the block section
134150
Block sections are registered in the \link libscratchcpp::IExtension::registerSections() registerSections() \endlink
135151
function of an extension:

0 commit comments

Comments
 (0)