OpenCPN Partial API docs
Loading...
Searching...
No Matches
plugin_loader.h
Go to the documentation of this file.
1/**************************************************************************
2 * Copyright (C) 2010 - 2023 by David S. Register *
3 * Copyright (C) 2023 - 2025 Alec Leamas *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
17 **************************************************************************/
18
25#ifndef PLUGIN_LOADER_H_GUARD
26#define PLUGIN_LOADER_H_GUARD
27
28#include <functional>
29
30#include <wx/wx.h>
31#include <wx/bitmap.h>
32#include <wx/dynarray.h>
33#include <wx/dynlib.h>
34
35#include "config.h"
36
37#include "observable/evtvar.h"
38
41#include "model/semantic_vers.h"
42#include "ocpn_plugin.h"
43
44enum class PluginStatus {
45 System,
46 Managed,
47 Unmanaged,
48 Ghost,
49 Unknown,
50 LegacyUpdateAvailable,
51 ManagedInstallAvailable,
52 ManagedInstalledUpdateAvailable,
53 ManagedInstalledCurrentVersion,
54 ManagedInstalledDowngradeAvailable,
55 Imported,
56 PendingListRemoval
57};
58
59class PlugInContainer; // forward
60
63public:
65 explicit PlugInData(const PluginMetadata& md);
66
67 PlugInData();
68
70 bool m_enabled;
71 bool m_init_state;
72 bool m_toolbox_panel;
74 wxString m_plugin_file;
77 wxString m_common_name;
78 wxString m_short_description;
79 wxString m_long_description;
80 int m_api_version;
81 int m_version_major;
82 int m_version_minor;
83 PluginStatus m_status;
84 PluginMetadata m_managed_metadata;
85 wxBitmap m_bitmap;
86 wxString m_version_str;
87 std::string m_manifest_version;
88
90 std::string Key() const;
91};
92
98public:
100
101 ~PlugInContainer() = default;
102
103 opencpn_plugin* m_pplugin;
104 wxDynamicLibrary m_library;
105 destroy_t* m_destroy_fn;
106};
107
110public:
111 enum class Type {
112 Unloadable, //<! wrong magic, wrong type of binary...
113 Unreadable,
114 Incompatible,
115 NoCreate, //<! Missing linkage (is this a plugin?)
116 NoDestroy, //<! Missing linkage (is this a plugin?)
117 Blacklisted
118 } type;
119 const std::string lib_path; //<! Complete path to failing library
120 //<! As determined from plugin API
121 const SemanticVersion plugin_version; //<! As determined from plugin API
122
123 LoadError(Type t, const std::string& l, SemanticVersion pv)
124 : type(t), lib_path(l), plugin_version(pv) {}
125
126 LoadError(Type t, std::string l)
127 : type(t), lib_path(std::move(l)), plugin_version(SemanticVersion()) {}
128};
129
130WX_DEFINE_ARRAY_PTR(PlugInContainer*, ArrayOfPlugIns);
131
152public:
153 static PluginLoader* GetInstance();
154 virtual ~PluginLoader() = default;
155
160 static void MarkAsLoadable(const std::string& library_path);
164 static void UpdatePlugin(PlugInContainer* plugin, const PluginMetadata& md);
165
167 static std::string GetPluginVersion(
168 const PlugInData pd,
169 std::function<const PluginMetadata(const std::string&)> get_metadata);
170
172 static PluginMetadata MetadataByName(const std::string& name);
173
175 static PluginMetadata LatestMetadataByName(const std::string& name);
176
178 obs::EventVar evt_load_directory;
179
184 obs::EventVar evt_load_plugin;
185
187 obs::EventVar evt_pluglist_change;
188
193
196
202
211 bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans = false);
212
213 const wxBitmap* GetPluginDefaultIcon();
214 void SetPluginDefaultIcon(const wxBitmap* bitmap);
215
217 void SetOnActivateCb(std::function<void(const PlugInContainer*)> cb) {
218 m_on_activate_cb = cb;
219 }
220
222 void SetOnDeactivateCb(std::function<void(const PlugInContainer*)> cb) {
223 m_on_deactivate_cb = cb;
224 }
226 void ShowPreferencesDialog(const PlugInData& pd, wxWindow* parent);
227
228 void NotifySetupOptionsPlugin(const PlugInData* pic);
229
231 void RemovePlugin(const PlugInData& pd);
232
234 void SortPlugins(int (*cmp_func)(PlugInContainer**, PlugInContainer**));
235
237 bool UnLoadPlugIn(size_t ix);
238
240 bool UnLoadAllPlugIns();
241
244
247
249 bool DeactivatePlugIn(const PlugInData& pic);
250
252 bool UpdatePlugIns();
253
262 void UpdateManagedPlugins(bool keep_orphans);
263
265 PlugInContainer* LoadPlugIn(const wxString& plugin_file);
266
268 PlugInContainer* LoadPlugIn(const wxString& plugin_file,
269 PlugInContainer* pic);
270
272 const ArrayOfPlugIns* GetPlugInArray() { return &plugin_array; }
273
275 bool IsPlugInAvailable(const wxString& commonName);
276
282 bool CheckPluginCompatibility(const wxString& plugin_file);
283
285 void SetEnabled(const wxString& common_name, bool enabled);
286
288 void SetToolboxPanel(const wxString& common_name, bool value);
289
291 void SetSetupOptions(const wxString& common_name, bool value);
292
293private:
294 PluginLoader();
295 bool LoadPlugInDirectory(const wxString& plugin_dir, bool load_enabled);
296 bool LoadPluginCandidate(const wxString& file_name, bool load_enabled);
297 std::unique_ptr<AbstractBlacklist> m_blacklist;
298 ArrayOfPlugIns plugin_array;
299 wxString m_last_error_string;
300 wxString m_plugin_location;
301
302#ifdef __WXMSW__
303 wxString m_module_name;
304 bool m_found_wxwidgets;
305#endif
306
307 const wxBitmap* m_default_plugin_icon;
308 std::function<void(const PlugInContainer*)> m_on_activate_cb;
309 std::function<void(const PlugInContainer*)> m_on_deactivate_cb;
310
311 std::vector<LoadError> load_errors;
312};
313
314#endif // PLUGIN_LOADER_H_GUARD
Datatypes and methods to parse ocpn-plugins.xml XML data, either complete catalog or a single plugin.
Error condition when loading a plugin.
Data for a loaded plugin, including dl-loaded library.
Basic data for a loaded plugin, trivially copyable.
wxString m_plugin_filename
The short file path.
wxString m_plugin_file
The full file path.
int m_cap_flag
PlugIn Capabilities descriptor.
wxString m_common_name
A common name string for the plugin.
bool m_has_setup_options
Has run NotifySetupOptionsPlugin()
std::string Key() const
sort key.
std::string m_manifest_version
As detected from manifest.
wxDateTime m_plugin_modification
used to detect upgraded plugins
wxString m_version_str
Complete version as of semantic_vers.
PluginLoader is a backend module without any direct GUI functionality.
void SetOnDeactivateCb(std::function< void(const PlugInContainer *)> cb)
Callback invoked in late stage on deactivating a plugin.
obs::EventVar evt_load_plugin
Notified with a PlugInContainer* pointer when a plugin is loaded.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
bool IsPlugInAvailable(const wxString &commonName)
Return true if a plugin with given name exists in GetPlugInArray()
static void MarkAsLoadable(const std::string &library_path)
Mark a library file (complete path) as loadable i.
static PluginMetadata LatestMetadataByName(const std::string &name)
Find highest versioned metadata for given plugin.
obs::EventVar evt_deactivate_plugin
Notified with plugin name when it's deactivated.
void UpdateManagedPlugins(bool keep_orphans)
Update all managed plugins i.
void SetOnActivateCb(std::function< void(const PlugInContainer *)> cb)
Callback invoked in late stage on activating a plugin.
obs::EventVar evt_update_chart_types
Notified without data after all plugins loaded ot updated.
static std::string GetPluginVersion(const PlugInData pd, std::function< const PluginMetadata(const std::string &)> get_metadata)
Return version string for a plugin, possibly with an "Imported" suffix.
bool UnLoadPlugIn(size_t ix)
Unload, delete and remove item ix in GetPlugInArray().
void SortPlugins(int(*cmp_func)(PlugInContainer **, PlugInContainer **))
Sort GetPluginArray().
static void UpdatePlugin(PlugInContainer *plugin, const PluginMetadata &md)
Update PlugInContainer status using data from PluginMetadata and manifest.
obs::EventVar evt_plugin_loadall_finalize
Emitted after all plugins are loaded.
void SetSetupOptions(const wxString &common_name, bool value)
Update m_has_setup_options state for plugin with given name.
obs::EventVar evt_load_directory
Notified without data when loader starts loading from a new directory.
void SetEnabled(const wxString &common_name, bool enabled)
Update enabled/disabled state for plugin with given name.
void SetToolboxPanel(const wxString &common_name, bool value)
Update m_toolbox_panel state for plugin with given name.
static PluginMetadata MetadataByName(const std::string &name)
Find metadata for given plugin.
bool DeactivatePlugIn(PlugInContainer *pic)
Deactivate given plugin.
bool UnLoadAllPlugIns()
Unload allplugins i.
void RemovePlugin(const PlugInData &pd)
Remove a plugin from *GetPluginArray().
bool UpdatePlugIns()
Update the GetPlugInArray() list by reloading all plugins from disk.
void ShowPreferencesDialog(const PlugInData &pd, wxWindow *parent)
Display the preferences dialog for a plugin.
bool CheckPluginCompatibility(const wxString &plugin_file)
Check plugin compatibiliet w r t library type.
const ArrayOfPlugIns * GetPlugInArray()
Return list of currently loaded plugins.
obs::EventVar evt_pluglist_change
Notified without data when the GetPlugInArray() list is changed.
bool DeactivateAllPlugIns()
Deactivate all plugins.
PlugInContainer * LoadPlugIn(const wxString &plugin_file)
Load given plugin file from disk into GetPlugInArray() list.
Base class for OpenCPN plugins.
PlugIn Object Definition/API.
Plugin blacklist for plugins which can or should not be loaded.
PluginStatus
@ Ghost
Managed, shadowing another (packaged?) plugin.
@ Unmanaged
Unmanaged, probably a package.
@ Managed
Managed by installer.
@ System
One of the four system plugins, unmanaged.
Semantic version encode/decode object.
Plugin metadata, reflects the xml format directly.
Versions uses a modified semantic versioning scheme: major.minor.revision.post-tag+build.