refactor(plugins): SPI workspace-only e remoção de menus legados
Remove GuiManager e pitiupi.models.Menus; atualiza chat/screencast, docs e testes (ConfigLoader, TcpConnectionManager). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
7c8a476253
commit
42e70af48b
33 files changed
+104
-444
No files matched your search
+1
-1
@@ -16,7 +16,7 @@ Entrada na raiz do repositório: [README.md](../README.md).
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| **Aluno (TP)** | [documentation/00_quickstart.md](documentation/00_quickstart.md) → [10_tutorial_plugin.md](documentation/10_tutorial_plugin.md) → [17_tutorial_ping_aula.md](documentation/17_tutorial_ping_aula.md) → [11_plugins_referencia.md](documentation/11_plugins_referencia.md) |
|
| **Aluno (TP)** | [documentation/00_quickstart.md](documentation/00_quickstart.md) → [10_tutorial_plugin.md](documentation/10_tutorial_plugin.md) → [17_tutorial_ping_aula.md](documentation/17_tutorial_ping_aula.md) → [11_plugins_referencia.md](documentation/11_plugins_referencia.md) |
|
||||||
| **Monitor / docência** | [documentation/01_visao_disciplina_e_tp.md](documentation/01_visao_disciplina_e_tp.md) → [15_testes_e_gate.md](documentation/15_testes_e_gate.md) |
|
| **Monitor / docência** | [documentation/01_visao_disciplina_e_tp.md](documentation/01_visao_disciplina_e_tp.md) → [15_testes_e_gate.md](documentation/15_testes_e_gate.md) |
|
||||||
| **Desenvolvedor** | [documentation/13_guia_dev_e_agente.md](documentation/13_guia_dev_e_agente.md) → [14_arquitetura_e_manutencao.md](documentation/14_arquitetura_e_manutencao.md) |
|
| **Desenvolvedor** | [documentation/13_guia_desenvolvimento.md](documentation/13_guia_desenvolvimento.md) → [14_arquitetura_e_manutencao.md](documentation/14_arquitetura_e_manutencao.md) |
|
||||||
| **Professor / banca** | [documentation/16_fundamentacao_redes.md](documentation/16_fundamentacao_redes.md) → [references/README.md](references/README.md) |
|
| **Professor / banca** | [documentation/16_fundamentacao_redes.md](documentation/16_fundamentacao_redes.md) → [references/README.md](references/README.md) |
|
||||||
|
|
||||||
**Idioma:** documentação em PT-BR; pacotes e classes Java como no código.
|
**Idioma:** documentação em PT-BR; pacotes e classes Java como no código.
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
| D7 | Plugins via JAR + Java SPI | Carregamento dinâmico sem recompilar o núcleo | [09_sistema_de_plugins.md](documentation/09_sistema_de_plugins.md) |
|
| D7 | Plugins via JAR + Java SPI | Carregamento dinâmico sem recompilar o núcleo | [09_sistema_de_plugins.md](documentation/09_sistema_de_plugins.md) |
|
||||||
| D8 | Classloader por JAR de plugin | Isolar dependências; desserialização com `PluginObjectInputStream` | [09_sistema_de_plugins.md](documentation/09_sistema_de_plugins.md) |
|
| D8 | Classloader por JAR de plugin | Isolar dependências; desserialização com `PluginObjectInputStream` | [09_sistema_de_plugins.md](documentation/09_sistema_de_plugins.md) |
|
||||||
| D9 | Plugins em `PITIUPI_HOME/plugins` | Dados do usuário fora do clone Git; `PITIUPI_HOME` ou `~/pitiupi` | [00_quickstart.md](documentation/00_quickstart.md) |
|
| D9 | Plugins em `PITIUPI_HOME/plugins` | Dados do usuário fora do clone Git; `PITIUPI_HOME` ou `~/pitiupi` | [00_quickstart.md](documentation/00_quickstart.md) |
|
||||||
| D10 | Erros com `ErrorCode` | Mensagens PT na UI; `PitiupiException` no domínio | [13_guia_dev_e_agente.md](documentation/13_guia_dev_e_agente.md) |
|
| D10 | Erros com `ErrorCode` | Mensagens PT na UI; `PitiupiException` no domínio | [13_guia_desenvolvimento.md](documentation/13_guia_desenvolvimento.md) |
|
||||||
| D11 | Reinício após instalar/remover JAR | Mutar `plugins/` exige reiniciar o app para recarregar SPI | [04_inicializacao_e_gui.md](documentation/04_inicializacao_e_gui.md) |
|
| D11 | Reinício após instalar/remover JAR | Mutar `plugins/` exige reiniciar o app para recarregar SPI | [04_inicializacao_e_gui.md](documentation/04_inicializacao_e_gui.md) |
|
||||||
| D16 | UI em abas; sem `JFrame` de plugin | Conteúdo na `MainShellFrame`; galeria e peer actions abrem abas | [04_inicializacao_e_gui.md](documentation/04_inicializacao_e_gui.md) |
|
| D16 | UI em abas; sem `JFrame` de plugin | Conteúdo na `MainShellFrame`; galeria e peer actions abrem abas | [04_inicializacao_e_gui.md](documentation/04_inicializacao_e_gui.md) |
|
||||||
| D17 | Goodbye + timeout de presença | `GoodbyeMessage` em multicast ao fechar; timeout ~15 s mantido | [08_heartbeat_e_presenca.md](documentation/08_heartbeat_e_presenca.md) |
|
| D17 | Goodbye + timeout de presença | `GoodbyeMessage` em multicast ao fechar; timeout ~15 s mantido | [08_heartbeat_e_presenca.md](documentation/08_heartbeat_e_presenca.md) |
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Cada equipe/aluno entrega um **módulo Java separado** que:
|
|||||||
|
|
||||||
1. Compila para JAR e carrega via `pitiupi/plugins/`.
|
1. Compila para JAR e carrega via `pitiupi/plugins/`.
|
||||||
2. Define mensagens (`extends Message`) e o fluxo entre peers.
|
2. Define mensagens (`extends Message`) e o fluxo entre peers.
|
||||||
3. Integra menus/janelas via `GuiManager`.
|
3. Integra UI na aba central via `PluginWorkspace` e peer actions na lista lateral.
|
||||||
4. Inclui README do módulo (build + protocolo).
|
4. Inclui README do módulo (build + protocolo).
|
||||||
|
|
||||||
Exemplos de tema: chat temático, tabuleiro (xadrez/damas), compartilhamento de arquivo, quiz síncrono.
|
Exemplos de tema: chat temático, tabuleiro (xadrez/damas), compartilhamento de arquivo, quiz síncrono.
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
# Sistema de plugins
|
# Sistema de plugins
|
||||||
|
|
||||||
O sistema de plugins permite extensão modular sem alterar o núcleo. O contrato
|
O sistema de plugins permite extensão modular sem alterar o núcleo. O contrato está em `pitiupi.models.Plugin` (classe abstrata).
|
||||||
está em `pitiupi.models.Plugin` (classe abstrata).
|
|
||||||
|
**Breaking change (pós-v1):** plugins devem implementar apenas `createPlugin(ConnectionManager, PluginWorkspace)`. A API antiga com `GuiManager` e menus por categoria foi removida.
|
||||||
|
|
||||||
## Interface Plugin
|
## Interface Plugin
|
||||||
|
|
||||||
@@ -11,8 +12,7 @@ Métodos obrigatórios:
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `getName()`, `getAuthor()`, `getVersion()`, `getIdentifier()` | Identificação (o `identifier` distingue plugins em conexões TCP dedicadas) |
|
| `getName()`, `getAuthor()`, `getVersion()`, `getIdentifier()` | Identificação (o `identifier` distingue plugins em conexões TCP dedicadas) |
|
||||||
| `getDisplayName()` | Texto na galeria e título de aba (padrão: `getName()`) |
|
| `getDisplayName()` | Texto na galeria e título de aba (padrão: `getName()`) |
|
||||||
| `createPlugin(ConnectionManager, PluginWorkspace)` | Inicialização na shell: painel na aba, peer actions, rede |
|
| `createPlugin(ConnectionManager, PluginWorkspace)` | Inicialização: `bindShellWorkspaceContent`, `installPeerActions`, rede |
|
||||||
| `createPlugin(ConnectionManager, GuiManager)` | Legado — adapter na carga; não usar em plugins novos |
|
|
||||||
| `getMessages()` | Lista de classes `Message` que o plugin desserializa |
|
| `getMessages()` | Lista de classes `Message` que o plugin desserializa |
|
||||||
| `receiveMessage(Message)` | Processamento após o `PluginManager` identificar o tipo |
|
| `receiveMessage(Message)` | Processamento após o `PluginManager` identificar o tipo |
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,24 @@ Este guia complementa [09_sistema_de_plugins.md](09_sistema_de_plugins.md). Use
|
|||||||
|
|
||||||
```java
|
```java
|
||||||
public class MeuPlugin extends Plugin {
|
public class MeuPlugin extends Plugin {
|
||||||
|
private PluginWorkspace workspace;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createPlugin(ConnectionManager cm, GuiManager gui) {
|
public void createPlugin(ConnectionManager cm, PluginWorkspace workspace) {
|
||||||
// registrar menus, abrir janelas
|
this.workspace = workspace;
|
||||||
|
MeuPanel panel = new MeuPanel(cm);
|
||||||
|
bindShellWorkspaceContent(panel);
|
||||||
|
installPeerActions(workspace.peerActions());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void installPeerActions(PeerActionsRegistrar registrar) {
|
||||||
|
registrar.register(PeerAction.of(
|
||||||
|
"meuplugin.abrir",
|
||||||
|
"Abrir",
|
||||||
|
PeerActionTarget.ALL_PEERS,
|
||||||
|
target -> workspace.openOrFocusTab(getIdentifier(), getDisplayName())
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -49,25 +64,9 @@ Arquivo `src/META-INF/services/pitiupi.models.Plugin`:
|
|||||||
pacote.MeuPlugin
|
pacote.MeuPlugin
|
||||||
```
|
```
|
||||||
|
|
||||||
## 5. Categoria no menu
|
## 5. Registrar no catálogo
|
||||||
|
|
||||||
Escolha onde o plugin aparece na barra **Plugin**:
|
Adicione uma entrada em [`plugins.registry.json`](../../plugins.registry.json):
|
||||||
|
|
||||||
| `MenuCategory` | Uso |
|
|
||||||
| --- | --- |
|
|
||||||
| `Social` | Chat, presença |
|
|
||||||
| `Jogos` | Jogos entre peers |
|
|
||||||
| `Streaming` | Screen cast, mídia |
|
|
||||||
|
|
||||||
Exemplo:
|
|
||||||
|
|
||||||
```java
|
|
||||||
guiManager.createMenu(MenuCategory.Jogos, new MeuMenu(...));
|
|
||||||
```
|
|
||||||
|
|
||||||
## 6. Registrar no catálogo
|
|
||||||
|
|
||||||
Adicione uma entrada em [`plugins.registry.json`](../../plugins.registry.json) na raiz do repo:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -81,29 +80,15 @@ Adicione uma entrada em [`plugins.registry.json`](../../plugins.registry.json) n
|
|||||||
|
|
||||||
O `id` é o que você passa para `./scripts/pitiupi.sh run --plugins xadrez`.
|
O `id` é o que você passa para `./scripts/pitiupi.sh run --plugins xadrez`.
|
||||||
|
|
||||||
## 7. Build e instalação
|
## 6. Build e instalação
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./scripts/pitiupi.sh build --plugins xadrez
|
./scripts/pitiupi.sh build --plugins xadrez
|
||||||
# ou, manualmente:
|
|
||||||
cd pitiupi.xadrez && ant jar
|
|
||||||
ln -sf ../../pitiupi.xadrez/dist/pitiupi.xadrez.jar ../pitiupi/plugins/xadrez.jar
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Reinicie o Pitiupi após trocar JARs.
|
JARs de runtime ficam em `PITIUPI_HOME/plugins` (ver [00_quickstart.md](00_quickstart.md)).
|
||||||
|
|
||||||
## 8. Teste
|
## 7. Próximos passos
|
||||||
|
|
||||||
Duas instâncias, mesma rede, portas distintas se no mesmo host. Ver [00_quickstart.md](00_quickstart.md).
|
- [11_plugins_referencia.md](11_plugins_referencia.md) — chat e screenCast
|
||||||
|
- [17_tutorial_ping_aula.md](17_tutorial_ping_aula.md) — plugin didático Ping (opcional, fora do commit)
|
||||||
## TCP dedicado (avançado)
|
|
||||||
|
|
||||||
Se o plugin precisa de canal TCP com handshake por `getIdentifier()`, estude `plugins/chat` (`receivePrivateConnection`, `receiveBytes`). Use `MessageDispatcher` para envios didáticos. Ver [11_plugins_referencia.md](11_plugins_referencia.md).
|
|
||||||
|
|
||||||
## Erros frequentes
|
|
||||||
|
|
||||||
| Problema | Causa provável |
|
|
||||||
| --- | --- |
|
|
||||||
| Plugin não aparece | SPI ausente ou JAR fora de `plugins/` |
|
|
||||||
| `ClassNotFoundException` na recepção | Classe da mensagem não no JAR do remetente/destino |
|
|
||||||
| Peers não se veem | Multicast bloqueado — [appendix_portas_e_multicast.md](appendix_portas_e_multicast.md) |
|
|
||||||
@@ -1,34 +1,15 @@
|
|||||||
# Menus, peer actions e transportes
|
# Menus e ações na lista (histórico)
|
||||||
|
|
||||||
## Interface atual (shell v1)
|
Na v1 atual, plugins **não** registram menus na barra superior nem submenus legados por categoria.
|
||||||
|
|
||||||
Plugins de referência **não** dependem da barra de menus superior para o fluxo principal:
|
## Como expor ações hoje
|
||||||
|
|
||||||
- **Galeria** na aba **Plugins** abre cada extensão em aba própria (fechável com ×).
|
1. **Galeria Plugins** — abre a aba central do plugin.
|
||||||
- **Peer actions** na lista **Usuários nesta rede** (clique em um peer ou em **Todos**) agrupam ações de todos os plugins instalados.
|
2. **Lista lateral** — clique em um peer ou em **Todos** → menu com **peer actions** registradas por cada plugin (`PeerActionBroker`).
|
||||||
- Dentro da aba do plugin, **`PluginRoutingPanel`** padroniza destino (sala geral vs IP), forma de envio (multicast UDP, UDP unicast, TCP) e texto de ajuda.
|
3. **`PluginWorkspace.openOrFocusTab`** — dentro do handler da peer action ou após carregar o painel.
|
||||||
|
|
||||||
Ver [04_inicializacao_e_gui.md](04_inicializacao_e_gui.md) e [09_sistema_de_plugins.md](09_sistema_de_plugins.md).
|
## Catálogo `menuCategory`
|
||||||
|
|
||||||
## MenuCategory (legado)
|
O campo `menuCategory` em [`plugins.registry.json`](../../plugins.registry.json) (`Social`, `Jogos`, `Streaming`) serve apenas ao script `./scripts/pitiupi.sh` para filtrar build/run — não cria menus Swing.
|
||||||
|
|
||||||
Enum em `pitiupi.models.Menus.MenuCategory` (`Jogos`, `Social`, `Streaming`) ainda aparece no **catálogo** (`menuCategory` em `plugins.registry.json`) e em plugins antigos que chamam `GuiManager.createMenu(...)`.
|
Referência de plugins: [11_plugins_referencia.md](11_plugins_referencia.md).
|
||||||
|
|
||||||
Novos plugins devem preferir `PluginWorkspace` + peer actions. O menu da shell expõe apenas **Ajuda → Sobre**.
|
|
||||||
|
|
||||||
## Unicast vs multicast na aplicação
|
|
||||||
|
|
||||||
| Modo | API típica | Semântica |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| Multicast | `MessageDispatcher` / `SocketUDP.sendMulticast` | Todos no grupo na porta configurada |
|
|
||||||
| Unicast UDP | envio para IP de um peer | Um destinatário, sem estabelecer TCP |
|
|
||||||
| TCP | `ConnectionManager` / `SocketTCP` | Canal com framing 4+N bytes |
|
|
||||||
|
|
||||||
Detalhes de rede: [05_udp_multicast.md](05_udp_multicast.md), [06_tcp_conexoes.md](06_tcp_conexoes.md).
|
|
||||||
|
|
||||||
## Referência de código
|
|
||||||
|
|
||||||
- Chat e screencast: peer actions em `ChatPlugin` e `ScreenCastPlugin`.
|
|
||||||
- Envio unificado: `pitiupi.application.messaging.MessageDispatcher` e `TransportMode`.
|
|
||||||
|
|
||||||
O antigo plugin **mpChat** foi unificado no módulo `plugins/chat` (mensagens `LegacyMpChatMessage` para compatibilidade TCP privado). Ver [11_plugins_referencia.md](11_plugins_referencia.md) e decisão D19 no [decision-register.md](../decision-register.md).
|
|
||||||
+5
-7
@@ -1,6 +1,6 @@
|
|||||||
# Guia para desenvolvedor e agente
|
# Guia para desenvolvimento
|
||||||
|
|
||||||
Esta documentação descreve **apenas** a ferramenta Pitiupi neste repositório: build, rede, plugins e convenções de código. Quem clona o projeto não precisa de pastas ou ferramentas de meta-desenvolvimento externas; mantenha referências técnicas e tutoriais limitados ao que está em `docs/` e no código do próprio repo.
|
Esta documentação descreve a ferramenta Pitiupi neste repositório: build, rede, plugins e convenções de código.
|
||||||
|
|
||||||
## Leitura mínima antes de mudar código
|
## Leitura mínima antes de mudar código
|
||||||
|
|
||||||
@@ -21,23 +21,21 @@ Esta documentação descreve **apenas** a ferramenta Pitiupi neste repositório:
|
|||||||
|
|
||||||
## Gate de build
|
## Gate de build
|
||||||
|
|
||||||
Compilar núcleo e os dois plugins do catálogo:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd pitiupi && ant jar && ant test
|
cd pitiupi && ant jar && ant test
|
||||||
cd plugins/chat && ant jar
|
cd plugins/chat && ant jar
|
||||||
cd plugins/screencast && ant jar
|
cd plugins/screencast && ant jar
|
||||||
```
|
```
|
||||||
|
|
||||||
Ou na raiz do clone: `./scripts/pitiupi.sh build --all`.
|
Ou na raiz: `./scripts/pitiupi.sh build --all`.
|
||||||
|
|
||||||
Requer JDK e Ant no PATH. Teste manual em rede: [15_testes_e_gate.md](15_testes_e_gate.md).
|
Testes manuais em rede: [15_testes_e_gate.md](15_testes_e_gate.md).
|
||||||
|
|
||||||
## Convenções
|
## Convenções
|
||||||
|
|
||||||
- Código e identificadores em inglês (pacotes `pitiupi.*`).
|
- Código e identificadores em inglês (pacotes `pitiupi.*`).
|
||||||
- Documentação em português (BR) em `docs/`.
|
- Documentação em português (BR) em `docs/`.
|
||||||
- Evitar alterar o núcleo para necessidades de um único plugin — preferir extensão via `Plugin`.
|
- Evitar alterar o núcleo para um único plugin — preferir extensão via `Plugin` e `PluginWorkspace`.
|
||||||
|
|
||||||
## Decisões e débitos
|
## Decisões e débitos
|
||||||
|
|
||||||
@@ -10,7 +10,6 @@
|
|||||||
| Usuários online, peer actions | `pitiupi.presentation.shell.NetworkUsersPanel`, `PeerActionBroker` |
|
| Usuários online, peer actions | `pitiupi.presentation.shell.NetworkUsersPanel`, `PeerActionBroker` |
|
||||||
| Facade rede para plugins | `pitiupi.control.ConnectionManager` |
|
| Facade rede para plugins | `pitiupi.control.ConnectionManager` |
|
||||||
| Workspace na aba (SPI) | `pitiupi.api.plugin.PluginWorkspace`, `ShellPluginWorkspace` |
|
| Workspace na aba (SPI) | `pitiupi.api.plugin.PluginWorkspace`, `ShellPluginWorkspace` |
|
||||||
| Menus legados (adapter) | `pitiupi.control.GuiManager` — deprecado; preferir peer actions |
|
|
||||||
| UDP | `pitiupi.net.udp.SocketUDP` |
|
| UDP | `pitiupi.net.udp.SocketUDP` |
|
||||||
| TCP servidor e mapa de conexões | `pitiupi.net.tcp.SocketTCP`, `TcpConnectionManager` |
|
| TCP servidor e mapa de conexões | `pitiupi.net.tcp.SocketTCP`, `TcpConnectionManager` |
|
||||||
| Conexão TCP por peer | `pitiupi.net.tcp.TcpConnection` |
|
| Conexão TCP por peer | `pitiupi.net.tcp.TcpConnection` |
|
||||||
@@ -18,8 +17,6 @@
|
|||||||
| Heartbeat | `pitiupi.control.HeartbeatManager`, `HeartbeatMessage` |
|
| Heartbeat | `pitiupi.control.HeartbeatManager`, `HeartbeatMessage` |
|
||||||
| Carregar JARs, despacho | `pitiupi.control.plugins.PluginManager` |
|
| Carregar JARs, despacho | `pitiupi.control.plugins.PluginManager` |
|
||||||
| Contrato plugin | `pitiupi.models.Plugin`, `pitiupi.models.Messages.Message` |
|
| Contrato plugin | `pitiupi.models.Plugin`, `pitiupi.models.Messages.Message` |
|
||||||
| Menus por categoria | `pitiupi.models.Menus.*` |
|
|
||||||
|
|
||||||
## Dependências entre módulos
|
## Dependências entre módulos
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ cd pitiupi && ant test
|
|||||||
|
|
||||||
Falha se `java`, `javac` ou Ant estiverem ausentes.
|
Falha se `java`, `javac` ou Ant estiverem ausentes.
|
||||||
|
|
||||||
|
Pacotes com testes automatizados (JUnit 5): `platform` (`PitiupiHome`, `ConfigLoader`), `plugins.store`, `application.presence`, `application.peeractions`, `application.invites`, `application.messaging`, `application.activity`, `presentation.shell`, `control` (goodbye), `net.tcp` (fechamento de conexões), `models`.
|
||||||
|
|
||||||
## Gate de build (produto)
|
## Gate de build (produto)
|
||||||
|
|
||||||
Na raiz do clone:
|
Na raiz do clone:
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ Referência para **código Java**, **rede P2P** e **plugins**. Índice geral: [d
|
|||||||
| 11 | [11_plugins_referencia.md](11_plugins_referencia.md) | chat e screencast |
|
| 11 | [11_plugins_referencia.md](11_plugins_referencia.md) | chat e screencast |
|
||||||
| 17 | [17_tutorial_ping_aula.md](17_tutorial_ping_aula.md) | Exercício Ping (aula) |
|
| 17 | [17_tutorial_ping_aula.md](17_tutorial_ping_aula.md) | Exercício Ping (aula) |
|
||||||
| 12 | [12_menus_unicast_multicast.md](12_menus_unicast_multicast.md) | MenuCategory e ações |
|
| 12 | [12_menus_unicast_multicast.md](12_menus_unicast_multicast.md) | MenuCategory e ações |
|
||||||
| 13 | [13_guia_dev_e_agente.md](13_guia_dev_e_agente.md) | Leitura para dev/agente |
|
| 13 | [13_guia_desenvolvimento.md](13_guia_desenvolvimento.md) | Guia de desenvolvimento |
|
||||||
| 14 | [14_arquitetura_e_manutencao.md](14_arquitetura_e_manutencao.md) | Onde editar cada comportamento |
|
| 14 | [14_arquitetura_e_manutencao.md](14_arquitetura_e_manutencao.md) | Onde editar cada comportamento |
|
||||||
| 15 | [15_testes_e_gate.md](15_testes_e_gate.md) | Build gate e testes manuais |
|
| 15 | [15_testes_e_gate.md](15_testes_e_gate.md) | Build gate e testes manuais |
|
||||||
| 16 | [16_fundamentacao_redes.md](16_fundamentacao_redes.md) | Teoria ↔ código |
|
| 16 | [16_fundamentacao_redes.md](16_fundamentacao_redes.md) | Teoria ↔ código |
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import pitiupi.application.invites.InviteInboxService;
|
|||||||
import pitiupi.application.peeractions.PeerActionBroker;
|
import pitiupi.application.peeractions.PeerActionBroker;
|
||||||
import pitiupi.application.peeractions.PluginPeerActionsRegistrar;
|
import pitiupi.application.peeractions.PluginPeerActionsRegistrar;
|
||||||
import pitiupi.control.ConnectionManager;
|
import pitiupi.control.ConnectionManager;
|
||||||
import pitiupi.control.GuiManager;
|
|
||||||
import pitiupi.models.Plugin;
|
import pitiupi.models.Plugin;
|
||||||
import pitiupi.presentation.shell.ShellHost;
|
import pitiupi.presentation.shell.ShellHost;
|
||||||
import pitiupi.presentation.shell.TabWorkspacePanel;
|
import pitiupi.presentation.shell.TabWorkspacePanel;
|
||||||
@@ -12,14 +11,13 @@ import pitiupi.presentation.shell.TabWorkspacePanel;
|
|||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Workspace com abas e barra de status (Onda D).
|
* Workspace com abas e barra de status.
|
||||||
*/
|
*/
|
||||||
public final class ShellPluginWorkspace implements PluginWorkspace {
|
public final class ShellPluginWorkspace implements PluginWorkspace {
|
||||||
|
|
||||||
private final String pluginId;
|
private final String pluginId;
|
||||||
private final Plugin plugin;
|
private final Plugin plugin;
|
||||||
private final ConnectionManager connectionManager;
|
private final ConnectionManager connectionManager;
|
||||||
private final GuiManager guiManager;
|
|
||||||
private final TabWorkspacePanel tabWorkspace;
|
private final TabWorkspacePanel tabWorkspace;
|
||||||
private final ShellHost shellHost;
|
private final ShellHost shellHost;
|
||||||
private final PluginPeerActionsRegistrar registrar;
|
private final PluginPeerActionsRegistrar registrar;
|
||||||
@@ -28,7 +26,6 @@ public final class ShellPluginWorkspace implements PluginWorkspace {
|
|||||||
String pluginId,
|
String pluginId,
|
||||||
Plugin plugin,
|
Plugin plugin,
|
||||||
ConnectionManager connectionManager,
|
ConnectionManager connectionManager,
|
||||||
GuiManager guiManager,
|
|
||||||
PeerActionBroker peerActionBroker,
|
PeerActionBroker peerActionBroker,
|
||||||
InviteInboxService inviteInboxService,
|
InviteInboxService inviteInboxService,
|
||||||
TabWorkspacePanel tabWorkspace,
|
TabWorkspacePanel tabWorkspace,
|
||||||
@@ -37,7 +34,6 @@ public final class ShellPluginWorkspace implements PluginWorkspace {
|
|||||||
this.pluginId = pluginId;
|
this.pluginId = pluginId;
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.connectionManager = connectionManager;
|
this.connectionManager = connectionManager;
|
||||||
this.guiManager = guiManager;
|
|
||||||
this.tabWorkspace = tabWorkspace;
|
this.tabWorkspace = tabWorkspace;
|
||||||
this.shellHost = shellHost;
|
this.shellHost = shellHost;
|
||||||
this.registrar = new PluginPeerActionsRegistrar(peerActionBroker, pluginId);
|
this.registrar = new PluginPeerActionsRegistrar(peerActionBroker, pluginId);
|
||||||
@@ -46,10 +42,6 @@ public final class ShellPluginWorkspace implements PluginWorkspace {
|
|||||||
inviteInboxService.setInviteHandler(pluginId, plugin::onInviteAccepted);
|
inviteInboxService.setInviteHandler(pluginId, plugin::onInviteAccepted);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GuiManager guiManager() {
|
|
||||||
return guiManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConnectionManager connectionManager() {
|
public ConnectionManager connectionManager() {
|
||||||
return connectionManager;
|
return connectionManager;
|
||||||
|
|||||||
@@ -30,12 +30,6 @@ public final class PeerActivityInbox {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @deprecated use {@link #recordCounted} */
|
|
||||||
@Deprecated
|
|
||||||
public void record(String peerInstanceId, String pluginId, String peerActionId) {
|
|
||||||
recordCounted(peerInstanceId, pluginId, peerActionId, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void recordBroadcast(String pluginId, String peerActionId) {
|
public void recordBroadcast(String pluginId, String peerActionId) {
|
||||||
recordCounted(BROADCAST_PEER_KEY, pluginId, peerActionId, PeerActivityFocusTokens.broadcast());
|
recordCounted(BROADCAST_PEER_KEY, pluginId, peerActionId, PeerActivityFocusTokens.broadcast());
|
||||||
}
|
}
|
||||||
@@ -74,12 +68,6 @@ public final class PeerActivityInbox {
|
|||||||
return sum(countedByPeerAndAction.getOrDefault(peerKey(peerInstanceId), Map.of()));
|
return sum(countedByPeerAndAction.getOrDefault(peerKey(peerInstanceId), Map.of()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @deprecated use {@link #totalCountedForPeer} */
|
|
||||||
@Deprecated
|
|
||||||
public int totalForPeer(String peerInstanceId) {
|
|
||||||
return totalCountedForPeer(peerInstanceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasIndicatorForPeer(String peerInstanceId) {
|
public boolean hasIndicatorForPeer(String peerInstanceId) {
|
||||||
Map<String, Integer> map = indicatorByPeerAndAction.get(peerKey(peerInstanceId));
|
Map<String, Integer> map = indicatorByPeerAndAction.get(peerKey(peerInstanceId));
|
||||||
return map != null && !map.isEmpty();
|
return map != null && !map.isEmpty();
|
||||||
|
|||||||
@@ -1,80 +0,0 @@
|
|||||||
package pitiupi.control;
|
|
||||||
|
|
||||||
import pitiupi.presentation.shell.NetworkUsersPanel;
|
|
||||||
import pitiupi.presentation.shell.ShellHost;
|
|
||||||
import pitiupi.models.Menus.*;
|
|
||||||
import pitiupi.models.Menus.MulticastMenus.MulticastActionMenu;
|
|
||||||
import pitiupi.models.Menus.MulticastMenus.MulticastMenu;
|
|
||||||
import pitiupi.models.Menus.MulticastMenus.MulticastSubMenu;
|
|
||||||
import pitiupi.models.Menus.UnicastMenus.UnicastActionMenu;
|
|
||||||
import pitiupi.models.Menus.UnicastMenus.UnicastMenu;
|
|
||||||
import pitiupi.models.Menus.UnicastMenus.UnicastSubMenu;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
public class GuiManager {
|
|
||||||
private final ShellHost shellHost;
|
|
||||||
private final NetworkUsersPanel networkUsersPanel;
|
|
||||||
|
|
||||||
private Logger logger;
|
|
||||||
|
|
||||||
public GuiManager(ShellHost shellHost, javax.swing.JMenuBar menuBar, NetworkUsersPanel networkUsersPanel) {
|
|
||||||
this.shellHost = shellHost;
|
|
||||||
this.networkUsersPanel = networkUsersPanel;
|
|
||||||
this.logger = Logger.getLogger(GuiManager.class.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createMenu(MenuCategory category, Menu menu) {
|
|
||||||
try {
|
|
||||||
JMenuItem newMenu = buildMenu(menu);
|
|
||||||
if (menu instanceof MulticastMenu) {
|
|
||||||
// Onda D: ações multicast migram para peer actions / abas (Onda E).
|
|
||||||
}
|
|
||||||
if (menu instanceof UnicastMenu) {
|
|
||||||
networkUsersPanel.addUnicastMenu(category, newMenu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e) {
|
|
||||||
logger.log(Level.WARNING, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private JMenuItem buildMenu(Menu menu) {
|
|
||||||
if (menu instanceof MulticastSubMenu multicastSubMenu) {
|
|
||||||
JMenu newMenu = new JMenu(menu.getText());
|
|
||||||
|
|
||||||
for (Menu child : multicastSubMenu.getMenus()) {
|
|
||||||
newMenu.add(buildMenu(child));
|
|
||||||
}
|
|
||||||
|
|
||||||
return newMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (menu instanceof UnicastSubMenu unicastSubMenu) {
|
|
||||||
JMenu newMenu = new JMenu(menu.getText());
|
|
||||||
|
|
||||||
for (Menu child : unicastSubMenu.getMenus()) {
|
|
||||||
newMenu.add(buildMenu(child));
|
|
||||||
}
|
|
||||||
|
|
||||||
return newMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (menu instanceof MulticastActionMenu multicastActionMenu) {
|
|
||||||
JMenuItem newMenu = new JMenuItem(menu.getText());
|
|
||||||
newMenu.addActionListener(e -> multicastActionMenu.onClick());
|
|
||||||
return newMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (menu instanceof UnicastActionMenu unicastActionMenu) {
|
|
||||||
JMenuItem newMenu = new JMenuItem(menu.getText());
|
|
||||||
|
|
||||||
networkUsersPanel.initUnicastMenu(newMenu, unicastActionMenu::onClick);
|
|
||||||
return newMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Invalid menu type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,6 @@ import pitiupi.Main;
|
|||||||
import pitiupi.api.plugin.PluginWorkspace;
|
import pitiupi.api.plugin.PluginWorkspace;
|
||||||
import pitiupi.models.Plugin;
|
import pitiupi.models.Plugin;
|
||||||
import pitiupi.control.ConnectionManager;
|
import pitiupi.control.ConnectionManager;
|
||||||
import pitiupi.control.GuiManager;
|
|
||||||
import pitiupi.errors.ErrorCode;
|
import pitiupi.errors.ErrorCode;
|
||||||
import pitiupi.models.Messages.Message;
|
import pitiupi.models.Messages.Message;
|
||||||
import pitiupi.platform.PitiupiHome;
|
import pitiupi.platform.PitiupiHome;
|
||||||
@@ -112,7 +111,6 @@ public class PluginManager {
|
|||||||
|
|
||||||
public void loadPlugins(
|
public void loadPlugins(
|
||||||
ConnectionManager connectionManager,
|
ConnectionManager connectionManager,
|
||||||
GuiManager guiManager,
|
|
||||||
Function<Plugin, PluginWorkspace> workspaceFactory
|
Function<Plugin, PluginWorkspace> workspaceFactory
|
||||||
) {
|
) {
|
||||||
File pluginDir = PitiupiHome.get().pluginsDirectory().toFile();
|
File pluginDir = PitiupiHome.get().pluginsDirectory().toFile();
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
package pitiupi.models.Menus;
|
|
||||||
|
|
||||||
public abstract class Menu {
|
|
||||||
public abstract String getText();
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package pitiupi.models.Menus;
|
|
||||||
|
|
||||||
public enum MenuCategory {
|
|
||||||
Jogos,
|
|
||||||
Social,
|
|
||||||
Streaming
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package pitiupi.models.Menus.MulticastMenus;
|
|
||||||
|
|
||||||
public abstract class MulticastActionMenu extends MulticastMenu{
|
|
||||||
public abstract void onClick();
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package pitiupi.models.Menus.MulticastMenus;
|
|
||||||
|
|
||||||
import pitiupi.models.Menus.Menu;
|
|
||||||
|
|
||||||
public abstract class MulticastMenu extends Menu {
|
|
||||||
MulticastMenu() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package pitiupi.models.Menus.MulticastMenus;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public abstract class MulticastSubMenu extends MulticastMenu{
|
|
||||||
public abstract List<MulticastMenu> getMenus();
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package pitiupi.models.Menus.UnicastMenus;
|
|
||||||
|
|
||||||
import pitiupi.models.User;
|
|
||||||
|
|
||||||
public abstract class UnicastActionMenu extends UnicastMenu{
|
|
||||||
public abstract void onClick(User user);
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package pitiupi.models.Menus.UnicastMenus;
|
|
||||||
|
|
||||||
import pitiupi.models.Menus.Menu;
|
|
||||||
import pitiupi.models.User;
|
|
||||||
|
|
||||||
public abstract class UnicastMenu extends Menu {
|
|
||||||
UnicastMenu() {}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package pitiupi.models.Menus.UnicastMenus;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public abstract class UnicastSubMenu extends UnicastMenu{
|
|
||||||
public abstract List<UnicastMenu> getMenus();
|
|
||||||
}
|
|
||||||
@@ -7,9 +7,7 @@ package pitiupi.models;
|
|||||||
import pitiupi.api.plugin.InviteDetails;
|
import pitiupi.api.plugin.InviteDetails;
|
||||||
import pitiupi.api.plugin.PeerActionsRegistrar;
|
import pitiupi.api.plugin.PeerActionsRegistrar;
|
||||||
import pitiupi.api.plugin.PluginWorkspace;
|
import pitiupi.api.plugin.PluginWorkspace;
|
||||||
import pitiupi.api.plugin.ShellPluginWorkspace;
|
|
||||||
import pitiupi.control.ConnectionManager;
|
import pitiupi.control.ConnectionManager;
|
||||||
import pitiupi.control.GuiManager;
|
|
||||||
import pitiupi.models.Messages.Message;
|
import pitiupi.models.Messages.Message;
|
||||||
import pitiupi.net.tcp.TcpConnection;
|
import pitiupi.net.tcp.TcpConnection;
|
||||||
|
|
||||||
@@ -54,24 +52,9 @@ public abstract class Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inicializa o plugin.
|
* Inicializa o plugin na aba central (shell) e registra peer actions.
|
||||||
*
|
|
||||||
* <p>Este método é chamado pela aplicação após o carregamento do plugin.</p>
|
|
||||||
*
|
|
||||||
* @param connectionManager interface com o sistema de conexões da aplicação.
|
|
||||||
* @param guiManager interface com a janela principal da aplicação
|
|
||||||
*/
|
*/
|
||||||
public abstract void createPlugin(ConnectionManager connectionManager, GuiManager guiManager);
|
public abstract void createPlugin(ConnectionManager connectionManager, PluginWorkspace workspace);
|
||||||
|
|
||||||
/**
|
|
||||||
* Inicialização via workspace (Onda C+). O adaptador chama o legado e {@link #installPeerActions}.
|
|
||||||
*/
|
|
||||||
public void createPlugin(ConnectionManager connectionManager, PluginWorkspace workspace) {
|
|
||||||
if (workspace instanceof ShellPluginWorkspace shell) {
|
|
||||||
createPlugin(connectionManager, shell.guiManager());
|
|
||||||
installPeerActions(workspace.peerActions());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void installPeerActions(PeerActionsRegistrar registrar) {
|
public void installPeerActions(PeerActionsRegistrar registrar) {
|
||||||
}
|
}
|
||||||
@@ -87,19 +70,9 @@ public abstract class Plugin {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retorna uma mensagem utilizada pelo plugin.
|
* Retorna uma mensagem utilizada pelo plugin.
|
||||||
*
|
|
||||||
* @return mensagem criada pelo plugin.
|
|
||||||
*/
|
*/
|
||||||
public abstract List<Class<? extends Message>> getMessages();
|
public abstract List<Class<? extends Message>> getMessages();
|
||||||
|
|
||||||
/**
|
|
||||||
* Recebe uma mensagem enviada pela aplicação.
|
|
||||||
*
|
|
||||||
* <p>A mensagem é recebida em formato serializado. O plugin deve verificar
|
|
||||||
* se a mensagem pertence ao seu tipo e realizar o processamento necessário.</p>
|
|
||||||
*
|
|
||||||
* @param message mensagem serializada recebida.
|
|
||||||
*/
|
|
||||||
public abstract void receiveMessage(Message message);
|
public abstract void receiveMessage(Message message);
|
||||||
|
|
||||||
public boolean receiveAllTypes() {return false;}
|
public boolean receiveAllTypes() {return false;}
|
||||||
@@ -112,4 +85,4 @@ public abstract class Plugin {
|
|||||||
public boolean onSocketClosed(TcpConnection connection) {
|
public boolean onSocketClosed(TcpConnection connection) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,6 @@ package pitiupi.presentation.shell;
|
|||||||
|
|
||||||
import pitiupi.api.plugin.ShellPluginWorkspace;
|
import pitiupi.api.plugin.ShellPluginWorkspace;
|
||||||
import pitiupi.control.ConnectionManager;
|
import pitiupi.control.ConnectionManager;
|
||||||
import pitiupi.control.GuiManager;
|
|
||||||
import pitiupi.control.plugins.PluginManager;
|
import pitiupi.control.plugins.PluginManager;
|
||||||
import pitiupi.models.Plugin;
|
import pitiupi.models.Plugin;
|
||||||
|
|
||||||
@@ -22,7 +21,6 @@ public final class MainShellFrame extends JFrame implements ShellHost {
|
|||||||
private final PluginManager pluginManager = new PluginManager();
|
private final PluginManager pluginManager = new PluginManager();
|
||||||
private final ConnectionManager connectionManager;
|
private final ConnectionManager connectionManager;
|
||||||
private final NetworkUsersPanel networkUsersPanel;
|
private final NetworkUsersPanel networkUsersPanel;
|
||||||
private final GuiManager guiManager;
|
|
||||||
private final TabWorkspacePanel tabWorkspace;
|
private final TabWorkspacePanel tabWorkspace;
|
||||||
private final PluginGalleryPanel galleryPanel;
|
private final PluginGalleryPanel galleryPanel;
|
||||||
private final SettingsPanel settingsPanel;
|
private final SettingsPanel settingsPanel;
|
||||||
@@ -49,8 +47,6 @@ public final class MainShellFrame extends JFrame implements ShellHost {
|
|||||||
ShellMenuBar menuBar = new ShellMenuBar();
|
ShellMenuBar menuBar = new ShellMenuBar();
|
||||||
setJMenuBar(menuBar);
|
setJMenuBar(menuBar);
|
||||||
|
|
||||||
guiManager = new GuiManager(this, menuBar, networkUsersPanel);
|
|
||||||
|
|
||||||
JPanel center = new JPanel(new BorderLayout());
|
JPanel center = new JPanel(new BorderLayout());
|
||||||
center.add(tabWorkspace.getRootPanel(), BorderLayout.CENTER);
|
center.add(tabWorkspace.getRootPanel(), BorderLayout.CENTER);
|
||||||
getContentPane().add(center, BorderLayout.CENTER);
|
getContentPane().add(center, BorderLayout.CENTER);
|
||||||
@@ -90,11 +86,10 @@ public final class MainShellFrame extends JFrame implements ShellHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadPlugins() {
|
private void loadPlugins() {
|
||||||
pluginManager.loadPlugins(connectionManager, guiManager, (plugin) -> new ShellPluginWorkspace(
|
pluginManager.loadPlugins(connectionManager, (plugin) -> new ShellPluginWorkspace(
|
||||||
plugin.getIdentifier(),
|
plugin.getIdentifier(),
|
||||||
plugin,
|
plugin,
|
||||||
connectionManager,
|
connectionManager,
|
||||||
guiManager,
|
|
||||||
connectionManager.getPeerActionBroker(),
|
connectionManager.getPeerActionBroker(),
|
||||||
connectionManager.getInviteInboxService(),
|
connectionManager.getInviteInboxService(),
|
||||||
tabWorkspace,
|
tabWorkspace,
|
||||||
|
|||||||
@@ -7,9 +7,7 @@ import pitiupi.application.peeractions.PeerActionTarget;
|
|||||||
import pitiupi.application.peeractions.PeerTarget;
|
import pitiupi.application.peeractions.PeerTarget;
|
||||||
import pitiupi.application.presence.UserPeerView;
|
import pitiupi.application.presence.UserPeerView;
|
||||||
import pitiupi.control.ConnectionManager;
|
import pitiupi.control.ConnectionManager;
|
||||||
import pitiupi.control.GuiManager;
|
|
||||||
import pitiupi.control.PeerListener;
|
import pitiupi.control.PeerListener;
|
||||||
import pitiupi.models.Menus.MenuCategory;
|
|
||||||
import pitiupi.models.User;
|
import pitiupi.models.User;
|
||||||
import pitiupi.presentation.shell.ui.ShellUi;
|
import pitiupi.presentation.shell.ui.ShellUi;
|
||||||
|
|
||||||
@@ -28,10 +26,7 @@ import java.awt.Component;
|
|||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lista lateral com Todos e peer actions (sem badges de atividade na v1).
|
* Lista lateral com Todos e peer actions (sem badges de atividade na v1).
|
||||||
@@ -40,8 +35,6 @@ public final class NetworkUsersPanel extends JPanel implements PeerListener {
|
|||||||
|
|
||||||
private final DefaultListModel<DisplayPeer> listModel = new DefaultListModel<>();
|
private final DefaultListModel<DisplayPeer> listModel = new DefaultListModel<>();
|
||||||
private final JList<DisplayPeer> userList = new JList<>(listModel);
|
private final JList<DisplayPeer> userList = new JList<>(listModel);
|
||||||
private final JPopupMenu menu = new JPopupMenu();
|
|
||||||
private final Map<MenuCategory, JMenu> legacyCategories = new HashMap<>();
|
|
||||||
private final ConnectionManager connectionManager;
|
private final ConnectionManager connectionManager;
|
||||||
|
|
||||||
public NetworkUsersPanel(ConnectionManager connectionManager) {
|
public NetworkUsersPanel(ConnectionManager connectionManager) {
|
||||||
@@ -49,12 +42,6 @@ public final class NetworkUsersPanel extends JPanel implements PeerListener {
|
|||||||
setLayout(new BorderLayout());
|
setLayout(new BorderLayout());
|
||||||
setPreferredSize(new Dimension(200, 0));
|
setPreferredSize(new Dimension(200, 0));
|
||||||
|
|
||||||
for (MenuCategory category : MenuCategory.values()) {
|
|
||||||
JMenu cat = new JMenu(category.toString());
|
|
||||||
menu.add(cat);
|
|
||||||
legacyCategories.put(category, cat);
|
|
||||||
}
|
|
||||||
|
|
||||||
userList.setCellRenderer(new DefaultListCellRenderer() {
|
userList.setCellRenderer(new DefaultListCellRenderer() {
|
||||||
@Override
|
@Override
|
||||||
public Component getListCellRendererComponent(
|
public Component getListCellRendererComponent(
|
||||||
@@ -114,40 +101,13 @@ public final class NetworkUsersPanel extends JPanel implements PeerListener {
|
|||||||
}
|
}
|
||||||
popup.add(pluginMenu);
|
popup.add(pluginMenu);
|
||||||
}
|
}
|
||||||
for (JMenu legacy : legacyCategories.values()) {
|
|
||||||
if (legacy.getItemCount() > 0 && target == PeerActionTarget.SINGLE_PEER && !peer.view.isBroadcastTarget()) {
|
|
||||||
popup.addSeparator();
|
|
||||||
JMenu copy = new JMenu(legacy.getText());
|
|
||||||
for (int i = 0; i < legacy.getItemCount(); i++) {
|
|
||||||
copy.add(legacy.getItem(i));
|
|
||||||
}
|
|
||||||
popup.add(copy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (popup.getComponentCount() > 0) {
|
if (popup.getComponentCount() > 0) {
|
||||||
popup.show(userList, x, y);
|
popup.show(userList, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initUnicastMenu(JMenuItem menuItem, Consumer<User> action) {
|
|
||||||
menuItem.addActionListener(e -> {
|
|
||||||
DisplayPeer selected = userList.getSelectedValue();
|
|
||||||
if (selected == null || selected.view.isBroadcastTarget()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
User user = selected.toUser();
|
|
||||||
if (user.getAddress() != null) {
|
|
||||||
action.accept(user);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addUnicastMenu(MenuCategory category, JMenuItem menuItem) {
|
|
||||||
legacyCategories.get(category).add(menuItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPeersChanged(List<User> peers) {
|
public void onPeersChanged(List<pitiupi.models.User> peers) {
|
||||||
refreshFromPresence();
|
refreshFromPresence();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +120,7 @@ public final class NetworkUsersPanel extends JPanel implements PeerListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
record DisplayPeer(UserPeerView view) {
|
private record DisplayPeer(UserPeerView view) {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return view.getDisplayName();
|
return view.getDisplayName();
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package pitiupi.models;
|
package pitiupi.models;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import pitiupi.api.plugin.PluginWorkspace;
|
||||||
|
import pitiupi.control.ConnectionManager;
|
||||||
import pitiupi.models.Messages.Message;
|
import pitiupi.models.Messages.Message;
|
||||||
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
@@ -36,8 +38,7 @@ class PluginDisplayNameTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createPlugin(pitiupi.control.ConnectionManager connectionManager,
|
public void createPlugin(ConnectionManager connectionManager, PluginWorkspace workspace) {
|
||||||
pitiupi.control.GuiManager guiManager) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -77,8 +78,7 @@ class PluginDisplayNameTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createPlugin(pitiupi.control.ConnectionManager connectionManager,
|
public void createPlugin(ConnectionManager connectionManager, PluginWorkspace workspace) {
|
||||||
pitiupi.control.GuiManager guiManager) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package pitiupi.net.tcp;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class TcpConnectionManagerTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void closeAllConnectionsOnEmptyManagerDoesNotThrow() {
|
||||||
|
TcpConnectionManager manager = new TcpConnectionManager();
|
||||||
|
manager.closeAllConnections();
|
||||||
|
manager.closeAllConnections("reason");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package pitiupi.platform;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
|
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
class ConfigLoaderTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void loadOrCreateDefaultsWritesConfig(@TempDir Path home) throws Exception {
|
||||||
|
ConfigLoader loader = new ConfigLoader(home);
|
||||||
|
loader.loadOrCreateDefaults();
|
||||||
|
assertTrue(Files.isRegularFile(home.resolve("config.properties")));
|
||||||
|
assertTrue(loader.isMigrationCwdPluginsPromptEnabled());
|
||||||
|
assertFalse(loader.isMigrationCwdPluginsDone());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void setMigrationFlagsPersist(@TempDir Path home) throws Exception {
|
||||||
|
ConfigLoader loader = new ConfigLoader(home);
|
||||||
|
loader.loadOrCreateDefaults();
|
||||||
|
loader.setMigrationCwdPluginsDone(true);
|
||||||
|
ConfigLoader reloaded = new ConfigLoader(home);
|
||||||
|
reloaded.loadOrCreateDefaults();
|
||||||
|
assertTrue(reloaded.isMigrationCwdPluginsDone());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
|
||||||
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
|
|
||||||
*/
|
|
||||||
package pitiupi.chat.GUI;
|
|
||||||
|
|
||||||
import pitiupi.models.Menus.MulticastMenus.MulticastMenu;
|
|
||||||
import pitiupi.models.Menus.MulticastMenus.MulticastSubMenu;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author flavio
|
|
||||||
*/
|
|
||||||
public class ChatMenu extends MulticastSubMenu {
|
|
||||||
ChatMulticastMenu chatMulticastMenu;
|
|
||||||
|
|
||||||
public ChatMenu(ChatWindow chatWindow) {
|
|
||||||
this.chatMulticastMenu = new ChatMulticastMenu(chatWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getText() {
|
|
||||||
return "Chat";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<MulticastMenu> getMenus() {
|
|
||||||
return List.of(chatMulticastMenu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package pitiupi.chat.GUI;
|
|
||||||
|
|
||||||
import pitiupi.models.Menus.MulticastMenus.MulticastActionMenu;;
|
|
||||||
|
|
||||||
public class ChatMulticastMenu extends MulticastActionMenu {
|
|
||||||
ChatWindow chatWindow;
|
|
||||||
|
|
||||||
public ChatMulticastMenu(ChatWindow chatWindow) {
|
|
||||||
this.chatWindow = chatWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getText() {
|
|
||||||
return "Show Chat Window";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick() {
|
|
||||||
chatWindow.setVisible(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -12,7 +12,6 @@ import pitiupi.chat.control.PrivateChatHost;
|
|||||||
import pitiupi.chat.net.ChatMessage;
|
import pitiupi.chat.net.ChatMessage;
|
||||||
import pitiupi.chat.net.LegacyMpChatMessage;
|
import pitiupi.chat.net.LegacyMpChatMessage;
|
||||||
import pitiupi.control.ConnectionManager;
|
import pitiupi.control.ConnectionManager;
|
||||||
import pitiupi.control.GuiManager;
|
|
||||||
import pitiupi.models.Messages.Message;
|
import pitiupi.models.Messages.Message;
|
||||||
import pitiupi.models.Plugin;
|
import pitiupi.models.Plugin;
|
||||||
import pitiupi.models.User;
|
import pitiupi.models.User;
|
||||||
@@ -44,10 +43,6 @@ public class ChatPlugin extends Plugin implements PrivateChatHost {
|
|||||||
installPeerActions(workspace.peerActions());
|
installPeerActions(workspace.peerActions());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void createPlugin(ConnectionManager connectionManager, GuiManager guiManager) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void installPeerActions(PeerActionsRegistrar registrar) {
|
public void installPeerActions(PeerActionsRegistrar registrar) {
|
||||||
registrar.register(PeerAction.of(
|
registrar.register(PeerAction.of(
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
|
||||||
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
|
|
||||||
*/
|
|
||||||
package pitiupi.screenCast.GUI;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import pitiupi.models.Menus.MulticastMenus.MulticastActionMenu;
|
|
||||||
import pitiupi.models.Menus.MulticastMenus.MulticastMenu;
|
|
||||||
import pitiupi.models.Menus.MulticastMenus.MulticastSubMenu;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author flavio
|
|
||||||
*/
|
|
||||||
public class ScreenCastMenu extends MulticastSubMenu {
|
|
||||||
|
|
||||||
private final ScreenCastShowMenu showMenu;
|
|
||||||
|
|
||||||
public ScreenCastMenu(ScreenCastPanel screenCastPanel) {
|
|
||||||
this.showMenu = new ScreenCastShowMenu(screenCastPanel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getText() {
|
|
||||||
return "Screen Cast";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<MulticastMenu> getMenus() {
|
|
||||||
return List.of(showMenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class ScreenCastShowMenu extends MulticastActionMenu {
|
|
||||||
private final ScreenCastPanel screenCastPanel;
|
|
||||||
|
|
||||||
ScreenCastShowMenu(ScreenCastPanel screenCastPanel) {
|
|
||||||
this.screenCastPanel = screenCastPanel;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getText() {
|
|
||||||
return "ScreenCast Window";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick() {
|
|
||||||
screenCastPanel.requestFocusInWindow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,14 +9,11 @@ import pitiupi.application.presence.UserPeerView;
|
|||||||
import pitiupi.application.peeractions.PeerActionTarget;
|
import pitiupi.application.peeractions.PeerActionTarget;
|
||||||
import pitiupi.application.peeractions.PeerTarget;
|
import pitiupi.application.peeractions.PeerTarget;
|
||||||
import pitiupi.control.ConnectionManager;
|
import pitiupi.control.ConnectionManager;
|
||||||
import pitiupi.control.GuiManager;
|
|
||||||
import pitiupi.models.Menus.MenuCategory;
|
|
||||||
import pitiupi.application.session.SessionNoticeChannel;
|
import pitiupi.application.session.SessionNoticeChannel;
|
||||||
import pitiupi.application.session.SessionNoticePhase;
|
import pitiupi.application.session.SessionNoticePhase;
|
||||||
import pitiupi.models.Messages.Message;
|
import pitiupi.models.Messages.Message;
|
||||||
import pitiupi.models.Messages.SessionNoticeMessage;
|
import pitiupi.models.Messages.SessionNoticeMessage;
|
||||||
import pitiupi.models.Plugin;
|
import pitiupi.models.Plugin;
|
||||||
import pitiupi.screenCast.GUI.ScreenCastMenu;
|
|
||||||
import pitiupi.screenCast.GUI.ScreenCastPanel;
|
import pitiupi.screenCast.GUI.ScreenCastPanel;
|
||||||
import pitiupi.screenCast.GUI.ScreenCastReceiveScope;
|
import pitiupi.screenCast.GUI.ScreenCastReceiveScope;
|
||||||
import pitiupi.screenCast.net.ScreenCastMessage;
|
import pitiupi.screenCast.net.ScreenCastMessage;
|
||||||
@@ -62,12 +59,6 @@ public class ScreenCastPlugin extends Plugin {
|
|||||||
installPeerActions(workspace.peerActions());
|
installPeerActions(workspace.peerActions());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void createPlugin(ConnectionManager connectionManager, GuiManager guiManager) {
|
|
||||||
this.screenCastPanel = new ScreenCastPanel(connectionManager);
|
|
||||||
guiManager.createMenu(MenuCategory.Streaming, new ScreenCastMenu(screenCastPanel));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onShellTabClosed() {
|
public void onShellTabClosed() {
|
||||||
if (screenCastPanel != null) {
|
if (screenCastPanel != null) {
|
||||||
|
|||||||
Reference in new issue
Block a user