---
sidebar_position: 4
title: "Entendendo o Blockly"
---

O Blockly é o editor visual de lógica usado nas atividades de programação. O usuário arrasta blocos para montar o programa; o Blockly converte esse workspace em JavaScript, que o interpretador executa.

Referência externa: https://developers.google.com/blockly

## Como o Blockly se encaixa na atividade

```mermaid
flowchart TD
    TB["toolboxGenerator: define blocos disponiveis"] --> BL["BlocklyEditor: workspace interativo"]
    BL -->|javascriptGenerator| JS["Codigo JavaScript"]
    JS -->|registerExecutionFunction| GS["GameStateContext execute"]
    GS --> INT["GameInterpreter executa o codigo"]
```

Cada atividade define quais blocos estão disponíveis por fase via `toolboxGenerator`. Quando o usuário clica em Executar, o `BlocklyEditor` serializa o workspace em JavaScript e entrega ao `GameStateContext` para execução.

## BlocklyEditor

`app/src/components/game/editors/BlocklyEditor.jsx`

O componente principal do editor. É criado com `forwardRef` para expor operações imperativas ao pai quando necessário.

Props relevantes:

| Prop | Tipo | Descrição |
|---|---|---|
| `toolboxGenerator` | `Function` | Recebe `allowedBlocks` da fase e retorna o JSON de toolbox |
| `starterBlocks` | `Object` | JSON de blocos pré-carregados no início de uma fase |
| `debugSolutions` | `Object` | Mapa `{ [fase]: jsonSolução }` - disponível apenas em desenvolvimento |

### Ciclo de vida interno

```mermaid
sequenceDiagram
    participant F as Fase (EditorContext)
    participant BE as BlocklyEditor
    participant WS as Workspace Blockly
    participant ST as blockstorage

    F->>BE: toolboxGenerator atualiza
    BE->>WS: recria toolbox com allowedBlocks da fase
    BE->>ST: tenta carregar workspace salvo
    ST-->>WS: injeta blocos salvos (se existirem)
    WS->>BE: onChange dispara a cada edição
    BE->>ST: salva workspace com debounce (1s)
    BE->>F: registra função de execução (registerExecutionFunction)
```

### Persistência automática

O workspace é salvo automaticamente no `localStorage` via `blockstorage.js` com debounce de 1 segundo. Ao trocar de fase, o editor carrega o estado salvo daquela fase, se houver.

Arquivos:
- `app/src/services/blockstorage.js`

### Limite de blocos por fase

Quando `maxBlocks` está configurado na fase, o editor desabilita categorias da toolbox ao atingir o limite. O contador visível fica na `GameArea` via a prop `blocksRemaining`.

## Toolbox

A toolbox define o painel lateral com as categorias e blocos disponíveis. Cada atividade tem seu `toolboxGenerator`, uma função que recebe a lista de blocos permitidos pela fase e monta a estrutura JSON do Blockly.

```mermaid
graph TD
    AG[allowedBlocks
da configFase] --> TG[toolboxGenerator]
    TG --> CAT[Categorias com blocos filtrados]
    CAT --> FILT[filtrarCategoriasVazias]
    FILT --> BL[Blockly renderiza toolbox]
```

Helpers disponíveis em `app/src/blockly/toolbox.js`:

- `criarToolboxBase()` - estrutura base vazia.
- `criarCategoria(nome, cor)` - cria uma categoria com cor automática por nome.
- `filtrarCategoriasVazias(toolbox)` - remove categorias sem blocos para não poluir a UI.

## Gerador de código

O Blockly usa a API `javascriptGenerator` para traduzir blocos em código JavaScript. Cada bloco customizado precisa de uma função geradora registrada.

```javascript
// app/src/blockly/generator.js - padrão usado nas atividades
import { configurarGerador, gerarComando } from '@/blockly/generator';

export const defineGenerators = () => {
  configurarGerador(); // adiciona highlightBlock como prefixo
  gerarComando('robo_mover_frente', 'moverFrente()');
  gerarComando('robo_virar_esquerda', 'virarEsquerda()');
};
```

O `highlightBlock(%1)` inserido como prefixo é o que faz o bloco piscar durante a execução passo a passo.

Referências externas:
- Blockly code generators: https://developers.google.com/blockly/guides/create-custom-blocks/generating-code/overview
- javascriptGenerator: https://developers.google.com/blockly/reference/js/blockly.javascriptgenerator_class

## Modo mobile

Em telas pequenas, o Blockly troca para uma toolbox simplificada com menos categorias visíveis. O comportamento é controlado por `app/src/blockly/mobileToolbox.js` e `BlocklyEditor.mobile.css`.

O hook `useIsMobile` detecta o tamanho da tela e o componente reconfigura o workspace com `isMobile`.

Referência externa: https://developers.google.com/blockly/guides/configure/advanced/zoom
