File indexing completed on 2024-05-19 05:42:14

0001 // ct_lvtplg_pluginmanager.h                                         -*-C++-*-
0002 
0003 /*
0004 // Copyright 2023 Codethink Ltd <codethink@codethink.co.uk>
0005 // SPDX-License-Identifier: Apache-2.0
0006 //
0007 // Licensed under the Apache License, Version 2.0 (the "License");
0008 // you may not use this file except in compliance with the License.
0009 // You may obtain a copy of the License at
0010 //
0011 //     http://www.apache.org/licenses/LICENSE-2.0
0012 //
0013 // Unless required by applicable law or agreed to in writing, software
0014 // distributed under the License is distributed on an "AS IS" BASIS,
0015 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0016 // See the License for the specific language governing permissions and
0017 // limitations under the License.
0018 */
0019 
0020 #ifndef DIAGRAM_SERVER_CT_LVTPLG_PLUGINMANAGER_H
0021 #define DIAGRAM_SERVER_CT_LVTPLG_PLUGINMANAGER_H
0022 
0023 #include <lvtplg_export.h>
0024 
0025 #include <ct_lvtplg_abstractlibrarydispatcher.h>
0026 #include <ct_lvtplg_basicpluginhandlers.h>
0027 #include <ct_lvtplg_basicpluginhooks.h>
0028 #include <ct_lvtplg_pythonlibrarydispatcher.h>
0029 
0030 #include <QDebug>
0031 #include <QDir>
0032 #include <QString>
0033 
0034 #pragma push_macro("slots")
0035 #undef slots
0036 #include <pybind11/embed.h>
0037 #pragma pop_macro("slots")
0038 
0039 #include <filesystem>
0040 #include <functional>
0041 #include <memory>
0042 #include <optional>
0043 #include <vector>
0044 
0045 namespace py = pybind11;
0046 
0047 namespace Codethink::lvtplg {
0048 
0049 class LVTPLG_EXPORT PluginManager {
0050   public:
0051     PluginManager() = default;
0052     PluginManager(PluginManager const&) = delete;
0053     PluginManager(PluginManager&&) = delete;
0054     PluginManager operator=(PluginManager const&) = delete;
0055     PluginManager operator=(PluginManager&) = delete;
0056     void loadPlugins(const QList<QString>& paths);
0057     std::vector<std::string> getPluginsMetadataFilePaths() const;
0058     std::optional<std::reference_wrapper<AbstractLibraryDispatcher>> getPluginById(std::string const& id) const;
0059 
0060     void reloadPlugin(const QString& pluginfolder);
0061     void removePlugin(const QString& pluginFolder);
0062 
0063     void callHooksSetupPlugin();
0064     void callHooksTeardownPlugin();
0065 
0066     using getAllEntitiesInCurrentView_f = decltype(PluginContextMenuHandler::getAllEntitiesInCurrentView);
0067     using getEntityByQualifiedName_f = decltype(PluginContextMenuHandler::getEntityByQualifiedName);
0068     using getEdgeByQualifiedName_f = decltype(PluginContextMenuHandler::getEdgeByQualifiedName);
0069     using registerContextMenu_f = decltype(PluginContextMenuHandler::registerContextMenu);
0070     void callHooksContextMenu(getAllEntitiesInCurrentView_f const& getAllEntitiesInCurrentView,
0071                               getEntityByQualifiedName_f const& getEntityByQualifiedName,
0072                               getEdgeByQualifiedName_f const& getEdgeByQualifiedName,
0073                               registerContextMenu_f const& registerContextMenu);
0074 
0075     using createPluginDock_f = decltype(PluginSetupDockWidgetHandler::createNewDock);
0076     void callHooksSetupDockWidget(createPluginDock_f const& createPluginDock);
0077 
0078     using getEntity_f = decltype(PluginEntityReportHandler::getEntity);
0079     using addReport_f = decltype(PluginEntityReportHandler::addReport);
0080     void callHooksSetupEntityReport(getEntity_f const& getEntity, addReport_f const& addReport);
0081 
0082     using getSourceFile_f = decltype(PluginPhysicalParserOnHeaderFoundHandler::getSourceFile);
0083     using getIncludedFile_f = decltype(PluginPhysicalParserOnHeaderFoundHandler::getIncludedFile);
0084     using getLineNo_f = decltype(PluginPhysicalParserOnHeaderFoundHandler::getLineNo);
0085     void callHooksPhysicalParserOnHeaderFound(getSourceFile_f const& getSourceFile,
0086                                               getIncludedFile_f const& getIncludedFile,
0087                                               getLineNo_f const& getLineNo);
0088 
0089     using getFilename_f = decltype(PluginLogicalParserOnCppCommentFoundHandler::getFilename);
0090     using getBriefText_f = decltype(PluginLogicalParserOnCppCommentFoundHandler::getBriefText);
0091     using getStartLine_f = decltype(PluginLogicalParserOnCppCommentFoundHandler::getStartLine);
0092     using getEndLine_f = decltype(PluginLogicalParserOnCppCommentFoundHandler::getEndLine);
0093     void callHooksPluginLogicalParserOnCppCommentFoundHandler(getFilename_f const& getFilename,
0094                                                               getBriefText_f const& getBriefText,
0095                                                               getStartLine_f const& getStartLine,
0096                                                               getEndLine_f const& getEndLine);
0097 
0098     using runQueryOnDatabase_f = decltype(PluginParseCompletedHandler::runQueryOnDatabase);
0099     void callHooksOnParseCompleted(runQueryOnDatabase_f const& runQueryOnDatabase);
0100 
0101     using getSceneName_f = decltype(PluginActiveSceneChangedHandler::getSceneName);
0102     void callHooksActiveSceneChanged(getSceneName_f const& getSceneName);
0103 
0104     using graphChanged_getSceneName_f = decltype(PluginGraphChangedHandler::getSceneName);
0105     using graphChanged_getVisibleEntities_f = decltype(PluginGraphChangedHandler::getVisibleEntities);
0106     using graphChanged_getEdgeByQualifiedName_f = decltype(PluginGraphChangedHandler::getEdgeByQualifiedName);
0107     using graphChanged_getProjectData_f = decltype(PluginGraphChangedHandler::getProjectData);
0108     void callHooksGraphChanged(graphChanged_getSceneName_f const& getSceneName,
0109                                graphChanged_getVisibleEntities_f const& getVisibleEntities,
0110                                graphChanged_getEdgeByQualifiedName_f const& getEdgeByQualifiedName,
0111                                graphChanged_getProjectData_f const& getProjectData);
0112 
0113     void registerPluginData(std::string const& id, void *data);
0114     void unregisterPluginData(std::string const& id);
0115     void *getPluginData(std::string const& id) const;
0116 
0117     void registerPluginQObject(std::string const& id, QObject *object);
0118     QObject *getPluginQObject(std::string const& id) const;
0119 
0120   private:
0121 #ifdef ENABLE_PYTHON_PLUGINS
0122     py::scoped_interpreter py;
0123     py::gil_scoped_release defaultReleaseGIL;
0124 #endif
0125     std::unordered_map<std::string, std::unique_ptr<AbstractLibraryDispatcher>> libraries;
0126     std::map<std::string, void *> pluginData;
0127     std::unordered_map<std::string, QObject *> pluginQObjects;
0128 };
0129 } // namespace Codethink::lvtplg
0130 
0131 #endif // DIAGRAM_SERVER_CT_LVTPLG_PLUGINMANAGER_H