C++插件类
2021/12/26 1:07:58
本文主要是介绍C++插件类,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
注册一个插件
#define NS_SCORER_PLUGIN_REGISTER(name, cls) CTOOL_PLUGIN_REGISTER(ns::SearchScorerPluginMgr, name, cls)
search scorer插件
class SearchScorerPlugin : public Plugin { public: // 信息初始化 bool Init() { return true;} virtual bool Init(RankParam *rank_param, pugi::xml_node &instance_node) { const char *instance_name = instance_node.attribute("name").value(); name_ = string(instance_name); const char *output_key = instance_node.attribute("output_key").value(); output_key_ = string(output_key); return LoadConfig(rank_param, instance_node); } // 加载配置文件 virtual bool LoadConfig(RankParam *rank_param, pugi::xml_node &instance_node) = 0; // 获取ScorerParam virtual ScorerParam *GetScorerParam(SearchSession *session) { ScorerParam *param = new ScorerParam(session); return param; } // query预处理 virtual bool ProcessQuery(SearchSession *session, ScorerParam *param) { return true; } // 打分+输出 virtual double ProcessDoc(s::DocValue *doc, ScorerParam *param, int index) { double score = CalScore(doc, param, index); if (output_key_.length() > 0) { doc->SetParam(output_key_, score); } return score; } // 打分 virtual double CalScore(s::DocValue *doc, ScorerParam *param, int index) = 0; protected: string name_; string output_key_; }; typedef PluginMgr<SearchScorerPlugin> SearchScorerPluginMgr;
注册插件宏定义
#define CTOOL_PLUGIN_REGISTER(mgr_name, name, cls) \ class RegisterPlugin##name##cls { \ public: \ RegisterPlugin##name##cls () { \ mgr_name::GetInstance()->Register(#name, new cls); \ } \ }; \ RegisterPlugin##name##cls ___g_cRegisterPlugin##name##cls; \
插件基础类
class Plugin { public: virtual bool GlobalInit() {return true;} // 全局初始化,进程级,在注册插件时调用 virtual bool Init() {return true;} // 插件初始化接口 virtual void Reset() { } // 重置本插件中间结果 virtual Plugin *NewInstance() = 0; // 创建一个新的插件 };
插件管理器
template<class _Tp> class PluginMgr { // 获取新实例 _Tp *NewInstance(string name) { string temp_name = strings::ToLowerCase(name); typename map<string, _Tp *>::iterator itr = class_map_.find(temp_name); if (itr != class_map_.end()) { _Tp *tp = (_Tp *) itr->second->NewInstance(); if (tp->Init()) { // 这里要实始化 return tp; } delete tp; } return NULL; } // 获取所有注册名 CStringList GetAllName() { CStringList name_list; typename map<string, _Tp *>::iterator itr = class_map_.begin(); for (; itr != class_map_.end(); itr++) { name_list.push_back(itr->first); } return name_list; } // 注册插件 void Register(string name, _Tp *cls) { string temp_name = strings::ToLowerCase(name); ScopeLock scope_lock(lock_); class_map_[temp_name] = cls; } // 全局初始化 bool GlobalInit() { ScopeLock scope_lock(lock_); typename map<string, _Tp *>::iterator itr = class_map_.begin(); for (; itr != class_map_.end(); itr++) { if (!itr->second->GlobalInit()) { return false; } } return true; } // 获取单例 static PluginMgr<_Tp> *GetInstance() { static SingletonHolder<PluginMgr<_Tp> > inst; return inst.Get(); } protected: SpinLock lock_; // 锁 map<string, _Tp *> class_map_; // 类型和实例指针map };
这篇关于C++插件类的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享