Loading...
Searching...
No Matches
score-plugin-lv2/LV2/ApplicationPlugin.hpp
1#pragma once
2#include <LV2/Context.hpp>
3#include <LV2/Suil.hpp>
4
5#include <score/plugins/application/GUIApplicationPlugin.hpp>
6#include <score/serialization/DataStreamFwd.hpp>
7
8#include <ossia/detail/hash_map.hpp>
9
10#include <QString>
11#include <QStringList>
12#include <QVector>
13#include <QtCore/qglobal.h>
14
15#include <lilv/lilvmm.hpp>
16
17#include <score_plugin_lv2_export.h>
18
19#include <memory>
20#include <vector>
21#include <verdigris>
22
23namespace Media
24{
25class PluginScanner;
26}
27
28namespace LV2
29{
30struct HostContext;
31struct GlobalContext;
32
33// Cached descriptor from a lv2puppet scan; persisted to QSettings("Effect/KnownLV2")
35{
36 QString bundle; // file system path to .lv2 bundle dir
37 QString uri; // canonical plug-in URI
38 QString name;
39 QString class_label; // lv2:Class label (Reverb, Delay, ...)
40 QString author;
41 QString documentationLink; // author homepage URL
42
43 // Cache invalidation key — re-scan when the manifest changes.
44 qint64 mtime{};
45 qint64 size{};
46
47 int audio_in{};
48 int audio_out{};
49 int midi_in{};
50 int midi_out{};
51 int control_in{};
52 int control_out{};
53 int atom_in{};
54 int atom_out{};
55 int cv_in{};
56
57 bool has_ui{};
58 QStringList ui_uris;
59 QStringList preset_uris;
60 // Parallel to preset_uris: bundle that must be loaded before lilv_plugin_get_related
61 QStringList preset_bundles;
62
63 bool valid{};
64};
65
66class SCORE_PLUGIN_LV2_EXPORT ApplicationPlugin
67 : public QObject
69{
70 W_OBJECT(ApplicationPlugin)
71public:
73 void initialize() override;
74 ~ApplicationPlugin() override;
75
76 const std::vector<PluginInfo>& cachedDescriptors() const noexcept
77 {
78 return m_plugins;
79 }
80
81 const PluginInfo* findDescriptor(const QString& uri_or_bundle) const noexcept;
82
83 // Idempotent; main thread only.
84 void ensureBundleLoaded(const QString& uri_or_bundle);
85
86 // Replace the descriptor cache wholesale (cache import, tests). Main thread only.
87 void setCachedDescriptors(std::vector<PluginInfo> descriptors);
88
89public:
90 void descriptorsChanged() E_SIGNAL(SCORE_PLUGIN_LV2_EXPORT, descriptorsChanged);
91
92public:
93 Lilv::World lilv;
94 std::unique_ptr<LV2::GlobalContext> lv2_context;
95 LV2::HostContext lv2_host_context;
96
97 const libsuil& suil = libsuil::instance();
98
100 void forceRescan();
101
102private:
103 void rescanBundles();
104 void onScanned(const QString& bundlePath, const class QJsonObject& obj);
105 void addPluginsFromJson(const QString& bundlePath, const class QJsonArray& arr);
106 void markBundleInvalid(const QString& bundlePath);
107 void persistCache();
108
109 QStringList discoverLv2Search();
110 static QStringList discoverBundles(const QStringList& search);
111 // Pick out LV2 spec bundles (atom, urid, ui, ...) so puppets can skip load_all
112 static QStringList discoverSpecBundles(const QStringList& bundles);
113
114#if QT_CONFIG(process)
115 std::unique_ptr<Media::PluginScanner> m_scanner;
116#endif
117 bool m_scanRan{};
118
119 std::vector<PluginInfo> m_plugins;
120
121 ossia::hash_set<QString> m_loaded_bundles;
122
123 QStringList m_spec_bundles;
124
125 // Coalesces persistCache + descriptorsChanged into one fire per burst
126 class QTimer* m_persistTimer{};
127};
128
129}
130
131Q_DECLARE_METATYPE(LV2::PluginInfo)
132Q_DECLARE_METATYPE(std::vector<LV2::PluginInfo>)
133
134// Every TU that puts PluginInfo in a QVariant must see these, or Qt6 bakes
135// null stream handlers into its copy of the QMetaTypeInterface.
136SCORE_SERIALIZE_DATASTREAM_DECLARE(SCORE_PLUGIN_LV2_EXPORT, LV2::PluginInfo)
137SCORE_SERIALIZE_DATASTREAM_DECLARE(SCORE_PLUGIN_LV2_EXPORT, std::vector<LV2::PluginInfo>)
Definition score-plugin-lv2/LV2/ApplicationPlugin.hpp:69
Definition Suil.hpp:10
Definition GUIApplicationPlugin.hpp:31
Definition Context.hpp:60
Definition score-plugin-lv2/LV2/ApplicationPlugin.hpp:35
Definition FactorySetup.hpp:68
Used to access all the application-wide state and structures.
Definition ApplicationContext.hpp:25