@@ -16,34 +16,39 @@ using namespace libscratchcpp;
1616### Adding blocks
1717See 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
2224class 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
3944MySection::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
4853class 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
10196class 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
111109MySection::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
131145because \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
134150Block sections are registered in the \link libscratchcpp::IExtension::registerSections() registerSections() \endlink
135151function of an extension:
0 commit comments