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
34SCORE_PLUGIN_LV2_TEST_EXPORT
35void on_uiMessage(
36 SuilController controller, uint32_t port_index, uint32_t buffer_size,
37 uint32_t protocol, const void* buffer);
39SCORE_PLUGIN_LV2_TEST_EXPORT
40uint32_t port_index(SuilController controller, const char* symbol);
41
42// Cached descriptor from a lv2puppet scan; persisted to QSettings("Effect/KnownLV2")
44{
45 QString bundle; // file system path to .lv2 bundle dir
46 QString uri; // canonical plug-in URI
47 QString name;
48 QString class_label; // lv2:Class label (Reverb, Delay, ...)
49 QString author;
50 QString documentationLink; // author homepage URL
51
52 // Cache invalidation key — re-scan when the manifest changes.
53 qint64 mtime{};
54 qint64 size{};
55
56 int audio_in{};
57 int audio_out{};
58 int midi_in{};
59 int midi_out{};
60 int control_in{};
61 int control_out{};
62 int atom_in{};
63 int atom_out{};
64 int cv_in{};
65
66 bool has_ui{};
67 QStringList ui_uris;
68 QStringList preset_uris;
69 // Parallel to preset_uris: bundle that must be loaded before lilv_plugin_get_related
70 QStringList preset_bundles;
71
72 bool valid{};
73};
74
75class SCORE_PLUGIN_LV2_EXPORT ApplicationPlugin
76 : public QObject
78{
79 W_OBJECT(ApplicationPlugin)
80public:
82 void initialize() override;
83 ~ApplicationPlugin() override;
84
85 const std::vector<PluginInfo>& cachedDescriptors() const noexcept
86 {
87 return m_plugins;
88 }
89
90 const PluginInfo* findDescriptor(const QString& uri_or_bundle) const noexcept;
91
92 // Idempotent; main thread only.
93 void ensureBundleLoaded(const QString& uri_or_bundle);
94
95 // Replace the descriptor cache wholesale (cache import, tests). Main thread only.
96 void setCachedDescriptors(std::vector<PluginInfo> descriptors);
97
98public:
99 void descriptorsChanged() E_SIGNAL(SCORE_PLUGIN_LV2_EXPORT, descriptorsChanged);
100
101public:
102 Lilv::World lilv;
103 std::unique_ptr<LV2::GlobalContext> lv2_context;
104 LV2::HostContext lv2_host_context;
105
106 const libsuil& suil = libsuil::instance();
107
109 void forceRescan();
110
111private:
112 void rescanBundles();
113 void onScanned(const QString& bundlePath, const class QJsonObject& obj);
114 void addPluginsFromJson(const QString& bundlePath, const class QJsonArray& arr);
115 void markBundleInvalid(const QString& bundlePath);
116 void persistCache();
117
118 QStringList discoverLv2Search();
119 static QStringList discoverBundles(const QStringList& search);
120 // Pick out LV2 spec bundles (atom, urid, ui, ...) so puppets can skip load_all
121 static QStringList discoverSpecBundles(const QStringList& bundles);
122
123#if QT_CONFIG(process)
124 std::unique_ptr<Media::PluginScanner> m_scanner;
125#endif
126 bool m_scanRan{};
127
128 std::vector<PluginInfo> m_plugins;
129
130 ossia::hash_set<QString> m_loaded_bundles;
131
132 QStringList m_spec_bundles;
133
134 // Coalesces persistCache + descriptorsChanged into one fire per burst
135 class QTimer* m_persistTimer{};
136};
137
138}
139
140Q_DECLARE_METATYPE(LV2::PluginInfo)
141Q_DECLARE_METATYPE(std::vector<LV2::PluginInfo>)
142
143// Every TU that puts PluginInfo in a QVariant must see these, or Qt6 bakes
144// null stream handlers into its copy of the QMetaTypeInterface.
145SCORE_SERIALIZE_DATASTREAM_DECLARE(SCORE_PLUGIN_LV2_EXPORT, LV2::PluginInfo)
146SCORE_SERIALIZE_DATASTREAM_DECLARE(SCORE_PLUGIN_LV2_EXPORT, std::vector<LV2::PluginInfo>)
Definition score-plugin-lv2/LV2/ApplicationPlugin.hpp:78
Definition Suil.hpp:10
Definition GUIApplicationPlugin.hpp:39
Definition Context.hpp:61
Definition score-plugin-lv2/LV2/ApplicationPlugin.hpp:44
Definition FactorySetup.hpp:68
Used to access all the application-wide state and structures.
Definition ApplicationContext.hpp:25