~hp/link.lv2

5b912b77b60e63ad43bbd5d22990aa3e7a3e3d48 — Hanspeter Portner 3 years ago 9188a74 + 511f4f7
Merge commit '511f4f7e5d5ae1f3b861583d402a367987594052'
3 files changed, 112 insertions(+), 3 deletions(-)

M props.lv2/VERSION
M props.lv2/props.h
M props.lv2/test/props.ttl
M props.lv2/VERSION => props.lv2/VERSION +1 -1
@@ 1,1 1,1 @@
0.1.159
0.1.165

M props.lv2/props.h => props.lv2/props.h +110 -0
@@ 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

M props.lv2/test/props.ttl => props.lv2/test/props.ttl +1 -2
@@ 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 ;