Основной интерфейс любого плагина
Приступим к реализации самого плагина. Тип основного интерфейса зависитот типа плагина, что очевидно, но все они основаны на общем интерфейсеIPluginBase
с подсчётом ссылок, который выполняет общие для всехплагинов (и очень простые) задачи. Каждый плагин имеет некоторый (тоже сподсчётом ссылок) объект, которому принадлежит этот плагин. Чтобывыполнять интеллектуальное управление жизненным циклом плагинов, любойплагин должен иметь возможность хранить информацию о владельце исообщать её диспетчеру плагинов по запросу. Это означает, что каждыйплагин должен реализовывать два тривиальных метода setOwner()
иgetOwner()
, содержащиеся в интерфейсе IPluginBase
. Зависимые от типаплагина методы, безусловно, более интересны — они обсуждаются в частиописания интерфейсов.
Давайте рассмотрим типичную часть реализации любого плагина (здесь яспециально использую несуществующий тип SomePlugin
):
class MyPlugin : public ISomePluginImpl<MyPlugin, CheckStatusWrapper>
{
public:
explicit MyPlugin(IPluginConfig* cnf) throw()
: config(cnf), refCounter(0), owner(NULL)
{
config->addRef();
}
...
Конструктор получает в качестве параметра интерфейс конфигурацииплагина. Если вы собираетесь конфигурировать плагин каким-то образом, торекомендуется сохранить этот интерфейс в вашем плагине и использоватьего позже. Это позволит вам использовать общий стиль конфигурацииFirebird, позволяя пользователям иметь привычную конфигурацию и свести кминимуму написание кода. Конечно, при сохранении какого-либо ссылочногоинтерфейса лучше не забывать добавлять ссылку на него. Также не забудьтеустановить счетчик ссылок в 0 и владельца плагина в NULL
.
~MyPlugin()
{
config->release();
}
Деструктор освобождает конфигурационный интерфейс. Обратите внимание: мыне меняем счетчик ссылок нашего владельца, потому что он принадлежитнам, а не мы принадлежим ему.
// IRefCounted implementation
int release()
{
if (--refCounter == 0)
{
delete this;
return 0;
}
return 1;
}
void addRef()
{
++refCounter;
}
Абсолютно типичная реализация объекта с подсчётом ссылок.
// IPluginBase implementation
void setOwner(IReferenceCounted* o)
{
owner = o;
}
IReferenceCounted* getOwner()
{
return owner;
}
Как и было обещано, реализация IPluginBase
тривиальна.
// ISomePlugin implementation
// … here go various methods required for particular plugin type
private:
IPluginConfig* config;
FbSampleAtomic refCounter;
IReferenceCounted* owner;
};
В этом примере формальная часть реализации основного интерфейса плагиназавершена. После добавления специфичных для типа методов (и, возможно,написания кода, чтобы сделать их полезным), интерфейс готов.