diff --git a/libsearch/pluginmanage/plugin-manager.cpp b/libsearch/pluginmanage/plugin-manager.cpp index 3bbb0c9..0ec7a6c 100644 --- a/libsearch/pluginmanage/plugin-manager.cpp +++ b/libsearch/pluginmanage/plugin-manager.cpp @@ -64,6 +64,7 @@ PluginManager::PluginManager(QObject *parent) : QObject(parent) case PluginInterface::PluginType::SearchTaskPlugin: { auto p = dynamic_cast(plugin); SearchTaskPluginManager::getInstance()->registerPlugin(p); + SearchTaskPluginManager::getInstance()->registerPluginPath(p->getCustomSearchType(), pluginsDir.absoluteFilePath(fileName)); break; } default: diff --git a/libsearch/pluginmanage/search-task-plugin-manager.cpp b/libsearch/pluginmanage/search-task-plugin-manager.cpp index 7867137..1dbd963 100644 --- a/libsearch/pluginmanage/search-task-plugin-manager.cpp +++ b/libsearch/pluginmanage/search-task-plugin-manager.cpp @@ -1,5 +1,6 @@ #include "search-task-plugin-manager.h" #include +#include #include "file-search-task.h" #include "file-content-search-task.h" @@ -83,3 +84,142 @@ void SearchTaskPluginManager::pluginSearch(QString customSearchType, std::shared Q_EMIT this->searchError(searchController.get()->getCurrentSearchId(), tr("plugin type: %1, is not registered!").arg(customSearchType)); } } + +bool SearchTaskPluginManager::startSearch(const QUuid &uuid, std::shared_ptr searchController, SearchType searchType, const QString &customType) +{ + if (m_managedPlugins.contains(uuid)) { + ManagedPlugin* managedPlugin = m_managedPlugins.value(uuid); + + SearchTaskPluginIface *plugin = nullptr; + if (searchType == SearchType::Custom) { + plugin = managedPlugin->externalPlugin(customType); + + } else { + plugin = managedPlugin->internalPlugin(searchType); + } + + if (plugin) { + plugin->startSearch(std::move(searchController)); + return true; + } + } + + return false; +} + +SearchTaskPluginIface *SearchTaskPluginManager::getPlugin(SearchType searchType, const QString& customType) +{ + SearchTaskPluginIface *searchPlugin = nullptr; + if (searchType == SearchType::Custom) { + if (m_loadedPluginPath.contains(customType)) { + QPluginLoader pluginLoader(m_loadedPluginPath.value(customType)); + QObject *plugin = pluginLoader.instance(); + if (plugin) { + searchPlugin = dynamic_cast(plugin); + } + } + + } else { + switch (searchType) { + case SearchType::File: + searchPlugin = new FileSearchTask(this); + break; + case SearchType::FileContent: + searchPlugin = new FileContentSearchTask(this); + break; + default: + break; + } + } + + return searchPlugin; +} + +void SearchTaskPluginManager::registerPluginPath(const QString& customType, const QString &pluginPath) +{ + if (!m_loadedPluginPath.contains(customType)) { + m_loadedPluginPath.insert(customType, pluginPath); + } +} + +SearchTaskPluginIface *SearchTaskPluginManager::initPlugins(const QUuid& uuid, SearchType searchType, const QString& customType) +{ + if (!m_managedPlugins.contains(uuid)) { + m_managedPlugins.insert(uuid, new ManagedPlugin(nullptr)); + } + + SearchTaskPluginIface *plugin = getPlugin(searchType, customType); + bool succeed = false; + if (searchType == SearchType::Custom) { + succeed = m_managedPlugins.value(uuid)->insertExternalPlugin(customType, plugin); + + } else { + succeed = m_managedPlugins.value(uuid)->insertInternalPlugin(searchType, plugin); + } + + return succeed ? plugin : nullptr; +} + +void SearchTaskPluginManager::destroyPlugins(const QUuid &uuid) +{ + if (m_managedPlugins.contains(uuid)) { + ManagedPlugin *managedPlugin = m_managedPlugins.value(uuid); + m_managedPlugins.remove(uuid); + + delete managedPlugin; + } +} + +ManagedPlugin::~ManagedPlugin() +{ + +} + +bool ManagedPlugin::insertInternalPlugin(const SearchType &searchType, SearchTaskPluginIface *plugin) +{ + if (plugin) { + auto type = static_cast(searchType); + plugin->setParent(this); + + if (!m_internalPlugins.contains(type)) { + m_internalPlugins.insert(type, plugin); + return true; + } + + plugin->deleteLater(); + } + + return false; +} + +bool ManagedPlugin::insertExternalPlugin(const QString &customType, SearchTaskPluginIface *plugin) +{ + if (plugin) { + plugin->setParent(this); + if (!customType.isEmpty() && !m_externalPlugin.contains(customType)) { + m_externalPlugin.insert(customType, plugin); + return true; + } + + plugin->deleteLater(); + } + + return false; +} + +inline SearchTaskPluginIface *ManagedPlugin::internalPlugin(const SearchType &searchType) +{ + auto type = static_cast(searchType); + if (m_internalPlugins.contains(type)) { + return m_internalPlugins.value(type); + } + return nullptr; +} + +inline SearchTaskPluginIface *ManagedPlugin::externalPlugin(const QString &customType) +{ + if (m_externalPlugin.contains(customType)) { + return m_externalPlugin.value(customType); + } + return nullptr; +} diff --git a/libsearch/pluginmanage/search-task-plugin-manager.h b/libsearch/pluginmanage/search-task-plugin-manager.h index d94087f..766e806 100644 --- a/libsearch/pluginmanage/search-task-plugin-manager.h +++ b/libsearch/pluginmanage/search-task-plugin-manager.h @@ -2,19 +2,46 @@ #define SEARCHTASKPLUGINMANAGER_H #include +#include #include "search-task-plugin-iface.h" + namespace UkuiSearch { +class ManagedPlugin : public QObject +{ + Q_OBJECT +public: + explicit ManagedPlugin(QObject *parent) : QObject(parent) {} + ~ManagedPlugin() override; + + inline SearchTaskPluginIface *internalPlugin(const SearchType& searchType); + inline SearchTaskPluginIface *externalPlugin(const QString& customType); + + bool insertInternalPlugin(const SearchType& searchType, SearchTaskPluginIface* plugin); + bool insertExternalPlugin(const QString& customType, SearchTaskPluginIface* plugin); + +private: + QMap m_internalPlugins; + QMap m_externalPlugin; +}; + class SearchTaskPluginManager : public QObject { Q_OBJECT public: static SearchTaskPluginManager *getInstance(); void initPlugins(SearchType searchType); + SearchTaskPluginIface *initPlugins(const QUuid&, SearchType, const QString& customType = QString()); bool registerPlugin(SearchTaskPluginIface *plugin); bool registerBuildinPlugin(SearchTaskPluginIface *plugin); void pluginSearch(SearchType searchType, std::shared_ptr searchController); void pluginSearch(QString customSearchType, std::shared_ptr searchController); + bool startSearch(const QUuid&, std::shared_ptr, SearchType, const QString& customType = QString()); + void destroyPlugins(const QUuid& uuid); + + SearchTaskPluginIface *getPlugin(SearchType searchType, const QString& customType = QString()); + void registerPluginPath(const QString& customType, const QString& pluginPath); + Q_SIGNALS: void searchFinished(size_t searchId); void searchError(size_t searchId, QString msg); @@ -25,7 +52,8 @@ private: //这里初衷是把内外部插件分开管理,内部插件可以增加枚举值,外部插件似乎只能用编写者自定义的字符串区分? QHash m_buildinPlugin; QHash m_loadedPlugin; - + QMap m_loadedPluginPath; + QMap m_managedPlugins; }; } diff --git a/libsearch/searchinterface/search-controller.cpp b/libsearch/searchinterface/search-controller.cpp index 66da16e..2af8f95 100644 --- a/libsearch/searchinterface/search-controller.cpp +++ b/libsearch/searchinterface/search-controller.cpp @@ -112,7 +112,7 @@ void SearchControllerPrivate::finishSearchIdCheck() void SearchControllerPrivate::stop() { m_searchIdMutex.lock(); - m_searchId = 0; + m_searchId += 1; m_searchIdMutex.unlock(); } diff --git a/libsearch/searchinterface/ukui-search-task-private.h b/libsearch/searchinterface/ukui-search-task-private.h index a28e1b6..3a00832 100644 --- a/libsearch/searchinterface/ukui-search-task-private.h +++ b/libsearch/searchinterface/ukui-search-task-private.h @@ -5,9 +5,12 @@ #include #include #include +#include #include "data-queue.h" #include "search-controller.h" +#include "search-task-plugin-iface.h" + namespace UkuiSearch { class UkuiSearchTaskPrivate : public QObject { @@ -23,23 +26,25 @@ public: void setOnlySearchFile(bool onlySearchFile); void setOnlySearchDir(bool onlySearchDir); void setSearchOnlineApps(bool searchOnlineApps); - void initSearchPlugin(SearchType searchType); + void initSearchPlugin(SearchType searchType, const QString& customSearchType = QString()); void clearAllConditions(); void clearKeyWords(); void clearSearchDir(); void clearFileLabel(); void setPagination(unsigned int first, unsigned int maxResults); - size_t startSearch(SearchType searchtype, QString customSearchType = QString()); + size_t startSearch(SearchType searchtype, const QString& customSearchType = QString()); void stop(); private: std::shared_ptr m_searchCotroller = nullptr; size_t m_searchId = 0; UkuiSearchTask* q = nullptr; + QUuid m_uuid; Q_SIGNALS: void searchFinished(size_t searchId); + void searchError(size_t searchId, QString msg); }; } diff --git a/libsearch/searchinterface/ukui-search-task.cpp b/libsearch/searchinterface/ukui-search-task.cpp index 891e327..fb42c91 100644 --- a/libsearch/searchinterface/ukui-search-task.cpp +++ b/libsearch/searchinterface/ukui-search-task.cpp @@ -7,14 +7,14 @@ UkuiSearchTaskPrivate::UkuiSearchTaskPrivate(UkuiSearchTask *parent) : QObject(parent), q(parent) { - m_searchCotroller = std::shared_ptr(new SearchController()); - connect(SearchTaskPluginManager::getInstance(), &SearchTaskPluginManager::searchFinished, this, &UkuiSearchTaskPrivate::searchFinished); - connect(SearchTaskPluginManager::getInstance(), &SearchTaskPluginManager::searchError, q, &UkuiSearchTask::searchError); + m_searchCotroller = std::make_shared(); + m_uuid = QUuid::createUuid(); } UkuiSearchTaskPrivate::~UkuiSearchTaskPrivate() { this->stop(); + SearchTaskPluginManager::getInstance()->destroyPlugins(m_uuid); } DataQueue *UkuiSearchTaskPrivate::init() @@ -56,25 +56,27 @@ void UkuiSearchTaskPrivate::setSearchOnlineApps(bool searchOnlineApps) { } -void UkuiSearchTaskPrivate::initSearchPlugin(SearchType searchType) +void UkuiSearchTaskPrivate::initSearchPlugin(SearchType searchType, const QString& customSearchType) { - SearchTaskPluginManager::getInstance()->initPlugins(searchType); + SearchTaskPluginIface *plugin = SearchTaskPluginManager::getInstance()->initPlugins(m_uuid, searchType, customSearchType); + if (plugin) { + connect(plugin, &SearchTaskPluginIface::searchFinished,this, &UkuiSearchTaskPrivate::searchFinished); + connect(plugin, &SearchTaskPluginIface::searchError,this, &UkuiSearchTaskPrivate::searchError); + } else { + qWarning() << "The plugin has been initialized or the plugin failed to load."; + } } -size_t UkuiSearchTaskPrivate::startSearch(SearchType searchtype, QString customSearchType) +size_t UkuiSearchTaskPrivate::startSearch(SearchType searchtype, const QString& customSearchType) { - m_searchId = m_searchCotroller->refreshSearchId(); if(m_searchCotroller->getDataQueue() == nullptr) { qWarning() << "the date queue has not been initialized, you need run init first!"; } //plugin manager do async search here - if(SearchType::Custom != searchtype) { - SearchTaskPluginManager::getInstance()->pluginSearch(searchtype, m_searchCotroller); - } else { - SearchTaskPluginManager::getInstance()->pluginSearch(customSearchType, m_searchCotroller); - + if (!SearchTaskPluginManager::getInstance()->startSearch(m_uuid, m_searchCotroller, searchtype, customSearchType)) { + Q_EMIT searchError(m_searchCotroller->getCurrentSearchId(), tr("Current task uuid error or an unregistered plugin is used!")); } return m_searchId; @@ -113,6 +115,7 @@ void UkuiSearchTaskPrivate::setPagination(unsigned int first, unsigned int maxRe UkuiSearchTask::UkuiSearchTask(QObject *parent) : QObject(parent), d(new UkuiSearchTaskPrivate(this)) { connect(d, &UkuiSearchTaskPrivate::searchFinished, this, &UkuiSearchTask::searchFinished); + connect(d, &UkuiSearchTaskPrivate::searchError, this, &UkuiSearchTask::searchError); } UkuiSearchTask::~UkuiSearchTask()