CTK-服務追蹤


一、簡介

服務追蹤:如果想在B插件里使用A服務,可以專門寫一個類繼承ctkServiceTracker,在這個類里完成對A服務的底層操作,然后在B插件里通過這個類提供的接口來使用回收A服務。

 

 

 注意ctkServiceTracker和A服務應該是一起的,這里有點像服務工廠。優點就是獲取服務的代碼簡單,不用各種判斷空指針【實際使用中感覺缺點大於優點】

 

二、新建A服務

這里直接使用以前服務工廠里的那個打印服務【通過服務工廠訪問服務】:https://www.cnblogs.com/judes/p/13237502.html

 

 三、新建ctkServiceTracker子類Tracker

主要實現以下三個接口,注意ctkServiceTracker是一個模板類,需要指明主要追蹤的服務類名

 

 

tracker.h

#ifndef TRACKER_H
#define TRACKER_H
#include "ctkServiceTracker.h"
#include "absprintserver.h"
#include "ctkPluginContext.h"
class Tracker : public ctkServiceTracker<AbsPrintServer*>
{
public:
    Tracker(ctkPluginContext* context);
protected:
    AbsPrintServer* addingService(const ctkServiceReference& reference) override;
    void modifiedService(const ctkServiceReference& reference, AbsPrintServer* service) override;
    void removedService(const ctkServiceReference& reference, AbsPrintServer* service) override;
private:
    ctkPluginContext* context;
};

#endif // TRACKER_H

tracker.cpp

#include "tracker.h"


Tracker::Tracker(ctkPluginContext *context)
    : ctkServiceTracker<AbsPrintServer*> (context)
{

}

AbsPrintServer *Tracker::addingService(const ctkServiceReference &reference)
{
    AbsPrintServer* service = static_cast<AbsPrintServer*>(ctkServiceTracker::addingService(reference));
    return service;
}

void Tracker::modifiedService(const ctkServiceReference &reference, AbsPrintServer* service)
{
    ctkServiceTracker::modifiedService(reference,service);
}

void Tracker::removedService(const ctkServiceReference &reference, AbsPrintServer* service)
{
    ctkServiceTracker::removedService(reference,service);
}

關於這個追蹤類,什么時候建立呢?這個問題繞了我很久,經過思考應該有如下幾種方式。

1、可以在封裝A服務的時候就建立,作為一種工具向外提供,但是不應該被編譯進插件中,它並不是插件的功能而是訪問插件的工具;

2、也可以在B插件中建立,完全和A服務獨立開,作為訪問A服務的一種手段;

3、單獨建立一個空工程,為項目中的所有服務建立對應的追蹤類,然后放在同一個文件夾中,其他想要的自己使用就行。

但是要注意:B插件如果想要使用A服務,需要tracker.h、tracker.cpp、A服務的接口類。

 

四、新建B插件工程

1、接口類

abslogtracker.h

#ifndef ABSLOGTRACKER_H
#define ABSLOGTRACKER_H

#include <QObject>
class AbsLogTracker{
public:
    virtual ~AbsLogTracker(){}
    virtual void log(QString) = 0;
};
Q_DECLARE_INTERFACE(AbsLogTracker,"judesmorning.zxy.AbsLogTracker")

#endif // ABSLOGTRACKER_H

2、實現類

imlog.h

#ifndef IMLOG_H
#define IMLOG_H
#include <QObject>
#include "abslogtracker.h"
#include "tracker.h"
class ImLog : public QObject, public AbsLogTracker
{
    Q_OBJECT
    Q_INTERFACES(AbsLogTracker)
public:
    ImLog(Tracker* tracker);
    void log(QString info) override;
private:
    Tracker* tracker;
};

#endif // IMLOG_H

imlog.cpp

#include "imlog.h"
#include <QDebug>
ImLog::ImLog(Tracker* tracker)
    : tracker(tracker)
{

}

void ImLog::log(QString info)
{
    AbsPrintServer* service = static_cast<AbsPrintServer*>(tracker->getService());
    if (service != Q_NULLPTR)
    {
        service->print("test plugin with tracker:"+info);
    }
    else
    {
        qDebug()<<"get AbsPrintServer from tracker failed";
    }
}

因為真正使用到A服務的地方就是B插件的實現類里,所以通過構造函數把tracker給傳進去。這里的tracker是在激活類里new的,因為context是從實現類里傳進來的,根據這個思路也可把context傳到B的實現類里,再在實現類里new出tracker

3、激活類

activator.h

#ifndef ACTIVATOR_H
#define ACTIVATOR_H
#include <QObject>
#include "tracker.h"
#include "imlog.h"
#include "ctkPluginActivator.h"
#include "ctkPluginContext.h"
class Activator : public QObject , public ctkPluginActivator
{
    Q_OBJECT
    Q_INTERFACES(ctkPluginActivator)
    Q_PLUGIN_METADATA(IID "AbsLogTracker")
public:
    Activator();
    void start(ctkPluginContext* context) override;
    void stop(ctkPluginContext* context)override;
private:
    QScopedPointer<Tracker> p_tracker;
    QScopedPointer<ImLog> p_plugin;
    ctkServiceRegistration m_registration;
};

#endif // ACTIVATOR_H

activator.cpp

#include "activator.h"

Activator::Activator()
{

}

void Activator::start(ctkPluginContext *context)
{
    p_tracker.reset(new Tracker(context));
    p_tracker->open();

    p_plugin.reset(new ImLog(p_tracker.data()));
    m_registration = context->registerService<AbsLogTracker>(p_plugin.data());
}

void Activator::stop(ctkPluginContext *context)
{
    Q_UNUSED(context);
    m_registration.unregister();
    p_tracker->close();
    p_tracker.reset(nullptr);
    p_plugin.reset(nullptr);
}

 

 

ps:

1、在B插件使用A服務的時候,一定要把tracker源文件加入到B插件工程中去,即.pro里要有它們,不能只include,不然會報錯

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM