Pular para conteúdo

Visão geral da arquitetura

O subsistema de plugins é construído a partir de três componentes, todos sob Components/:

Componente Visibilidade Responsabilidade
PluginApi Pública Interfaces puramente abstratas e tipos de valor. Sem Qt, sem Scintilla, sem cabeçalhos internos do MTE — apenas a biblioteca padrão.
PluginHost Interna Carrega, possui e despacha os plugins. O Qt é um detalhe de implementação aqui (ele usa QPluginLoader nos bastidores).
Plugins Oficiais Plugins de exemplo e integrados; cada um é o próprio alvo do CMake, dependendo apenas do PluginApi (e do Qt, ao usar o backend nativo).

Princípios de design

  • Contrato independente de backend. Todos os tipos do PluginApi ficam no namespace MTE::plugin e não podem incluir nenhum cabeçalho do Qt, do Scintilla ou interno do MTE. É isso que permite que um futuro backend Python atenda ao mesmo contrato sem o atrito do Qt.
  • Nenhum tipo de terceiros cruza a API pública. Os plugins nunca veem tipos do Scintilla ou do Qt; o host faz a adaptação entre o IEditorView interno e o IEditorService público.
  • RAII em toda parte. Registrar um comando, um item de menu, um painel acoplável ou uma assinatura de evento devolve um token/identificador. Destruí-lo cancela o registro da contribuição. Os plugins guardam os tokens como membros, de modo que tudo é desmontado automaticamente no shutdown().

Ciclo de vida

Todo plugin implementa uma única interface, IPlugin:

class IPlugin {
public:
    virtual ~IPlugin() = default;
    virtual PluginInfo info() const = 0;
    virtual bool       initialize(IPluginContext& ctx) = 0;
    virtual void       shutdown() noexcept = 0;
};
  • info() devolve metadados POD (id, name, version, vendor, description, apiVersion).
  • initialize(ctx) recebe um localizador de serviços IPluginContext. O plugin pega os serviços de que precisa e registra os comandos, menus, painéis e assinaturas de evento dele.
  • shutdown() roda na saída; como as contribuições são tokens RAII, o desmonte padrão costuma ser apenas deixar os membros se destruírem.

Sem recarga a quente

Ativar, desativar, instalar e desinstalar um plugin passam a valer todos na próxima inicialização. O host nunca carrega nem descarrega código de plugin enquanto está em execução — isso mantém o modelo simples e contorna o problema do Windows de "não é possível apagar uma DLL carregada".

Descoberta

O host varre, nesta ordem:

  1. <exe-dir>/Plugins/ — plugins oficiais incluídos.
  2. <AppLocalData>/Plugins/ — o diretório de instalação por usuário.
  3. Os caminhos da variável de ambiente MTE_PLUGIN_PATH.

Cada diretório é varrido em busca de bibliotecas soltas e de um nível de subdiretórios imediatos (o layout <id>/ por plugin que um instalador produz). A descoberta não desce mais fundo.