From eb7902a8c4f1ce235f35c79f5373b9a0b57c31d2 Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Thu, 18 Apr 2024 13:43:28 +0200 Subject: [PATCH 01/16] initial draft on undo v2.0 --- include/clap/all.h | 1 + include/clap/ext/draft/undo.h | 104 ++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 include/clap/ext/draft/undo.h diff --git a/include/clap/all.h b/include/clap/all.h index 45412475..e991a781 100644 --- a/include/clap/all.h +++ b/include/clap/all.h @@ -10,3 +10,4 @@ #include "ext/draft/transport-control.h" #include "ext/draft/triggers.h" #include "ext/draft/tuning.h" +#include "ext/draft/undo.h" \ No newline at end of file diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h new file mode 100644 index 00000000..ea859e17 --- /dev/null +++ b/include/clap/ext/draft/undo.h @@ -0,0 +1,104 @@ +#pragma once + +#include "../../plugin.h" + +static CLAP_CONSTEXPR const char CLAP_EXT_UNDO[] = "clap.undo/2"; + +#ifdef __cplusplus +extern "C" { +#endif + +/// @page Undo +/// +/// This extension enables the plugin to merge its undo history with the host. +/// This leads to a single undo history shared by the host and many plugins. +/// +/// Calling host->undo() or host->redo() is equivalent to clicking undo/redo within the host's GUI. +/// +/// If the plugin implements this interface then its undo and redo should be entirely delegated to +/// the host; clicking in the plugin's UI undo or redo is equivalent to clicking undo or redo in the +/// host's UI. +/// +/// Some changes are long running changes, for example a mouse interaction will begin editing some +/// complex data and it may take multiple events and a long duration to complete the change. +/// In such case the plugin will call host->begin_change() to indicate the begining of a long +/// running change and complete the change by calling host->complete_change(). +/// +/// The host may group changes together: +/// [---------------------------------] +/// ^-T0 ^-T1 ^-T2 ^-T3 +/// Here a long running change C0 begin at T0. +/// A instantaneous change C1 at T1, and another one C2 at T2. +/// Then at T3 the long running change is completed. +/// The host will then create a single undo step that will merge all the changes into C0. +/// +/// This leads to another important consideration: starting a long running change without +/// terminating is **VERY BAD**. +/// +/// Rationale: multiple designs were considered and this one has the benefit of having a single undo +/// history. This simplifies the host implementation, leading to less bugs and a more robust design +/// and maybe an easier experience for the user because there's a single undo context versus one +/// for the host and one for each plugin instance. + +enum clap_undo_context_flags { + CLAP_UNDO_IS_WITHIN_CHANGE = 1 << 0, + + // This indicates that the next undo/redo operation is related to this plugin instance + CLAP_UNDO_NEXT_UNDO_IS_RELATED = 1 << 1, + CLAP_UNDO_NEXT_REDO_IS_RELATED = 1 << 2, +}; + +typedef struct clap_plugin_undo { + // Applies synchronously a delta. + // Returns true on success. + // [main-thread] + bool(CLAP_ABI *apply_delta)(const clap_plugin_t *plugin, const void *delta, size_t delta_size); + + // Sets the undo context. + // flags: bitmask of clap_undo_context_flags values + // names: null terminated string if an redo/undo step exists, null otherwise. + // [main-thread] + void(CLAP_ABI *set_context)(const clap_plugin_t *plugin, + uint64_t flags, + const char *undo_name, + const char *redo_name); +} clap_plugin_undo_t; + +typedef struct clap_host_undo { + // Begins a long running change. + // The plugin must not call this twice: there must be either a call to cancel_change() or + // complete_change() before calling begin_change() again. + // [main-thread] + void(CLAP_ABI *begin_change)(const clap_host_t *host); + + // Cancels a long running change. + // cancel_change() must not be called without a preceding begin_change(). + // [main-thread] + void(CLAP_ABI *cancel_change)(const clap_host_t *host); + + // Completes an undoable change. + // name: mandatory null terminated string describing the change, this is displayed to the user + // detlas: optional, they are binary blobs used to perform the undo and redo. When not available + // the host will save of the plugin and use state->load() instead. + // [main-thread] + void(CLAP_ABI *complete_change)(const clap_host_t *host, + const char *name, + const void *redo_delta, + size_t redo_delta_size, + const void *undo_delta, + size_t undo_delta_size); + + // Asks the host to perform the next undo step. + // This operation may be asynchronous. + // [main-thread] + void(CLAP_ABI *undo)(const clap_host_t *host); + + // Asks the host to perform the next redo step. + // This operation may be asynchronous. + // [main-thread] + void(CLAP_ABI *redo)(const clap_host_t *host); +} clap_host_undo_t; + +#ifdef __cplusplus +} +#endif From 546ed7dfb58d09a40df42dd9d18044d40b40c601 Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Thu, 18 Apr 2024 14:54:53 +0200 Subject: [PATCH 02/16] clarify undo --- include/clap/ext/draft/undo.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h index ea859e17..d31068f2 100644 --- a/include/clap/ext/draft/undo.h +++ b/include/clap/ext/draft/undo.h @@ -77,6 +77,10 @@ typedef struct clap_host_undo { void(CLAP_ABI *cancel_change)(const clap_host_t *host); // Completes an undoable change. + // At the moment of this function call, plugin_state->save() would include the current change. + // + // TODO: discuss implicit changes like parameter changes that should not need to be reported to the host. + // // name: mandatory null terminated string describing the change, this is displayed to the user // detlas: optional, they are binary blobs used to perform the undo and redo. When not available // the host will save of the plugin and use state->load() instead. From e4c7447fb91ba4b963e893f10671fd240d0cc12c Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Thu, 18 Apr 2024 18:30:13 +0200 Subject: [PATCH 03/16] make the delta forward compatible as a requirement --- include/clap/ext/draft/undo.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h index d31068f2..1fe13d7c 100644 --- a/include/clap/ext/draft/undo.h +++ b/include/clap/ext/draft/undo.h @@ -84,6 +84,12 @@ typedef struct clap_host_undo { // name: mandatory null terminated string describing the change, this is displayed to the user // detlas: optional, they are binary blobs used to perform the undo and redo. When not available // the host will save of the plugin and use state->load() instead. + // + // Note: the provided delta **must** be serialized in a forward compatible way, because they may be used + // for incremental state saving and crash recovery. If the plugin is updated after the host crash, + // then we must be able to use delta created with an older version of the plugin. + // Worst case plugin->apply_delta() will fail but this is a scenario we prefer to avoid. + // // [main-thread] void(CLAP_ABI *complete_change)(const clap_host_t *host, const char *name, From f19882c57c4f5937109a2a5fcfeddcf4fa735c60 Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Fri, 19 Apr 2024 12:05:19 +0200 Subject: [PATCH 04/16] Add delta format version id and context subscription --- include/clap/ext/draft/undo.h | 54 +++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h index 1fe13d7c..ac0cfab3 100644 --- a/include/clap/ext/draft/undo.h +++ b/include/clap/ext/draft/undo.h @@ -41,27 +41,39 @@ extern "C" { /// for the host and one for each plugin instance. enum clap_undo_context_flags { + // While the host is within a change, it is impossible to perform undo or redo CLAP_UNDO_IS_WITHIN_CHANGE = 1 << 0, - - // This indicates that the next undo/redo operation is related to this plugin instance - CLAP_UNDO_NEXT_UNDO_IS_RELATED = 1 << 1, - CLAP_UNDO_NEXT_REDO_IS_RELATED = 1 << 2, }; typedef struct clap_plugin_undo { + // Asks the plugin what is the current delta format version. + // If the binary isn't supported at all, return CLAP_INVALID_ID. + // [main-thread] + clap_id(CLAP_ABI *get_delta_format_version)(const clap_plugin_t *plugin); + + // Asks the plugin if it can apply a delta using the given format version. + // Returns true if it is possible. + // [main-thread] + bool(CLAP_ABI *can_use_delta_format_version)(const clap_plugin_t *plugin, + clap_id format_version); + // Applies synchronously a delta. // Returns true on success. + // // [main-thread] - bool(CLAP_ABI *apply_delta)(const clap_plugin_t *plugin, const void *delta, size_t delta_size); + bool(CLAP_ABI *apply_delta)(const clap_plugin_t *plugin, + clap_id format_version, + const void *delta, + size_t delta_size); // Sets the undo context. // flags: bitmask of clap_undo_context_flags values // names: null terminated string if an redo/undo step exists, null otherwise. // [main-thread] - void(CLAP_ABI *set_context)(const clap_plugin_t *plugin, - uint64_t flags, - const char *undo_name, - const char *redo_name); + void(CLAP_ABI *set_context_info)(const clap_plugin_t *plugin, + uint64_t flags, + const char *undo_name, + const char *redo_name); } clap_plugin_undo_t; typedef struct clap_host_undo { @@ -79,16 +91,19 @@ typedef struct clap_host_undo { // Completes an undoable change. // At the moment of this function call, plugin_state->save() would include the current change. // - // TODO: discuss implicit changes like parameter changes that should not need to be reported to the host. + // TODO: discuss implicit changes like parameter changes that should not need to be reported to + // the host. // // name: mandatory null terminated string describing the change, this is displayed to the user + // // detlas: optional, they are binary blobs used to perform the undo and redo. When not available - // the host will save of the plugin and use state->load() instead. + // the host will save the plugin state and use state->load() to perform undo and redo. // - // Note: the provided delta **must** be serialized in a forward compatible way, because they may be used - // for incremental state saving and crash recovery. If the plugin is updated after the host crash, - // then we must be able to use delta created with an older version of the plugin. - // Worst case plugin->apply_delta() will fail but this is a scenario we prefer to avoid. + // Note: the provided delta **must** be serialized in a persistant way, because they may + // be used for incremental state saving and crash recovery. The plugin can indicate a format + // version id for the binary blobs, which the host can use to verify the compatiblilty before + // applying the delta. If the plugin is not able to use the delta, a notification should be + // produced to the user and the crash recovery will restore the latest saved state. // // [main-thread] void(CLAP_ABI *complete_change)(const clap_host_t *host, @@ -107,6 +122,15 @@ typedef struct clap_host_undo { // This operation may be asynchronous. // [main-thread] void(CLAP_ABI *redo)(const clap_host_t *host); + + // Subscribes to undo context info. + // The plugin may only need the context info if it's GUI is shown and it wants to display + // undo/redo info. + // + // wants_info: set to true to receive context info + // + // [main-thread] + void(CLAP_ABI *subscribe_to_context_info)(const clap_host_t *host, bool wants_info); } clap_host_undo_t; #ifdef __cplusplus From d90218693ddd0977857441b4ec9d91a93577a227 Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Fri, 19 Apr 2024 22:10:09 +0200 Subject: [PATCH 05/16] add a lifetime info to the undo delta --- include/clap/ext/draft/undo.h | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h index ac0cfab3..d1a5e871 100644 --- a/include/clap/ext/draft/undo.h +++ b/include/clap/ext/draft/undo.h @@ -45,11 +45,33 @@ enum clap_undo_context_flags { CLAP_UNDO_IS_WITHIN_CHANGE = 1 << 0, }; +enum clap_undo_delta_lifetime { + // The delta is valid for the duration of the plugin instance. + CLAP_UNDO_DELTA_LIFETIME_INSTANCE, + + // The delta is valid beyond the plugin instance, as long as the plugin is compatible with the + // current format version. + CLAP_UNDO_DELTA_LIFETIME_PERSISTANT, + + // The plugin guarentees that the delta will be forward compatible with all future version of + // this plugin. + CLAP_UNDO_DELTA_LIFETIME_FOREVER, +}; + +typedef struct clap_undo_delta_properties { + // This represent the delta format version that the plugin is using. + // Set to CLAP_INVALID_ID if irrelevant. + clap_id format_version; + + // see clap_undo_delta_lifetime + uint32_t lifetime; +} clap_undo_delta_properties_t; + typedef struct clap_plugin_undo { - // Asks the plugin what is the current delta format version. - // If the binary isn't supported at all, return CLAP_INVALID_ID. + // Asks the plugin the delta properties. // [main-thread] - clap_id(CLAP_ABI *get_delta_format_version)(const clap_plugin_t *plugin); + void(CLAP_ABI *get_delta_properties)(const clap_plugin_t *plugin, + clap_undo_delta_properties_t *properties); // Asks the plugin if it can apply a delta using the given format version. // Returns true if it is possible. From 35a97b1841ca1ec9c9f4d8b8928acb026f8966ba Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Fri, 19 Apr 2024 22:13:07 +0200 Subject: [PATCH 06/16] undo: doc --- include/clap/ext/draft/undo.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h index d1a5e871..6ab34bfd 100644 --- a/include/clap/ext/draft/undo.h +++ b/include/clap/ext/draft/undo.h @@ -121,11 +121,11 @@ typedef struct clap_host_undo { // detlas: optional, they are binary blobs used to perform the undo and redo. When not available // the host will save the plugin state and use state->load() to perform undo and redo. // - // Note: the provided delta **must** be serialized in a persistant way, because they may - // be used for incremental state saving and crash recovery. The plugin can indicate a format - // version id for the binary blobs, which the host can use to verify the compatiblilty before - // applying the delta. If the plugin is not able to use the delta, a notification should be - // produced to the user and the crash recovery will restore the latest saved state. + // Note: the provided delta may be used for incremental state saving and crash recovery. The + // plugin can indicate a format version id and the validity lifetime for the binary blobs. + // The host can use to verify the compatiblilty before applying the delta. + // If the plugin is not able to use a delta, a notification should be produced to the user and + // the crash recovery will do a best effort job, at least restore the latest saved state. // // [main-thread] void(CLAP_ABI *complete_change)(const clap_host_t *host, From f332bcebfe56691f9d1b80bd21013831b04be88c Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Fri, 19 Apr 2024 22:25:24 +0200 Subject: [PATCH 07/16] Add implicit change --- include/clap/ext/draft/undo.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h index 6ab34bfd..7a8c76cd 100644 --- a/include/clap/ext/draft/undo.h +++ b/include/clap/ext/draft/undo.h @@ -40,6 +40,9 @@ extern "C" { /// and maybe an easier experience for the user because there's a single undo context versus one /// for the host and one for each plugin instance. +// When supported, the plugin doesn't need to call host->complete_change() after a parameter set. +static CLAP_CONSTEXPR const char CLAP_UNDO_IMPLICIT_PARAM_SET[] = "param-set"; + enum clap_undo_context_flags { // While the host is within a change, it is impossible to perform undo or redo CLAP_UNDO_IS_WITHIN_CHANGE = 1 << 0, @@ -79,6 +82,17 @@ typedef struct clap_plugin_undo { bool(CLAP_ABI *can_use_delta_format_version)(const clap_plugin_t *plugin, clap_id format_version); + // Enables implicit change for this change_type. + // See CLAP_UNDO_IMPLICIT_PARAM_SET. + // + // An implicit change is a change that is reported and understood by the host, so it doesn't + // require the plugin declare it by calling host->complete_change(). + // For example, the host could create the undo step after changing a parameter value. + // + // Returns true if supported by the plugin. + // [main-thread] + bool(CLAP_ABI *enable_implicit_change)(const clap_plugin_t *plugin, const char *change_type); + // Applies synchronously a delta. // Returns true on success. // @@ -113,9 +127,6 @@ typedef struct clap_host_undo { // Completes an undoable change. // At the moment of this function call, plugin_state->save() would include the current change. // - // TODO: discuss implicit changes like parameter changes that should not need to be reported to - // the host. - // // name: mandatory null terminated string describing the change, this is displayed to the user // // detlas: optional, they are binary blobs used to perform the undo and redo. When not available From ce78ca62807591732d6433f873fdf3dca3d622b4 Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Fri, 19 Apr 2024 22:32:15 +0200 Subject: [PATCH 08/16] Add CLAP_UNDO_DELTA_LIFETIME_VOID --- include/clap/ext/draft/undo.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h index 7a8c76cd..3a076923 100644 --- a/include/clap/ext/draft/undo.h +++ b/include/clap/ext/draft/undo.h @@ -49,16 +49,19 @@ enum clap_undo_context_flags { }; enum clap_undo_delta_lifetime { + // No delta will be provided. + CLAP_UNDO_DELTA_LIFETIME_VOID = 0, + // The delta is valid for the duration of the plugin instance. - CLAP_UNDO_DELTA_LIFETIME_INSTANCE, + CLAP_UNDO_DELTA_LIFETIME_INSTANCE = 1, // The delta is valid beyond the plugin instance, as long as the plugin is compatible with the // current format version. - CLAP_UNDO_DELTA_LIFETIME_PERSISTANT, + CLAP_UNDO_DELTA_LIFETIME_PERSISTANT = 2, // The plugin guarentees that the delta will be forward compatible with all future version of // this plugin. - CLAP_UNDO_DELTA_LIFETIME_FOREVER, + CLAP_UNDO_DELTA_LIFETIME_FOREVER = 3, }; typedef struct clap_undo_delta_properties { From b3ffd50b990f1e43584e73dceccb6c310fe8b952 Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Fri, 19 Apr 2024 22:33:11 +0200 Subject: [PATCH 09/16] doc. --- include/clap/ext/draft/undo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h index 3a076923..2c25ae4c 100644 --- a/include/clap/ext/draft/undo.h +++ b/include/clap/ext/draft/undo.h @@ -159,7 +159,7 @@ typedef struct clap_host_undo { // [main-thread] void(CLAP_ABI *redo)(const clap_host_t *host); - // Subscribes to undo context info. + // Subscribes or unsubscribe to undo context info. // The plugin may only need the context info if it's GUI is shown and it wants to display // undo/redo info. // From aaf5745452e4d638f33655a88618dc1c188335fa Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Fri, 19 Apr 2024 22:35:53 +0200 Subject: [PATCH 10/16] doc. --- include/clap/ext/draft/undo.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h index 2c25ae4c..012c7d8b 100644 --- a/include/clap/ext/draft/undo.h +++ b/include/clap/ext/draft/undo.h @@ -33,10 +33,11 @@ extern "C" { /// The host will then create a single undo step that will merge all the changes into C0. /// /// This leads to another important consideration: starting a long running change without -/// terminating is **VERY BAD**. +/// terminating is **VERY BAD**, because while a change is running it is impossible to call undo or +/// redo. /// /// Rationale: multiple designs were considered and this one has the benefit of having a single undo -/// history. This simplifies the host implementation, leading to less bugs and a more robust design +/// history. This simplifies the host implementation, leading to less bugs, a more robust design /// and maybe an easier experience for the user because there's a single undo context versus one /// for the host and one for each plugin instance. From 9fbc411c7c1a915054fe160477ebdaa48089191b Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Fri, 19 Apr 2024 22:42:30 +0200 Subject: [PATCH 11/16] typo --- include/clap/ext/draft/undo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h index 012c7d8b..1eb30059 100644 --- a/include/clap/ext/draft/undo.h +++ b/include/clap/ext/draft/undo.h @@ -45,7 +45,7 @@ extern "C" { static CLAP_CONSTEXPR const char CLAP_UNDO_IMPLICIT_PARAM_SET[] = "param-set"; enum clap_undo_context_flags { - // While the host is within a change, it is impossible to perform undo or redo + // While the host is within a change, it is impossible to perform undo or redo. CLAP_UNDO_IS_WITHIN_CHANGE = 1 << 0, }; From ce92aa2c54c215511a694831d6c582caee8ddca7 Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Mon, 22 Apr 2024 10:48:42 +0200 Subject: [PATCH 12/16] complete_change() -> change_made() --- include/clap/ext/draft/undo.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h index 1eb30059..516c42b5 100644 --- a/include/clap/ext/draft/undo.h +++ b/include/clap/ext/draft/undo.h @@ -22,7 +22,7 @@ extern "C" { /// Some changes are long running changes, for example a mouse interaction will begin editing some /// complex data and it may take multiple events and a long duration to complete the change. /// In such case the plugin will call host->begin_change() to indicate the begining of a long -/// running change and complete the change by calling host->complete_change(). +/// running change and complete the change by calling host->change_made(). /// /// The host may group changes together: /// [---------------------------------] @@ -41,7 +41,7 @@ extern "C" { /// and maybe an easier experience for the user because there's a single undo context versus one /// for the host and one for each plugin instance. -// When supported, the plugin doesn't need to call host->complete_change() after a parameter set. +// When supported, the plugin doesn't need to call host->change_made() after a parameter set. static CLAP_CONSTEXPR const char CLAP_UNDO_IMPLICIT_PARAM_SET[] = "param-set"; enum clap_undo_context_flags { @@ -90,7 +90,7 @@ typedef struct clap_plugin_undo { // See CLAP_UNDO_IMPLICIT_PARAM_SET. // // An implicit change is a change that is reported and understood by the host, so it doesn't - // require the plugin declare it by calling host->complete_change(). + // require the plugin declare it by calling host->change_made(). // For example, the host could create the undo step after changing a parameter value. // // Returns true if supported by the plugin. @@ -119,7 +119,7 @@ typedef struct clap_plugin_undo { typedef struct clap_host_undo { // Begins a long running change. // The plugin must not call this twice: there must be either a call to cancel_change() or - // complete_change() before calling begin_change() again. + // change_made() before calling begin_change() again. // [main-thread] void(CLAP_ABI *begin_change)(const clap_host_t *host); @@ -143,12 +143,12 @@ typedef struct clap_host_undo { // the crash recovery will do a best effort job, at least restore the latest saved state. // // [main-thread] - void(CLAP_ABI *complete_change)(const clap_host_t *host, - const char *name, - const void *redo_delta, - size_t redo_delta_size, - const void *undo_delta, - size_t undo_delta_size); + void(CLAP_ABI *change_made)(const clap_host_t *host, + const char *name, + const void *redo_delta, + size_t redo_delta_size, + const void *undo_delta, + size_t undo_delta_size); // Asks the host to perform the next undo step. // This operation may be asynchronous. From 27517a5c246ef319f015a0449bde0641f8313516 Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Mon, 22 Apr 2024 10:56:09 +0200 Subject: [PATCH 13/16] Simplify the delta properties --- include/clap/ext/draft/undo.h | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h index 516c42b5..027bc14a 100644 --- a/include/clap/ext/draft/undo.h +++ b/include/clap/ext/draft/undo.h @@ -49,29 +49,22 @@ enum clap_undo_context_flags { CLAP_UNDO_IS_WITHIN_CHANGE = 1 << 0, }; -enum clap_undo_delta_lifetime { - // No delta will be provided. - CLAP_UNDO_DELTA_LIFETIME_VOID = 0, - - // The delta is valid for the duration of the plugin instance. - CLAP_UNDO_DELTA_LIFETIME_INSTANCE = 1, - - // The delta is valid beyond the plugin instance, as long as the plugin is compatible with the - // current format version. - CLAP_UNDO_DELTA_LIFETIME_PERSISTANT = 2, - - // The plugin guarentees that the delta will be forward compatible with all future version of - // this plugin. - CLAP_UNDO_DELTA_LIFETIME_FOREVER = 3, +enum clap_undo_delta_properties_flags { + // If not set, then all clap_undo_delta_properties's attributes becomes irrelevant. + // If set, then the plugin will provide deltas in host->change_made(). + CLAP_UNDO_DELTA_PROPERTIES_HAS_DELTA = 1 << 0, + + // If set, then the delta will be re-usable in the future as long as the plugin is + // compatible with the given format_version. + CLAP_UNDO_DELTA_PROPERTIES_IS_PERSISTANT = 1 << 0, }; typedef struct clap_undo_delta_properties { - // This represent the delta format version that the plugin is using. - // Set to CLAP_INVALID_ID if irrelevant. - clap_id format_version; + // Bitmask of clap_undo_delta_properties_flags + uint64_t flags; - // see clap_undo_delta_lifetime - uint32_t lifetime; + // This represent the delta format version that the plugin is using. + uint32_t format_version; } clap_undo_delta_properties_t; typedef struct clap_plugin_undo { From 92f68fcb197e5a88eb0229ea194a899927b3b71e Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Mon, 22 Apr 2024 10:59:46 +0200 Subject: [PATCH 14/16] subscribe_to_context_info -> set_wants_context_info --- include/clap/ext/draft/undo.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h index 027bc14a..1ba85739 100644 --- a/include/clap/ext/draft/undo.h +++ b/include/clap/ext/draft/undo.h @@ -157,10 +157,12 @@ typedef struct clap_host_undo { // The plugin may only need the context info if it's GUI is shown and it wants to display // undo/redo info. // + // Initial state is unsubscribed. + // // wants_info: set to true to receive context info // // [main-thread] - void(CLAP_ABI *subscribe_to_context_info)(const clap_host_t *host, bool wants_info); + void(CLAP_ABI *set_wants_context_info)(const clap_host_t *host, bool wants_info); } clap_host_undo_t; #ifdef __cplusplus From d1274b8538d173c708552ced7b05120b1df270d4 Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Mon, 22 Apr 2024 11:03:12 +0200 Subject: [PATCH 15/16] Rule for implicit changes --- include/clap/ext/draft/undo.h | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h index 1ba85739..1221db93 100644 --- a/include/clap/ext/draft/undo.h +++ b/include/clap/ext/draft/undo.h @@ -41,9 +41,6 @@ extern "C" { /// and maybe an easier experience for the user because there's a single undo context versus one /// for the host and one for each plugin instance. -// When supported, the plugin doesn't need to call host->change_made() after a parameter set. -static CLAP_CONSTEXPR const char CLAP_UNDO_IMPLICIT_PARAM_SET[] = "param-set"; - enum clap_undo_context_flags { // While the host is within a change, it is impossible to perform undo or redo. CLAP_UNDO_IS_WITHIN_CHANGE = 1 << 0, @@ -79,17 +76,6 @@ typedef struct clap_plugin_undo { bool(CLAP_ABI *can_use_delta_format_version)(const clap_plugin_t *plugin, clap_id format_version); - // Enables implicit change for this change_type. - // See CLAP_UNDO_IMPLICIT_PARAM_SET. - // - // An implicit change is a change that is reported and understood by the host, so it doesn't - // require the plugin declare it by calling host->change_made(). - // For example, the host could create the undo step after changing a parameter value. - // - // Returns true if supported by the plugin. - // [main-thread] - bool(CLAP_ABI *enable_implicit_change)(const clap_plugin_t *plugin, const char *change_type); - // Applies synchronously a delta. // Returns true on success. // @@ -135,6 +121,10 @@ typedef struct clap_host_undo { // If the plugin is not able to use a delta, a notification should be produced to the user and // the crash recovery will do a best effort job, at least restore the latest saved state. // + // Special case: for objects with shared and synchronized state, changes shouldn't be reported + // as the host already knows about it. + // For example, plugin parameters changes shouldn't produce a call to change_made(). + // // [main-thread] void(CLAP_ABI *change_made)(const clap_host_t *host, const char *name, From 3cb07ba4401676534d521b46ae600b702e16db90 Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Tue, 23 Apr 2024 16:27:55 +0200 Subject: [PATCH 16/16] Fix bad constant --- include/clap/ext/draft/undo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/clap/ext/draft/undo.h b/include/clap/ext/draft/undo.h index 1221db93..2dba1094 100644 --- a/include/clap/ext/draft/undo.h +++ b/include/clap/ext/draft/undo.h @@ -53,7 +53,7 @@ enum clap_undo_delta_properties_flags { // If set, then the delta will be re-usable in the future as long as the plugin is // compatible with the given format_version. - CLAP_UNDO_DELTA_PROPERTIES_IS_PERSISTANT = 1 << 0, + CLAP_UNDO_DELTA_PROPERTIES_IS_PERSISTANT = 1 << 1, }; typedef struct clap_undo_delta_properties {