L’interface principale de n’importe quel plugin
Commençons à implémenter le plugin lui-même. Le type de l’interface principale dépend évidemment du type de plugin, mais ils sont tous basés sur l’interface générale IPluginBase
avec comptage de références, qui effectue des tâches communes (et très simples) pour tous les plugins. Chaque plugin a un objet (également avec comptage de liens) auquel il appartient. Afin d’effectuer une gestion intelligente du cycle de vie des plugins, tout plugin doit être en mesure de stocker des informations sur le propriétaire et de les transmettre au gestionnaire de plugins sur demande. Cela signifie que chaque plugin doit implémenter les deux méthodes triviales setOwner()
et getOwner()
contenues dans l’interface IPluginBase
. Les méthodes dépendantes du type de plugin sont certainement plus intéressantes — elles sont discutées dans la partie description de l’interface.
Jetons un coup d’œil à la partie implémentation typique de n’importe quel plugin (j’utilise spécifiquement le type SomePlugin
inexistant ici) :
class MyPlugin : public ISomePluginImpl<MyPlugin, CheckStatusWrapper>
{
public:
explicit MyPlugin(IPluginConfig* cnf) noexcept
: config(cnf), refCounter(0), owner(NULL)
{
config->addRef();
}
...
Le constructeur reçoit l’interface de configuration du plugin en tant que paramètre. Si vous comptez configurer le plugin d’une manière ou d’une autre, il est recommandé d’enregistrer cette interface dans votre plugin et de l’utiliser plus tard. Cela vous permettra d’utiliser le style de configuration global de Firebird, ce qui permettra aux utilisateurs d’avoir une configuration familière et de minimiser le codage. Bien sûr, lors de l’enregistrement d’une interface de lien, il est préférable de ne pas oublier d’y ajouter un lien. N’oubliez pas non plus de définir le nombre de liens sur 0 et le propriétaire du plugin sur NULL
.
~MyPlugin()
{
config->release();
}
Le destructeur libère l’interface de configuration. Notez que nous ne modifions pas le nombre de liens de notre propriété car elle ne nous appartient pas.
// IRefCounted implementation
int release()
{
if (--refCounter == 0)
{
delete this;
return 0;
}
return 1;
}
void addRef()
{
++refCounter;
}
Il s’agit d’une implémentation tout à fait typique d’un objet avec comptage de références.
// IPluginBase implementation
void setOwner(IReferenceCounted* o)
{
owner = o;
}
IReferenceCounted* getOwner()
{
return owner;
}
Comme promis, l’implémentation d’IPluginBase est triviale.
// ISomePlugin implementation
// … here go various methods required for particular plugin type
private:
IPluginConfig* config;
std::atomic_int refCounter;
IReferenceCounted* owner;
};
Dans cet exemple, la partie formelle de l’implémentation de l’interface principale du plugin est terminée. Après avoir ajouté des méthodes spécifiques au type (et peut-être écrit du code pour les rendre utiles), l’interface est prête.