Přeskočit obsah

Přehled architektury

Subsystém zásuvných modulů je postaven ze tří komponent, všech pod Components/:

Komponenta Viditelnost Zodpovědnost
PluginApi Veřejná Čistě abstraktní rozhraní a hodnotové typy. Žádné Qt, žádná Scintilla, žádné vnitřní hlavičky MTE — jen standardní knihovna.
PluginHost Vnitřní Načítá, vlastní a obsluhuje zásuvné moduly. Qt je zde implementačním detailem (v zákulisí používá QPluginLoader).
Plugins Vlastní Ukázkové a vestavěné moduly; každý vlastní cíl CMake závislý jen na PluginApi (a na Qt, používá-li nativní backend).

Principy návrhu

  • Kontrakt nezávislý na backendu. Všechny typy PluginApi bydlí v namespace MTE::plugin a nesmí vkládat žádnou hlavičku Qt, Scintilly ani vnitřní hlavičku MTE. Právě to umožňuje budoucímu backendu v Pythonu naplnit tentýž kontrakt bez nesouladu s Qt.
  • Žádné typy třetích stran napříč veřejným rozhraním. Zásuvné moduly nikdy neuvidí typy Scintilly ani Qt; hostitel překlenuje vnitřní IEditorView a veřejné IEditorService.
  • RAII všude. Registrace příkazu, položky nabídky, ukotvitelného panelu či odběru událostí vrací token nebo popisovač odběru. Jeho zničením se příspěvek odregistruje. Moduly si tokeny drží jako členy, takže se ve shutdown() vše strhne automaticky.

Životní cyklus

Každý zásuvný modul implementuje jediné rozhraní, IPlugin:

class IPlugin {
public:
    virtual ~IPlugin() = default;
    virtual PluginInfo info() const = 0;
    virtual bool       initialize(IPluginContext& ctx) = 0;
    virtual void       shutdown() noexcept = 0;
};
  • info() vrací metadata typu POD (id, name, version, vendor, description, apiVersion).
  • initialize(ctx) dostává lokátor služeb IPluginContext. Modul si z něj vezme služby, které potřebuje, a zaregistruje své příkazy, nabídky, panely a odběry událostí.
  • shutdown() běží na odchodu; protože jsou příspěvky tokeny RAII, spočívá výchozí strhnutí obvykle jen v tom, že se členům umožní zaniknout.

Žádné načtení za běhu

Zapnutí, vypnutí, instalace i odinstalace zásuvného modulu se projeví až při příštím spuštění. Hostitel kód modulů za běhu nikdy nenačítá ani neuvolňuje — model tím zůstává jednoduchý a obchází se tak problém Windows »nelze smazat načtenou DLL«.

Hledání modulů

Hostitel prohledává v tomto pořadí:

  1. <exe-dir>/Plugins/ — dodávané vlastní moduly.
  2. <AppLocalData>/Plugins/ — instalační adresář pro uživatele.
  3. Cesty z proměnné prostředí MTE_PLUGIN_PATH.

Každý adresář se prohledá na volné knihovny a na jednu úroveň bezprostředních podadresářů (rozvržení <id>/ na modul, jaké vytváří instalátor). Hledání se hlouběji nezanořuje.