aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanspeter Portner <dev@open-music-kontrollers.ch>2021-04-13 21:34:22 +0200
committerHanspeter Portner <dev@open-music-kontrollers.ch>2021-04-13 21:34:22 +0200
commitcd05543f34667eb32de70bccdecbdf520e60118c (patch)
tree4b2f9550bd5de215b35ca72d42e0117bc44fe331
parent71dc2855de65455f6da91f3de9e8ef47120f0a17 (diff)
downloadvm.lv2-cd05543f34667eb32de70bccdecbdf520e60118c.tar.xz
Squashed 'props.lv2/' changes from e142214b..b0f93f3e
b0f93f3e always clear temporary memory in save before fill. e2f46942 ttl: update license URI 7721efd8 prototype patch:Patch and dynamic parameters. git-subtree-dir: props.lv2 git-subtree-split: b0f93f3e71521baf203cc3f0246387301ac3d3d0
-rw-r--r--VERSION2
-rw-r--r--props.h110
-rw-r--r--test/props.ttl3
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];
};
@@ -139,6 +159,10 @@ props_init(props_t *props, const char *subject,
// 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,
LV2_Atom_Forge_Ref *ref);
@@ -603,6 +627,12 @@ props_init(props_t *props, const char *subject,
}
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: <http://lv2plug.in/ns/extensions/units#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
-@prefix lic: <http://opensource.org/licenses/> .
@prefix omk: <http://open-music-kontrollers.ch/ventosus#> .
@prefix proj: <http://open-music-kontrollers.ch/lv2/> .
@prefix props: <http://open-music-kontrollers.ch/lv2/props#> .
@@ -104,7 +103,7 @@ props:test
a lv2:Plugin ,
lv2:ConverterPlugin ;
doap:name "Props Test" ;
- doap:license lic:Artistic-2.0 ;
+ doap:license <https://spdx.org/licenses/Artistic-2.0> ;
lv2:project proj:props ;
lv2:requiredFeature urid:map, log:log, state:loadDefaultState ;
lv2:optionalFeature lv2:isLive, lv2:hardRTCapable, state:threadSafeRestore ;