commit 39391d42163eaa1afe3f15b79ab05643a6e13919
parent 0bd6b59efc9fdb91aff5908015a61fc09b111fa2
Author: Alexandre Bique <bique.alexandre@gmail.com>
Date: Wed, 4 Jan 2023 11:35:17 +0100
Rework preset discovery
Diffstat:
3 files changed, 103 insertions(+), 86 deletions(-)
diff --git a/ChangeLog.md b/ChangeLog.md
@@ -2,7 +2,6 @@
* Add a [factory](incl/../include/clap/factory) folder for better organization and move our factories there
* [params.h](include/clap/ext/params.h): fix typos
-* [string-sizes.h](include/clap/string-sizes.h): add sizes for URI (8192 bytes) and descriptions (1024 bytes)
* CMake: disable C17 targets for CMake < 3.21
## Draft extensions
diff --git a/include/clap/factory/draft/preset-discovery.h b/include/clap/factory/draft/preset-discovery.h
@@ -10,12 +10,16 @@
- the user can browse for presets without having to commit to a particular plug-in first
The API works as follow to index presets and presets metadata:
- 1. get the preset discovery factory
- 2. create a preset provider
- 3. list locations and file extensions from the preset provider
- 4. monitor file system changes on the given locations
+ 1. clap_plugin_entry.get_factory(CLAP_PRESET_DISCOVERY_FACTORY_ID)
+ 2. clap_preset_discovery_factory_t.create(...)
+ 3. clap_preset_discovery_provider.register_filetypes()
+ `-> clap_preset_discovery_indexer.register_filetype()
+ clap_preset_discovery_provider.register_locations()
+ `-> clap_preset_discovery_indexer.register_location()
+ clap_preset_discovery_provider.register_collections()
+ `-> clap_preset_discovery_indexer.register_collection()
+ 4. crawl the given locations and monitor file system changes
5. read metadata for each preset files
- 6. fetch information about collections from the preset provider
Then to load a preset, use ext/draft/preset-load.h
@@ -40,6 +44,7 @@
#include "../../private/macros.h"
#include "../../string-sizes.h"
#include "../../version.h"
+#include "../../color.h"
// Use it to retrieve const clap_preset_discovery_factory_t* from
// clap_plugin_entry.get_factory()
@@ -62,6 +67,9 @@ enum clap_preset_discovery_flags {
// needs to purchase or the content itself needs to be bought and is only available in
// demo mode.
CLAP_PRESET_DISCOVERY_IS_DEMO_CONTENT = 1 << 2,
+
+ // This preset is a user's favorite
+ CLAP_PRESET_DISCOVERY_IS_FAVORITE = 1 << 3,
};
// Receiver that receives the metadata for a single preset file.
@@ -69,17 +77,18 @@ enum clap_preset_discovery_flags {
// would then call them.
//
// This interface isn't thread-safe.
-typedef const struct clap_preset_metadata_receiver {
+typedef const struct clap_preset_discovery_metadata_receiver {
// If there is an error reading metadata from a file this should be called with an error
// message.
// os_error: the operating system error, if applicable. If not applicable set it to a non-error
// value: 0 on unix and Windows.
- void(CLAP_ABI *on_error)(const struct clap_preset_metadata_receiver *receiver,
- int32_t os_error,
- const char *error_message);
+ void(CLAP_ABI *on_error)(const struct clap_preset_discovery_metadata_receiver *receiver,
+ int32_t os_error,
+ const char *error_message);
// Marks this file as a container file meaning that it can contain other presets.
- void(CLAP_ABI *mark_as_container_file)(const struct clap_preset_metadata_receiver *receiver);
+ void(CLAP_ABI *mark_as_container_file)(
+ const struct clap_preset_discovery_metadata_receiver *receiver);
// If the file being parsed is a preset container file (mark_as_container_file has been called)
// then this must be called for every preset in the file and before any preset metadata is
@@ -93,39 +102,45 @@ typedef const struct clap_preset_metadata_receiver {
// the preset-load plug-in extension. The preset_id can also just be the path if that's what the
// extension wants but it could also be some other unique id like a database primary key or a
// binary offset. It's use is entirely up to the plug-in.
- void(CLAP_ABI *begin_contained_preset)(const struct clap_preset_metadata_receiver *receiver,
- const char *path,
- const char *preset_id);
+ void(CLAP_ABI *begin_contained_preset)(
+ const struct clap_preset_discovery_metadata_receiver *receiver,
+ const char *path,
+ const char *preset_id);
// Marks this preset as a bank preset, meaning that it can be assigned to the plug-in as a
// preset but will update the banks in the plug-in.
- void(CLAP_ABI *mark_as_bank_preset)(const struct clap_preset_metadata_receiver *receiver);
+ void(CLAP_ABI *mark_as_bank_preset)(
+ const struct clap_preset_discovery_metadata_receiver *receiver);
// Sets plug-in id that this preset can be used with.
- void(CLAP_ABI *set_plugin_id)(const struct clap_preset_metadata_receiver *receiver,
- const char *plugin_id);
+ void(CLAP_ABI *set_plugin_id)(const struct clap_preset_discovery_metadata_receiver *receiver,
+ const char *plugin_id);
// Sets the collection to which the preset belongs to.
- void(CLAP_ABI *set_collection_id)(const struct clap_preset_metadata_receiver,
+ void(CLAP_ABI *set_collection_id)(const struct clap_preset_discovery_metadata_receiver,
const char *collection_id);
// Sets the flags, see clap_preset_discovery_flags.
// If unset, they are then inherited from the location.
- void(CLAP_ABI *set_flags)(const struct clap_preset_metadata_receiver, uint32_t flags);
+ void(CLAP_ABI *set_flags)(const struct clap_preset_discovery_metadata_receiver, uint32_t flags);
// Adds a creator name for the preset.
- void(CLAP_ABI *add_creator)(const struct clap_preset_metadata_receiver *receiver,
- const char *creator);
+ void(CLAP_ABI *add_creator)(const struct clap_preset_discovery_metadata_receiver *receiver,
+ const char *creator);
// Sets a description of the preset.
- void(CLAP_ABI *set_description)(const struct clap_preset_metadata_receiver *receiver,
- const char *description);
+ void(CLAP_ABI *set_description)(const struct clap_preset_discovery_metadata_receiver *receiver,
+ const char *description);
+
+ // Sets a color tag associated to the preset.
+ void(CLAP_ABI *set_color_tag)(const struct clap_preset_discovery_metadata_receiver *receiver,
+ const clap_color_t *color);
// Sets the creation time and last modification time of the preset.
// If one of the time isn't known, then set it to 0.
- void(CLAP_ABI *set_timestamps)(const struct clap_preset_metadata_receiver *receiver,
- uint64_t creation_time,
- uint64_t modification_time);
+ void(CLAP_ABI *set_timestamps)(const struct clap_preset_discovery_metadata_receiver *receiver,
+ uint64_t creation_time,
+ uint64_t modification_time);
// Adds a feature to the preset.
// See plugin-features.h and preset-features.h
@@ -136,96 +151,105 @@ typedef const struct clap_preset_metadata_receiver {
// Examples:
// kick, drum, tom, snare, clap, cymbal, bass, lead, metalic, hardsync, crossmod, acid,
// distorted, drone, pad, dirty, etc...
- void(CLAP_ABI *add_feature)(const struct clap_preset_metadata_receiver *receiver,
- const char *feature);
+ void(CLAP_ABI *add_feature)(const struct clap_preset_discovery_metadata_receiver *receiver,
+ const char *feature);
+
+} * clap_preset_discovery_metadata_receiver_t;
-} * clap_preset_metadata_receiver_t;
+typedef struct clap_preset_discovery_filetype {
+ const char *name;
+ const char *description;
+
+ // `.' isn't included in the string.
+ // If empty or NULL then every file should be matched.
+ const char *file_extension;
+
+ const char *icon_uri_small_light;
+ const char *icon_uri_small_dark;
+ const char *icon_uri_large_light;
+ const char *icon_uri_large_dark;
+} clap_preset_discovery_filetype_t;
// Defines a place in which to search for presets
-typedef struct clap_preset_location {
+typedef struct clap_preset_discovery_location {
uint32_t flags; // see enum clap_preset_discovery_flags
// name of this location
- char name[CLAP_NAME_SIZE];
+ const char *name;
// URI
// - file:/// for pointing to a file or directory; directories are scanned recursively
// eg: file:///home/abique/.u-he/Diva/presets/
// - plugin://<clap-plugin-id> for presets which are bundled inside the plugin itself
- char uri[CLAP_URI_SIZE];
-} clap_preset_location_t;
+ const char *uri;
+} clap_preset_discovery_location_t;
// A collection, represent a collection of presets; it is will most often used to identify presets
// which belongs to the same "sound pack".
-typedef struct clap_preset_collection_info {
+typedef struct clap_preset_discovery_collection {
uint64_t flags; // see enum clap_preset_discovery_flags
- char name[CLAP_NAME_SIZE]; // name of this collection
- char description[CLAP_DESCRIPTION_SIZE]; // reasonably short description of the collection
- char homepage_url[CLAP_URI_SIZE]; // url to the pack's homepage
- char image_uri[CLAP_URI_SIZE]; // may be an image on disk or from an http server
-} clap_preset_collection_info_t;
+ const char *id; // collection identifier
+ const char *name; // name of this collection
+ const char *description; // reasonably short description of the collection
+ const char *homepage_url; // url to the pack's homepage
+ const char *image_uri; // may be an image on disk or from an http server
+} clap_preset_discovery_collection_t;
// Describes a preset provider
-typedef struct clap_preset_provider_descriptor {
+typedef struct clap_preset_discovery_provider_descriptor {
clap_version_t clap_version; // initialized to CLAP_VERSION
const char *id;
const char *name;
const char *vendor;
const char *const *plugin_ids; // null terminated array of plugin ids
-} clap_preset_provider_descriptor_t;
+} clap_preset_discovery_provider_descriptor_t;
// This interface isn't thread-safe.
-typedef struct clap_preset_provider {
- const clap_preset_provider_descriptor_t *desc;
+typedef struct clap_preset_discovery_provider {
+ const clap_preset_discovery_provider_descriptor_t *desc;
// Destroys the preset provider
- void(CLAP_ABI *destroy)(const struct clap_preset_provider *provider);
+ void(CLAP_ABI *destroy)(const struct clap_preset_discovery_provider *provider);
- // Retrives the path to a watch file.
- // Whenever the given file is "touched", then the indexer shall invalidate all the data.
- bool(CLAP_ABI *invalidation_watch_file)(const struct clap_preset_provider *provider,
- char *watch_file_path,
- uint32_t watch_file_path_capacity);
+ // Asks the preset provider to register its locations
+ void(CLAP_ABI *register_locations)(const struct clap_preset_discovery_provider *provider);
- // returns the number of locations
- uint32_t(CLAP_ABI *locations_count)(const struct clap_preset_provider *provider);
+ // Asks the preset provider to register its filetypes
+ void(CLAP_ABI *register_filetypes)(const struct clap_preset_discovery_provider *provider);
- // gets the location info at index
- bool(CLAP_ABI *get_location)(const struct clap_preset_provider *provider,
- uint32_t index,
- clap_preset_location_t *out_info);
+ // Asks the preset provider to register its collections
+ void(CLAP_ABI *register_collections)(const struct clap_preset_discovery_provider *provider);
- // returns the number of different supported file extensions
- uint32_t(CLAP_ABI *file_extensions_count)(const struct clap_preset_provider *provider);
-
- // stores the file extensions at index into out_extension.
- // `.' isn't included in the string.
- // If out_extension is empty then every file should be matched.
- // capacity:
- // - in: the number of bytes available to store the extension
- // - out: the number of bytes required to store the extension (not including '\0')
- bool(CLAP_ABI *get_file_extension)(const struct clap_preset_provider *provider,
- uint32_t index,
- char *out_extension,
- uint32_t *capacity);
-
- // gets information about a given collection.
- bool(CLAP_ABI *get_collection_info)(const struct clap_preset_provider *provider,
- const char *collection_id,
- clap_preset_collection_info_t *out_info);
+ // Retrives the path to a watch file.
+ // Whenever the given file is "touched", then the indexer shall invalidate all the data.
+ bool(CLAP_ABI *invalidation_watch_file)(const struct clap_preset_discovery_provider *provider,
+ char *watch_file_path,
+ uint32_t watch_file_path_capacity);
// reads metadata from the given file and passes them to the metadata receiver
- bool(CLAP_ABI *get_metadata)(const struct clap_preset_provider *provider,
- const char *uri,
- const clap_preset_metadata_receiver_t *metadata_receiver);
-} clap_preset_provider_t;
+ bool(CLAP_ABI *get_metadata)(const struct clap_preset_discovery_provider *provider,
+ const char *uri,
+ const clap_preset_discovery_metadata_receiver_t *metadata_receiver);
+} clap_preset_discovery_provider_t;
-typedef struct clap_preset_indexer {
+typedef struct clap_preset_discovery_indexer {
clap_version_t clap_version; // initialized to CLAP_VERSION
const char *name;
const char *vendor;
const char *version;
+
+ // Registers a preset filetype
+ void(CLAP_ABI *register_filetype)(const struct clap_preset_discovery_indexer *indexer,
+ const clap_preset_discovery_filetype_t *filetype);
+
+ // Registers a preset location
+ void(CLAP_ABI *register_location)(const struct clap_preset_discovery_indexer *indexer,
+ const clap_preset_discovery_location_t *location);
+
+ // Registers a preset collection
+ void(CLAP_ABI *register_collection)(const struct clap_preset_discovery_indexer *indexer,
+ const clap_preset_discovery_collection_t *collection);
} clap_preset_indexer_t;
// Every methods in this factory must be thread-safe.
@@ -240,7 +264,7 @@ typedef struct clap_preset_discovery_factory {
// Returns null in case of error.
// The descriptor must not be freed.
// [thread-safe]
- const clap_preset_provider_descriptor_t *(CLAP_ABI *get_descriptor)(
+ const clap_preset_discovery_provider_descriptor_t *(CLAP_ABI *get_descriptor)(
const struct clap_preset_discovery_factory *factory, uint32_t index);
// Create a preset provider by its id.
@@ -248,7 +272,7 @@ typedef struct clap_preset_discovery_factory {
// The preset provider is not allowed to use the indexer callbacks in the create method.
// Returns null in case of error.
// [thread-safe]
- const clap_preset_provider_t *(CLAP_ABI *create)(
+ const clap_preset_discovery_provider_t *(CLAP_ABI *create)(
const struct clap_preset_discovery_factory *factory,
const clap_preset_indexer_t *indexer,
const char *provider_id);
diff --git a/include/clap/string-sizes.h b/include/clap/string-sizes.h
@@ -14,12 +14,6 @@ enum {
// This is not suited for describing a file path on the disk, as NTFS allows up to 32K long
// paths.
CLAP_PATH_SIZE = 1024,
-
- // String capacity for descriptions
- CLAP_DESCRIPTION_SIZE = 1024,
-
- // String capacity for describing a filesystem file path, an web URL, ...
- CLAP_URI_SIZE = 8192,
};
#ifdef __cplusplus