zoukankan      html  css  js  c++  java
  • 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,不然会报错

  • 相关阅读:
    结对作业
    小学算术题四则运算(升级)
    自动生成小学四则运算题目(Python实现)
    《基于CMMI的软件工程及实训指导》第一章 软件工程基础
    使用 python 进行微信好友分析
    中国大学排名
    python小程序测试
    爬虫测试
    体育竞技分析

  • 原文地址:https://www.cnblogs.com/judes/p/13278013.html
Copyright © 2011-2022 走看看