【大话QT之四】ctkPlugin插件系统实现项目插件式开发

2023-11-06

插件式开发体会:

        自开始写【大话QT】系列就开始接触渲染客户端的开发,说是开发不如更多的说是维护以及重构,在接手这块的东西之前自己还有点犹豫,因为之前我一直认为客户端嘛,没什么技术含量,总是想做比较有挑战性的,为了这周总还专门找我谈了谈,算是“安抚”民心吧。正式谈话过后,我才决定接手渲染客户端的开发。

        渲染客户端的所有构成均是采用开源框架拼凑起来的整体,细分它的组成大致包含以下开源模块,简单描述:

        1> CTKPlugin插件系统框架。负责整个项目的架构,决定了项目采用插件形式开发维护。

        2> Google protocol buffer。负责定义项目的通信协议,它是google内部使用的协议架构,最大的优点是:实现高效,向下兼容的通信协议。

        3> Zeromq框架:负责项目中的网络通信,用于高性能网络编程。

        4> 日志系统。负责项目中所有日志的输出。

        其中,最为关键的就是CTKPlugin插件系统,它决定了项目的整体架构——采用插件式开发。经过这么多天的维护开发也深深的感受到这种插件式开发的方式带来的好处。以前,总是从课本上读到所谓的理想的“热插拔”式的插件开发,而我总是不以为然,我的意识里一个项目的开发多多少少都是臃肿的,在使用了这种插件式的开发方式后,突然感觉软件的开发、维护、升级变得很容易,下面说一下我体会到的几点好处:

        1. 开发工作由之前的人等人变为并行开发。项目中插件系统分为两大部分:基础插件与应用插件,基础插件即通用插件,在其它插件系统中都要使用到的,比如:日志插件在每个其它插件中都会被使用;而应用插件之间则是相互独立的,比如:登录插件、文件管理插件等。基础插件一般是一些开源库,只需要我们编译出来使用即可,基本不需要我们自行开发;而应用插件功能的独立性决定了它们之间不会相互调用(业务整合插件除外),这样多个人员就可以独立开发,每个人负责一个独立的插件,项目进度会大大加快、周期缩短。

        2. 测试案例容易编写,插件功能很方便得到验证。在一个插件的初始版本完成后,可以很方便的编写测试用例,来验证插件提供的功能性。由于插件系统最终提供的是动态链接库dll(windows下),而测试用例则可以建立为应用工程或界面工程,提供程序入口,加载调用插件中提供的方法。而且,测试用例可以保存在项目中(不会最终发布,最终发布的是插件的dll),如果将来插件使用出现问题,或者需要添加其它功能,或者升级均可以利用测试案例重新快速测试验证。

       3. 系统业务逻辑变得异常清晰。如果项目不采用插件方式开发,每个功能均会杂糅在一起,无论是开发人员或者将来加入到项目开发的人都无法很快的了解业务流程,在分析这个功能的时候又涉及到那个功能。而采用插件式开发方式则每个业务逻辑很清晰明了,如果将来要调试3dmax的渲染模块,那么只需要阅读3dmax渲染插件就可以了,而且结合测试案例,很容易就可以上手。

        上面就是这段时间以来针对项目采用插件系统开发的几点体会。

CTKPlugin插件系统介绍:

                                             

        在CTKPlugin插件系统中要清晰地理解一个概念:插件是以服务的方式提供功能。每一个插件都有它的生命周期,在插件初始化的时候它会将自己的唯一实例注册到插件系统中作为服务提供,即上图中的register阶段。而当另一个插件需要使用到该插件提供的服务的时候就需要通过getService的方式获取。下面通过代码简单说明一下一个插件是如何想CTKPlugin系统中注册服务以及其它插件是如何使用该服务的:

        1.  插件服务注册

              每一个插件的实现都必须实现一个插件的声明周期类,它继承自CTKPlugin中的ctkPluginActivator,在ctkPluginActivator中定义了start与stop虚函数,插件的声明周期类必须要实现start与stop,实现服务的注册。        

[cpp]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. class LHAuthPlugin : public QObject, public ctkPluginActivator  
  2. {  
  3.     Q_OBJECT  
  4.     Q_INTERFACES(ctkPluginActivator)  
  5.   
  6. public:  
  7.     void start(ctkPluginContext *Context);  
  8.     void stop(ctkPluginContext *Context);  
  9.   
  10. private:  
  11.     LHAuth *m_Auth;  
  12. };  
      实现类:

[cpp]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. void LHAuthPlugin::start(ctkPluginContext *Context)  
  2. {  
  3.     m_Auth = new LHAuth();  
  4.     Context->registerService(QStringList("LHAuthInterface"), m_Auth);  
  5. }  
  6.   
  7. void LHAuthPlugin::stop(ctkPluginContext *Context)  
  8. {  
  9.     Q_UNUSED(Context)  
  10.     if (m_Auth)  
  11.     {  
  12.         delete m_Auth;  
  13.         m_Auth = 0;  
  14.     }  
  15. }  
        其中:registerService即向CTKPlugin插件系统中注册该插件的唯一实例,而stop则是插件声明周期的终止。

        2. 使用其它插件提供的服务

        在其它模块中如果想使用登录认证插件,则在其它模块的Init阶段完成登录认证模块的加载,并完成初始化的功能:

[cpp]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. //! 初始化登录模块  
  2. ctkServiceReference refAuth= d->m_PluginContext->getServiceReference("LHAuthInterface");  
  3. d->m_AuthInterface = (qobject_cast<LHAuthInterface *>(d->m_PluginContext->getService(refAuth)));  
  4. if (!d->m_AuthInterface ||  
  5.         (d->m_AuthInterface->Init(d->m_Parameters) != LH_SUCCESS) ||  
  6.         (d->m_AuthInterface->CreateInstance(varInstance, d->m_Parameters) != LH_SUCCESS))  
  7. {  
  8.     qDebug()<<QObject::tr("Module %1 is invalid").arg("com.lht.auth");  
  9.     return LH_FAILURE;  
  10. }  
  11. else  
  12.     d->m_nAuthInstance = varInstance.toInt();  
        getServiceReference()即在CTKPlugin插件系统中获取LHAuthInterface服务。在初始化完成之后,就可以利用m_AuthInterface->Login()来使用登录认证插件提供的功能了。

项目如何使用插件式开发:

        

       如上图所示,只是我这个项目本身实现插件系统功能的一个基本架构,相信不同的人使用会探索出更加有效,更加方便的使用方式。

       每个项目都会有它的入口,我们不妨称之为portal,在portal中实现的功能很简单,最主要的就是完成CTKPlugin系统的初始化工作,待ctkplugin初始化完成之后首先加载lht_controller插件,lht_controller插件是很重要的一个插件,它主要负责完成其它所有应用插件的加载工作,如上图所示,它加载了lht_login登录插件、lht_mayaMaya渲染插件、lht_log日志插件、lht_goldenfarm渲染客户端插件(业务逻辑插件),然后执行业务逻辑插件,即lht_goldenfarm,而在lht_goldenfarm中根据业务逻辑实现不同的功能,调用不同的插件。

        看上面的架构,很清晰明了,对于系统的维护很方便、容易。

本章总结:

        好了,以上就是我这段时间开发收获到的东西,很多东西都是我以前开发中不注意的,现在慢慢当成规则严格要求自己,争取让自己的开发更加规范。

        只有不断总结才能不断进步,还是验证了周总的那句话:“还是太年轻啊!!”。



FROM:  http://blog.csdn.net/houqd2012/article/details/23875279?utm_source=tuicool&utm_medium=referral

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【大话QT之四】ctkPlugin插件系统实现项目插件式开发 的相关文章

  • 一文搞懂Java中的继承(父类与子类间的联系)+实例分析

    前言 子类可以继承父类 除私有化外 的全部属性和方法 当然父类的构造方法也不可以被继承 只能使用super来调用 对于父类的默认无参构造方法 子类会默认调用 但对于父类的有参构造 子类只能使用super来显示调用 且super调用的这行代码
  • shell函数

    定义与调用函数 student myhost function a echo a function student myhost a a function student myhost b echo a function student m
  • [Machine Learning & Algorithm] 随机森林(Random Forest)

    1 什么是随机森林 作为新兴起的 高度灵活的一种机器学习算法 随机森林 Random Forest 简称RF 拥有广泛的应用前景 从市场营销到医疗保健保险 既可以用来做市场营销模拟的建模 统计客户来源 保留和流失 也可用来预测疾病的风险和病
  • 什么是Windows安全模式?Windows安全模式详解

    安全模式是Windows 操作系统中的一种诊断启动模式 用于在操作系统无法正常启动时获取有限的Windows访问权限 正常模式与安全模式相反 它以其典型方式启动Windows 注意 安全模式在macOS上称为安全启动 术语 安全模式 也指用
  • 【C++初阶】引用

    一 概念 引用就是取别名 在语法上它不会开空间 而是和它引用的变量共用同一块空间 对引用的操作也就是对原来变量的操作 就像现实生活中给人取外号一样 不管是喊外号还是本名 指的都是那个人 二 引用特性 1 引用类型必须和引用实体是同种类型的
  • python打包系列1 - pyinstaller打包遇坑笔记

    最近工作中需要将python打包成exe 我是用pyinstaller打包 这期间遇到了不少坑 最终打包成功 并在其他windows机器正常运行 环境 我打包的python代码 依赖了opencv numpy以及若干第三方库 MVS 相机接
  • k8s错误CrashLoopBackOff

    序言 2020年1月1日就收到一个故障 注定不是平凡的一年 所以呢 决定年后戒烟 至于是哪一年的年后 我没说 哈哈哈 CrashLoopBackoff 在创建一个pod之后 出现一个报错 都是按照套路来的 怎么可能会报错呢 查看一下相关的日
  • ViewerBase::renderingTraversals()的简易理解

    前两篇说到了camera用来剔除 context用来渲染 多线程渲染就是把cpu尽可能的分配给context 如果土豪的话 在剔除过程也分配cpu 另外 也要注意到过期请求数据不处理 当然 首先要获取场景 摄像机和上下文 现在看下摄像机剔除
  • JavaScript——冒泡排序、选择排序

    目录 一 冒泡排序 二 选择排序 一 冒泡排序 冒泡算法是最易懂的排序算法 它实现简单 但是效率较低 适合n较小时使用 基本思路 依次比较相邻的两个数 如果不符合排序规则 则调换两个数的位置 先比较一轮一次 再用循环比较一轮多次 得到最大
  • NumPy 库在 Python 中的妙用之NumPy处理数字

    这篇文章讨论了安装 NumPy 然后创建 读取和排序 NumPy 数组 NumPy 即 Numerical Python 是一个库 它使得在 Python 中对线性数列和矩阵进行统计和集合操作变得容易 我在 Python 数据类型的笔记中介

随机推荐

  • Java Socket 参数详解 setKeepAlive

    Java socket 编程中有个 keepalive 选项 看到这个选项经常会误解为长连接 不设置则为短连接 实则不然 socket 连接建立之后 只要双方均未主动关闭连接 那这个连接就是会一直保持的 就是持久的连接 keepalive
  • ajax设置定时请求第一次到页面没数据,第二次请求才有数据解决

    最近在做页面的时候发现前端HTML页面通过ajax请求后台数据 设置了十五秒的定时请求 每次第一次到页面的时候都没有数据 然后等十五秒后就有数据刷新出来 那别人第一次访问就没数据 也太尴尬了 然后问问度娘找到了解决办法 下面就写一个模板吧
  • 电视的网络显示没有连接服务器,网络电视显示网络未连接怎么回事

    原因 1 网线与路由器和电视机的网络接口是否接触不良导致电视机断网 2 路由器是否运行错误或者出现故障导致电视机断网 3 网络服务提供商的网络线路 服务器是否出现中断 故障导致路由器也无法连接网络 这种情况下电视机也必然断网 需要联系网络服
  • 梦之光芒Monyer (全关解析)

    目录 前言 第0关 描述 过程 第1关 描述 过程 第2关 描述 过程 第3关 描述 过程 第4关 描述 过程 第5关 描述 过程 第6关 描述 过程 第7关 描述 过程 第8关 描述 过程 第9关 描述 过程 第10关 描述 过程 第11
  • Pycharm ——1分钟设置成【汉化版】

    目录 操作步骤 搜索不到的解决方案 哈喽 大家好丫 你们的小郭子又来啦 今天我们继续聊一聊 在网上找如何将pycharm汉化 话不多说 直接上干货 嘻嘻嘻 操作步骤 打开settings 设置 然后在里面搜索plugins 插件 进入界面之
  • Javascript基本语法,与html,C 语言比较

    1 在中进行显示 2 与C语言比较 a 当进行加减乘除运算时 即把C语言中 printf 改为 document write b 当判断对错 用布尔类型 如 var a 1 b 2 document write a
  • Scanner对象

    Scanner对象 之前我们学的基本语法中我们没有实现程序和人的交互 但是Java给我们提供了这样一个工具类 我们可以获取用户的输入 java util Scanner是Java5的新特征 我们可以通过Scanner类来获取用户的输入 基本
  • 【电路设计】AD快速敷铜技巧

    推荐一款 求职面试 刷题学习 的神器 点击跳转 快来看看吧 参考帖子 http bbs eeworld com cn forum php mod viewthread tid 465056 建立一个工程 添加原理图和PCB文档 原理图上简单
  • 【C++】类和对象-封装

    目录 属 性 和 行 为 作 为 整 体 封装的意义 封装意义1 设 计 学 生 类 通过实例化对象对属性进行赋值 再使用类的行为 通过行为对属性进行赋值操作 访 问 权 限 struct 和 class 区别 成 员 属 性 私 有 化
  • 这些道理不懂,你注定就是穷打工的命

    看完之后 心里有点小鸡冻 呵呵 言辞有点激烈 顶住 来自世界经理人 同样是打工 为什么你一个月只有2 3K 而唐骏的身价却可以高达10亿 或许你会反驳我 说人人都成为唐骏的概率有多大 的确 人人都成为唐骏的确不现实 但是 经过努力 月薪达到
  • RNN/LSTM循环神经网络讲解

    转自 https zhuanlan zhihu com p 123211148 一 什么是循环神经网络 循环神经网络 Rerrent Neural Network RNN 历史啊 谁发明的都不重要 说了你也记不住 你只要记住RNN是神经网络
  • 给出一百分制成绩,要求输出成绩等级

    给出一百分制成绩 要求输出成绩等级 A B C D E 90分以上为 A 80 90分为 B 70 79分为 C 60 69分为 D 60分以下为 E 使用if语句 我自己的做法 include
  • JavaScript math对象

    今天我们来学习JavaScript的math对象 下面跟我来学习一下吧 Math对象和其他对象不同 它不是一个构造函数 它属于一个工具类不用创建对象 它里面封装了数 学运算相关的属性和方法 例如 Math PI 表示圆周率 约等于3 141
  • 匹配11位手机号码的正则表达式

    最近在做一个即时通讯的项目 首先是注册登录界面 项目需求是通过用户输入的手机号码获取一个4位数的验证码来完成注册 那么 问题来了 如何判断用户输入的手机号码是合法的正确的11位手机号码呢 这些简单的问题就在前端判断好了再post给后台 没必
  • 初级测开面试题分享(有文档)

    今天分享一下测试群友发出的面试 小伙伴可以看看自己能答出来几题 当然答案已经整理好了 直接点击文末小卡片就能领取了 同时 我也为大家准备了一份软件测试视频教程 含面试 接口 自动化 性能测试等 就在下方 需要的可以直接去观看 软件测试视频教
  • linux 删除文件

    http blog csdn net taiyang1987912 article details 41488395 http www 360doc com content 16 0325 23 532901 545276975 shtml
  • 3.5 Makefile的重建

    一 Makefile重建是什么 Makefiles是一种用于构建和维护软件项目的工具 它们是文本文件 包含了一系列规则和指令 告诉计算机如何编译 链接和生成可执行文件 当我们使用make命令时 它会检测当前目录下的makefile文件 并根
  • 【Hello Algorithm】二叉树相关算法

    本篇博客介绍 介绍二叉树的相关算法 二叉树相关算法 二叉树结构 遍历二叉树 递归序 二叉树的交集 非递归方式实现二叉树遍历 二叉树的层序遍历 二叉树难题 二叉树的序列化和反序列化 lc431 求二叉树最宽的层 二叉树的后继节点 谷歌面试题
  • 下载 安装npm nodejs yarn详细步骤

    一 安装nodejs 1 下载NodeJs 点击以下链接进入NodeJs官网 https nodejs org zh cn 其他下载 先前已发布版本 找到自己需要的版本 温馨提示 如果之前电脑有安装过Node js的话建议先把之前的文件删干
  • 【大话QT之四】ctkPlugin插件系统实现项目插件式开发

    插件式开发体会 自开始写 大话QT 系列就开始接触渲染客户端的开发 说是开发不如更多的说是维护以及重构 在接手这块的东西之前自己还有点犹豫 因为之前我一直认为客户端嘛 没什么技术含量 总是想做比较有挑战性的 为了这周总还专门找我谈了谈 算是