From 89a8bffac3e97d7712c3594aa34691dc0b08a81d Mon Sep 17 00:00:00 2001 From: Hanspeter Portner Date: Tue, 13 Apr 2021 21:28:04 +0200 Subject: [PATCH] Squashed 'props.lv2/' changes from e142214..b0f93f3 b0f93f3 always clear temporary memory in save before fill. e2f4694 ttl: update license URI 7721efd prototype patch:Patch and dynamic parameters. git-subtree-dir: props.lv2 git-subtree-split: b0f93f3e71521baf203cc3f0246387301ac3d3d0 --- VERSION | 2 +- props.h | 110 +++++++++++++++++++++++++++++++++++++++++++++++++ test/props.ttl | 3 +- 3 files changed, 112 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index a63a9fe..5130959 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.159 +0.1.165 diff --git a/props.h b/props.h index 0ea0396..b3905ab 100644 --- a/props.h +++ b/props.h @@ -40,14 +40,28 @@ extern "C" { // structures typedef struct _props_def_t props_def_t; typedef struct _props_impl_t props_impl_t; +typedef struct _props_dyn_t props_dyn_t; typedef struct _props_t props_t; +typedef enum _props_dyn_ev_t { + PROPS_DYN_EV_ADD, + PROPS_DYN_EV_REM, + PROPS_DYN_EV_SET +} props_dyn_ev_t; + // function callbacks typedef void (*props_event_cb_t)( void *data, int64_t frames, props_impl_t *impl); +typedef void (*props_dyn_prop_cb_t)( + void *data, + props_dyn_ev_t ev, + LV2_URID subj, + LV2_URID prop, + const LV2_Atom *body); + struct _props_def_t { const char *property; const char *type; @@ -79,6 +93,10 @@ struct _props_impl_t { bool stashing; }; +struct _props_dyn_t { + props_dyn_prop_cb_t prop; +}; + struct _props_t { struct { LV2_URID subject; @@ -122,6 +140,8 @@ struct _props_t { uint32_t max_size; + const props_dyn_t *dyn; + unsigned nimpls; props_impl_t impls [1]; }; @@ -137,6 +157,10 @@ props_init(props_t *props, const char *subject, void *value_base, void *stash_base, LV2_URID_Map *map, void *data); +// rt-safe +static inline void +props_dyn(props_t *props, const props_dyn_t *dyn); + // rt-safe static inline void props_idle(props_t *props, LV2_Atom_Forge *forge, uint32_t frames, @@ -602,6 +626,12 @@ props_init(props_t *props, const char *subject, return status; } +static inline void +props_dyn(props_t *props, const props_dyn_t *dyn) +{ + props->dyn = dyn; +} + static inline void props_idle(props_t *props, LV2_Atom_Forge *forge, uint32_t frames, LV2_Atom_Forge_Ref *ref) @@ -761,6 +791,14 @@ props_advance(props_t *props, LV2_Atom_Forge *forge, uint32_t frames, return 1; } + else if(props->dyn && props->dyn->prop) + { + const LV2_URID subj = subject ? subject->body : 0; + + props->dyn->prop(props->data, PROPS_DYN_EV_SET, subj, property->body, value); + + //TODO send ack + } else if(sequence_num) { if(*ref) @@ -823,6 +861,14 @@ props_advance(props_t *props, LV2_Atom_Forge *forge, uint32_t frames, if(def->event_cb) def->event_cb(props->data, frames, impl); } + else if(props->dyn && props->dyn->prop) + { + const LV2_URID subj = subject ? subject->body : 0; + + props->dyn->prop(props->data, PROPS_DYN_EV_SET, subj, property, value); + + //TODO send ack + } } if(sequence_num) @@ -833,6 +879,67 @@ props_advance(props_t *props, LV2_Atom_Forge *forge, uint32_t frames, return 1; } + else if(obj->body.otype == props->urid.patch_patch) + { + const LV2_Atom_URID *subject = NULL; + const LV2_Atom_Int *sequence = NULL; + const LV2_Atom_Object *add = NULL; + const LV2_Atom_Object *rem = NULL; + + lv2_atom_object_get(obj, + props->urid.patch_subject, &subject, + props->urid.patch_sequence, &sequence, + props->urid.patch_add, &add, + props->urid.patch_remove, &rem, + 0); + + LV2_URID subj = 0; + if(subject && (subject->atom.type == props->urid.atom_urid)) + { + subj = subject->body; + } + + int32_t sequence_num = 0; + if(sequence && (sequence->atom.type == props->urid.atom_int)) + { + sequence_num = sequence->body; + } + + if(rem && lv2_atom_forge_is_object_type(forge, rem->atom.type)) + { + LV2_ATOM_OBJECT_FOREACH(rem, prop) + { + const LV2_URID property = prop->key; + const LV2_Atom *value = &prop->value; + + if(props->dyn && props->dyn->prop) + { + props->dyn->prop(props->data, PROPS_DYN_EV_REM, subj, property, value); + } + } + } + + if(add && lv2_atom_forge_is_object_type(forge, add->atom.type)) + { + LV2_ATOM_OBJECT_FOREACH(add, prop) + { + const LV2_URID property = prop->key; + const LV2_Atom *value = &prop->value; + + if(props->dyn && props->dyn->prop) + { + props->dyn->prop(props->data, PROPS_DYN_EV_ADD, subj, property, value); + } + } + } + + if(sequence_num && *ref) + { + *ref = _props_patch_ack(props, forge, frames, sequence_num); + } + + return 1; + } return 0; // did not handle a patch event } @@ -981,6 +1088,9 @@ props_save(props_t *props, LV2_State_Store_Function store, if(impl->access == props->urid.patch_readable) continue; // skip read-only, as it makes no sense to restore them + // always clear memory + memset(body, 0x0, props->max_size); + _props_impl_spin_lock(impl, PROP_STATE_NONE, PROP_STATE_LOCK); // create temporary copy of value, store() may well be blocking diff --git a/test/props.ttl b/test/props.ttl index cd4d107..f2ce779 100644 --- a/test/props.ttl +++ b/test/props.ttl @@ -27,7 +27,6 @@ @prefix units: . @prefix xsd: . -@prefix lic: . @prefix omk: . @prefix proj: . @prefix props: . @@ -104,7 +103,7 @@ props:test a lv2:Plugin , lv2:ConverterPlugin ; doap:name "Props Test" ; - doap:license lic:Artistic-2.0 ; + doap:license ; lv2:project proj:props ; lv2:requiredFeature urid:map, log:log, state:loadDefaultState ; lv2:optionalFeature lv2:isLive, lv2:hardRTCapable, state:threadSafeRestore ; -- 2.38.5