Saltar a contenido

Visión general de la arquitectura

El subsistema de plugins se construye a partir de tres componentes, todos ellos bajo Components/:

Componente Visibilidad Responsabilidad
PluginApi Pública Interfaces puramente abstractas y tipos de valor. Sin Qt, sin Scintilla, sin cabeceras internas de MTE: solo la biblioteca estándar.
PluginHost Interna Carga, posee y despacha los plugins. Qt es aquí un detalle de implementación (usa QPluginLoader entre bastidores).
Plugins Oficiales Plugins de ejemplo e integrados; cada uno es su propio objetivo de CMake, que depende únicamente de PluginApi (y de Qt, cuando se usa el backend nativo).

Principios de diseño

  • Contrato independiente del backend. Todos los tipos de PluginApi viven en namespace MTE::plugin y no deben incluir ninguna cabecera de Qt, de Scintilla ni interna de MTE. Eso es lo que permite que un futuro backend de Python satisfaga el mismo contrato sin la fricción de Qt.
  • Ningún tipo de terceros cruza la API pública. Los plugins nunca ven tipos de Scintilla ni de Qt; el anfitrión hace de adaptador entre el IEditorView interno y el IEditorService público.
  • RAII en todas partes. Registrar un comando, un elemento de menú, un panel acoplable o una suscripción a eventos devuelve un testigo o un identificador de suscripción. Destruirlo anula el registro de la aportación. Los plugins guardan sus testigos como miembros, de modo que todo se desmonta automáticamente en shutdown().

Ciclo de vida

Todos los plugins implementan una única interfaz, IPlugin:

class IPlugin {
public:
    virtual ~IPlugin() = default;
    virtual PluginInfo info() const = 0;
    virtual bool       initialize(IPluginContext& ctx) = 0;
    virtual void       shutdown() noexcept = 0;
};
  • info() devuelve metadatos POD (id, name, version, vendor, description, apiVersion).
  • initialize(ctx) recibe un localizador de servicios IPluginContext. El plugin toma los servicios que necesita y registra sus comandos, menús, paneles y suscripciones a eventos.
  • shutdown() se ejecuta a la salida; como las aportaciones son testigos RAII, el desmontaje predeterminado suele consistir simplemente en dejar que los miembros se destruyan.

Sin recarga en caliente

Activar, desactivar, instalar y desinstalar un plugin surten efecto todos en el siguiente arranque. El anfitrión nunca carga ni descarga código de plugins mientras se está ejecutando: eso mantiene el modelo simple y esquiva el problema de Windows de «no se puede borrar una DLL cargada».

Detección

El anfitrión examina, en este orden:

  1. <exe-dir>/Plugins/ — plugins oficiales incluidos.
  2. <AppLocalData>/Plugins/ — el directorio de instalación por usuario.
  3. Las rutas de la variable de entorno MTE_PLUGIN_PATH.

En cada directorio se buscan bibliotecas sueltas y un nivel de subdirectorios inmediatos (la disposición <id>/ por plugin que produce un instalador). La detección no baja más.