Preskočiť na obsah

Prehľad architektúry

Podsystém zásuvných modulov tvoria tri komponenty, všetky v priečinku Components/:

Komponent Viditeľnosť Zodpovednosť
PluginApi Verejný Čisté abstraktné rozhrania a hodnotové typy. Žiadne Qt, žiadna Scintilla, žiadne interné hlavičky MTE — iba štandardná knižnica.
PluginHost Interný Načítava, vlastní a obsluhuje zásuvné moduly. Qt je tu implementačný detail (v zákulisí používa QPluginLoader).
Plugins Vlastné Ukážkové a vstavané zásuvné moduly; každý je vlastným cieľom CMake závislým iba od PluginApi (a od Qt, keď sa používa natívny backend).

Princípy návrhu

  • Kontrakt nezávislý od backendu. Všetky typy PluginApi sa nachádzajú v priestore namespace MTE::plugin a nesmú zahŕňať žiadnu hlavičku z Qt, Scintilly ani internú hlavičku MTE. Práve to umožňuje budúcemu backendu v Pythone naplniť ten istý kontrakt bez odporu zo strany Qt.
  • Žiadne typy tretích strán naprieč verejným API. Zásuvné moduly nikdy nevidia typy zo Scintilly ani z Qt; hostiteľ prispôsobuje interné IEditorView verejnému IEditorService.
  • RAII všade. Registrácia príkazu, položky ponuky, ukotviteľného panela či odberu udalostí vracia token, respektíve popisovač odberu. Jeho zničením sa príspevok odregistruje. Zásuvné moduly si svoje tokeny držia ako členy, takže sa v shutdown() všetko zruší automaticky.

Životný cyklus

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

class IPlugin {
public:
    virtual ~IPlugin() = default;
    virtual PluginInfo info() const = 0;
    virtual bool       initialize(IPluginContext& ctx) = 0;
    virtual void       shutdown() noexcept = 0;
};
  • info() vracia metaúdaje typu POD (id, name, version, vendor, description, apiVersion).
  • initialize(ctx) dostáva lokátor služieb IPluginContext. Zásuvný modul si vezme služby, ktoré potrebuje, a zaregistruje svoje príkazy, ponuky, panely a odbery udalostí.
  • shutdown() beží pri odchode; keďže sú príspevky tokenmi RAII, predvolené zrušenie zvyčajne znamená iba nechať členy zaniknúť.

Žiadne načítanie za behu

Zapnutie, vypnutie, inštalácia aj odinštalovanie zásuvného modulu sa prejavia až pri ďalšom spustení. Hostiteľ nikdy nenačítava ani neodpája kód zásuvných modulov počas behu — vďaka tomu ostáva model jednoduchý a obchádza sa tým problém Windows s tým, že „načítanú knižnicu DLL nemožno odstrániť“.

Vyhľadávanie

Hostiteľ prehľadáva v tomto poradí:

  1. <exe-dir>/Plugins/ — dodávané vlastné zásuvné moduly.
  2. <AppLocalData>/Plugins/ — inštalačný priečinok pre daného používateľa.
  3. Cesty z premennej prostredia MTE_PLUGIN_PATH.

V každom priečinku sa hľadajú samostatné knižnice a jedna úroveň priamych podpriečinkov (rozloženie <id>/ pre jednotlivé moduly, aké vytvára inštalátor). Vyhľadávanie nezostupuje hlbšie.