Files
pitiupi/docs/documentation/04_inicializacao_e_gui.md
T
Gabriel Felipe Souza SantosandCursor e84aba2f4e feat(run): abre o Java da placa real e guarda dados no clone
Linux, WSL e Windows usam o mesmo run --all, e plugins, cache e logs ficam em .pitiupi na raiz do projeto.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-03 23:52:08 -03:00

152 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Visão geral
O `Pitiupi` é uma plataforma P2P baseada em uma arquitetura de plugins,
desenvolvida para permitir a criação de aplicações distribuídas sobre uma
infraestrutura comum de comunicação em rede.
A aplicação fornece mecanismos de descoberta de usuários, comunicação entre
peers, troca de mensagens serializadas e integração de extensões por meio de
plugins. A comunicação de rede utiliza dois protocolos de transporte: UDP,
empregado principalmente na descoberta e comunicação multicast entre as
instâncias, e TCP, utilizado para comunicação direta e persistente entre peers.
O projeto serve como base para experimentação de aplicações distribuídas e
desenvolvimento de extensões via plugins.
Índice: [README.md](README.md).
# Arquitetura geral
A aplicação é dividida em três grupos principais:
- **Núcleo da aplicação**: a `MainShellFrame` coordena GUI, rede e plugins.
- **Sistema de plugins**: extensões em JAR carregadas de `PITIUPI_HOME/plugins` (dev: `./scripts/pitiupi.sh link --all`).
- **Comunicação de rede**: UDP (`SocketUDP`) e TCP (`SocketTCP`, `TcpConnection`).
## Inicialização da aplicação
1. `Main` garante o layout em `PITIUPI_HOME` e abre o `LoginDialog` (nome e porta, PT-BR, ~30% da área útil do monitor, centralizado).
2. Após confirmar o login, a `MainShellFrame` é exibida (1024×768, centralizada).
3. O `SocketUDP` associa-se à porta configurada e ingressa no grupo multicast.
4. O `SocketTCP` cria um `ServerSocket` na mesma porta para conexões TCP.
5. Os mecanismos de comunicação iniciam threads de recepção.
6. O `HeartbeatManager` envia heartbeats periodicamente; o `NetworkUsersPanel` lista peers via `PresenceService`.
7. O `PluginManager` carrega os JARs em `plugins/` via SPI, com `ShellPluginWorkspace` ligado às abas centrais.
Ver também: [05_udp_multicast.md](05_udp_multicast.md), [09_sistema_de_plugins.md](09_sistema_de_plugins.md).
### Teste manual T-LOGIN-01 (login centralizado)
1. Compilar e executar: `./scripts/pitiupi.sh run --all` na raiz do repositório.
2. O `LoginDialog` deve aparecer **no centro** do monitor principal (WSL/KDE), não no canto superior esquerdo.
3. Após entrar, a `MainShellFrame` (1024×768) também deve abrir centralizada.
A posição exata depende do gerenciador de janelas; o núcleo recentra após exibir a janela.
### Atualizar plugin Chat (Onda E)
O JAR do módulo é `plugins/chat/dist/pitiupi.chat.jar` (catálogo `plugins.registry.json`). Não use `dist/chat.jar`.
```bash
cd plugins/chat && ant clean jar
./scripts/pitiupi.sh link --all
```
Isso recria o symlink `.pitiupi/plugins/chat.jar` → o JAR buildado, na raiz do clone. O comando `link` lista o destino real de cada `.jar`.
# Interface gráfica
A interface gráfica é Swing, organizada em shell (`pitiupi.presentation.shell`):
| Região | Componente |
|--------|------------|
| Centro | `TabWorkspacePanel` — aba **Plugins** (galeria; abre plugin sob demanda), abas de plugin **fecháveis** (×), aba **Configurações** |
| Leste | `NetworkUsersPanel` — “Usuários nesta rede”, peer actions (badges na lista: **D23**, adiados — ver [decision-register.md](../decision-register.md)) |
| Sul | Barra de status (porta e nome local) |
| Menu | `ShellMenuBar` — apenas **Ajuda → Sobre** (sair pelo X da janela) |
Plugins expõem `getName()` (técnico), `getIdentifier()` (SPI) e `getDisplayName()` (texto na galeria e nas abas).
A aba **Configurações** mostra em cima **Sua conexão**: nome e porta editáveis, saída (Automático, Cabo ou Wi-Fi), TTL, IP local, interface em uso, ID da instância e contagem de peers. **Aplicar** grava a preferência e, se porta, saída ou TTL mudaram, reabre a rede na hora. IP e ID continuam somente leitura. Embaixo fica a tabela de JARs instalados.
Durante a inicialização, cada plugin recebe `ConnectionManager` e `PluginWorkspace`
no método `createPlugin()`. Menus multicast na barra superior não são mais usados;
ações para todos os peers migram para **peer actions** (contexto na lista lateral).
Ao iniciar, só as abas **Plugins** e **Configurações** ficam visíveis. Cada plugin registra um painel com `bindShellWorkspaceContent`; a aba abre ao clicar na galeria ou via peer action. Referência: **Conversa na rede** (`ChatPanel`) e **Compartilhar tela** (`ScreenCastPanel`).
O **chat** usa campo de mensagem compacto (~2 linhas, quebra de linha; barra de rolagem vertical só se o texto não couber). O histórico ocupa a maior parte da altura da aba (divisor proporcional ao abrir a janela). Cada pessoa tem uma sub-aba; o × fecha essa sub-aba mesmo com outras ao lado. Se a pessoa muda de cabo para Wi-Fi, a sub-aba já aberta passa a usar o IP novo em vez de aparecer uma segunda vez com o mesmo nome.
Canal TCP privado do chat fica no mesmo `ChatPanel` (histórico separado por conversa: sala geral, peer por IP, privado com toggle). O núcleo mantém `PeerActivityInbox` para atividade por peer; indicadores visuais completos na lista lateral ainda não fazem parte da v1 (**D23**).
Ao fechar a aba superior de **Compartilhar tela** (×), o núcleo chama `Plugin.onShellTabClosed()` — o plugin interrompe captura e envio (toggle desligado). Reabrir pela galeria deve mostrar compartilhamento inativo.
**TCP (transporte)** envia uma mensagem serializada pelo núcleo, na porta desta instância. A primeira conexão com um IP que ainda não tem socket aberto corre fora da thread da janela: o chat mostra “Conectando em …”, espera no máximo cerca de 5 s e, se falhar, avisa uma vez. Mensagens seguintes no mesmo socket não repetem esse aviso. **TCP privado** (toggle) abre conexão dedicada ao plugin entre dois peers, com o mesmo aviso só na abertura. Na UI só se informa o **IP** do peer: UDP/TCP unicast do Pitiupi usa sempre a **mesma porta** desta instância (convenção de sala: todos com a mesma porta, ex. 5000 e 5001 em testes no mesmo PC).
Textos da UI (destino, combo de forma de envio e linha **“Como esta mensagem vai”**) usam linguagem simples e o termo técnico entre parênteses (multicast UDP, UDP unicast, TCP). Na sala, o transporte não é só multicast: o combo pode escolher cópias unicast ou TCP para cada pessoa, conforme o plugin.
Ver [12_menus_unicast_multicast.md](12_menus_unicast_multicast.md).
## Boot (sequência)
```mermaid
sequenceDiagram
participant Main
participant Home as PitiupiHome
participant Login as LoginDialog
participant Shell as MainShellFrame
participant CM as ConnectionManager
participant PM as PluginManager
Main->>Home: ensureLayout()
Main->>Login: showLogin()
Login-->>Main: nome + porta
Main->>Shell: new MainShellFrame(nome, porta)
Shell->>CM: iniciar UDP/TCP/heartbeat
Shell->>PM: carregar JARs SPI
PM-->>Shell: createPlugin(cm, workspace)
```
## Camadas de comunicação
```mermaid
flowchart TB
subgraph ui [presentation.shell]
Shell[MainShellFrame]
Users[NetworkUsersPanel]
end
subgraph app [application + control]
CM[ConnectionManager]
HB[HeartbeatManager]
Disp[MessageDispatcher]
end
subgraph net [net]
UDP[SocketUDP]
TCP[SocketTCP]
end
subgraph ext [plugins]
PL[Plugin JARs]
end
Shell --> CM
Users --> CM
CM --> UDP
CM --> TCP
CM --> HB
Disp --> CM
PL --> Disp
UDP --> PL
TCP --> PL
```
O UDP multicast sustenta presença e mensagens broadcast/unicast; o TCP sustenta
canais diretos com framing de mensagens. Detalhes em [05](05_udp_multicast.md)
e [06](06_tcp_conexoes.md).
### Exemplo: um envio UDP até outro peer
1. Plugin chama `MessageDispatcher` (ou `ConnectionManager`) com `TransportMode` e destino.
2. Mensagem serializada (`Message.toByteArray()`).
3. `SocketUDP` monta `DatagramPacket` (multicast `224.0.0.3` ou unicast ao IP do peer).
4. Peer receptor: thread de `SocketUDP.receive()` desserializa e `PluginManager` entrega ao plugin que declarou o tipo em `getMessages()`.
Ver [07_mensagens_e_serializacao.md](07_mensagens_e_serializacao.md).