Podczas projektowania aplikacji korzystającej z Blockly możesz wybrać jeden z kilku paradygmatów. Te wybory należy rozważyć na wczesnym etapie, ponieważ wpływają one na bloki, których użytkownik będzie potrzebować.
Konfiguracja
Wiele aplikacji Blockly służy do opisywania konfiguracji, a nie programów wykonywalnych. Aplikacje konfiguracyjne zwykle zaczynają od zainicjowania jednego bloku na poziomie głównym w obszarze roboczym. Dobrym przykładem jest karta Fabryka bloków w Narzędziach deweloperskich Blockly:
Blockly.Blocks['factory_base'] = {
init: function() {
this.setDeletable(false);
this.setMovable(false);
this.setEditable(false);
// etc...
}
}
Blockly.serialization.blocks.append({'type': 'factory_base'}, workspace);
Tworzy to nieusuwalny i nieprzenośny blok, który zawiera całą konfigurację użytkownika. Obszar roboczy można w dowolnym momencie serializować, aby określić bieżącą konfigurację.
Takie aplikacje mogą automatycznie wyłączać wszystkie bloki, które nie są połączone z blokiem głównym. Możesz to zrobić za pomocą jednego wiersza:
workspace.addChangeListener(Blockly.Events.disableOrphans);
Program seryjny
Większość aplikacji Blockly jest przeznaczona do tworzenia programów szeregowych. Użytkownicy układają bloki, które są wykonywane w określonej kolejności.
Każdy (niezablokowany) blok w obszarze roboczym będzie częścią programu. Jeśli jest kilka stosów bloków, najpierw wykonywane są te wyższe. (Jeśli 2 stosy mają w przybliżeniu tę samą wysokość, priorytet mają stosy po lewej stronie (po prawej w trybie RTL).
Obszar roboczy można w dowolnym momencie wyeksportować do kodu wykonywalnego. Ten kod może być wykonywany po stronie klienta w JavaScript (przy użyciu eval
lub interpretera JS) albo po stronie serwera w dowolnym języku.
import {javascriptGenerator} from 'blockly/javascript';
var code = javascriptGenerator.workspaceToCode(workspace);
Program równoległy
Niektóre aplikacje Blockly wykonują wszystkie stosy bloków równolegle, a nie po kolei. Przykładem może być aplikacja muzyczna, w której pętla perkusyjna jest odtwarzana równocześnie z melodią.
Jednym ze sposobów wdrożenia równoległego wykonywania jest wygenerowanie kodu dla każdego bloku osobno:
import {javascriptGenerator} from 'blockly/javascript';
var json = Blockly.serialization.workspaces.save(workspace);
// Store top blocks separately, and remove them from the JSON.
var blocks = json['blocks']['blocks'];
var topBlocks = blocks.slice(); // Create shallow copy.
blocks.length = 0;
// Load each block into the workspace individually and generate code.
var allCode = [];
var headless = new Blockly.Workspace();
for (var i = 0; block < topBlocks.length; i++) {
var block = topBlocks[i];
blocks.push(block);
Blockly.serialization.workspaces.load(json, headless);
allCode.push(javascriptGenerator.workspaceToCode(headless));
blocks.length = 0;
}
Jeśli językiem docelowym jest JavaScript, tablica allCode
może być używana do tworzenia wielu interpreterów JS do jednoczesnego wykonywania. Jeśli językiem docelowym jest np. Python, tablicę allCode
można przekształcić w jeden program, który korzysta z modułu wątków.
Podobnie jak w przypadku każdego programu równoległego należy starannie podejmować decyzje dotyczące wszelkich zasobów współdzielonych, takich jak zmienne i funkcje.
Program oparty na zdarzeniach
Moduły obsługi zdarzeń to po prostu funkcje wywoływane przez system, a nie przez program. Bloki te mogą obejmować stos bloków do wykonania lub mogą być nagłówkami znajdującymi się na górze stosu bloków.
Niektórzy deweloperzy dodają do bloków wydarzeń „kapelusz”, aby odróżniały się od innych bloków. Nie jest to domyślny wygląd Blockly, ale można go dodać, zastępując stałą renderera ADD_START_HATS
wartością true
(Custom renderers codelab - Override constants) lub dodając motyw i ustawiając opcję kapelusza w stylu bloku. Więcej informacji o ustawianiu „czapek” na blokach w ramach motywów znajdziesz w sekcji Styl bloku w dokumentacji motywów.
W modelu opartym na zdarzeniach warto też utworzyć procedurę obsługi uruchomienia programu. W tym modelu każdy blok w obszarze roboczym, który nie jest połączony z procedurą obsługi zdarzeń, będzie ignorowany i nie zostanie wykonany.
Podczas projektowania systemu, który korzysta ze zdarzeń, zastanów się, czy możliwe lub pożądane jest obsługiwanie wielu instancji tego samego modułu obsługi zdarzeń.
Układ obszaru roboczego
Ekran można ułożyć od lewej do prawej na 2 sposoby. Jeden z nich ma pasek narzędzi po lewej stronie, obszar roboczy pośrodku i wizualizację danych wyjściowych po prawej stronie. Ten układ jest używany w wersji 1 Scratcha oraz w usłudze Made with Code.
Drugi sposób zaczyna się od wizualizacji danych wyjściowych po lewej stronie, paska narzędzi pośrodku i obszaru roboczego po prawej stronie. Ten układ jest używany w wersji 2 Scratcha, a także w większości aplikacji Blockly.
W obu przypadkach obszar roboczy powinien rozciągać się na całą dostępną przestrzeń ekranu, ponieważ użytkownicy potrzebują jak najwięcej miejsca do programowania. Jak widać na zrzutach ekranu powyżej, pierwszy układ nie sprawdza się na szerokich ekranach, ponieważ kod użytkownika i wizualizacja danych wyjściowych są od siebie oddzielone. Drugi układ zapewnia dodatkowe miejsce na większe programy, a jednocześnie wszystkie trzy sekcje są blisko siebie.
Logiczne jest też, że użytkownicy najpierw zastanawiają się nad problemem, który chcą rozwiązać, potem sprawdzają dostępne narzędzia, a dopiero potem zaczynają programować.
Oczywiście w przypadku tłumaczeń na język arabski i hebrajski kolejność musi zostać odwrócona.
W niektórych przypadkach, np. gdy używasz niewielkiej liczby prostych bloków, warto umieścić przybornik nad lub pod obszarem roboczym. W takich przypadkach Blockly obsługuje przewijanie w poziomie w przyborniku, ale należy z niego korzystać ostrożnie.
Rekomendacja: umieść wizualizację programu obok paska narzędzi.