diff options
| author | David Robillard <d@drobilla.net> | 2012-03-02 00:03:53 +0000 | 
|---|---|---|
| committer | David Robillard <d@drobilla.net> | 2012-03-02 00:03:53 +0000 | 
| commit | 6a848b53ef158648a4dc25274afeb668c530abd9 (patch) | |
| tree | ac346e53c87f379a1e6ca082b0963b6394b7498f /lv2/lv2plug.in/ns/ext | |
| parent | 88135c7bb27557e214928918ca46ecb86c790a0b (diff) | |
| download | lv2-6a848b53ef158648a4dc25274afeb668c530abd9.tar.xz | |
Add atom:childType.
Rename vector fields for consistently with atom:childType.
Change vector to have child type and size rather than num_elems, since that would require updating the body every time an element is added which ruins the usual atom construction pattern.
Implement incremental/automatic vector building with forge.
Diffstat (limited to 'lv2/lv2plug.in/ns/ext')
| -rw-r--r-- | lv2/lv2plug.in/ns/ext/atom/atom-test.c | 24 | ||||
| -rw-r--r-- | lv2/lv2plug.in/ns/ext/atom/atom.h | 5 | ||||
| -rw-r--r-- | lv2/lv2plug.in/ns/ext/atom/atom.ttl | 21 | ||||
| -rw-r--r-- | lv2/lv2plug.in/ns/ext/atom/forge.h | 74 | 
4 files changed, 85 insertions, 39 deletions
| diff --git a/lv2/lv2plug.in/ns/ext/atom/atom-test.c b/lv2/lv2plug.in/ns/ext/atom/atom-test.c index addad81..c92a370 100644 --- a/lv2/lv2plug.in/ns/ext/atom/atom-test.c +++ b/lv2/lv2plug.in/ns/ext/atom/atom-test.c @@ -79,10 +79,11 @@ main()  	LV2_URID eg_literal = urid_map(NULL, "http://example.org/literal");  	LV2_URID eg_tuple   = urid_map(NULL, "http://example.org/tuple");  	LV2_URID eg_vector  = urid_map(NULL, "http://example.org/vector"); +	LV2_URID eg_vector2 = urid_map(NULL, "http://example.org/vector2");  	LV2_URID eg_seq     = urid_map(NULL, "http://example.org/seq");  #define BUF_SIZE  1024 -#define NUM_PROPS 14 +#define NUM_PROPS 15  	uint8_t buf[BUF_SIZE];  	lv2_atom_forge_set_buffer(&forge, buf, BUF_SIZE); @@ -230,12 +231,26 @@ main()  	int32_t elems[] = { 1, 2, 3, 4 };  	LV2_Atom_Vector* vector = (LV2_Atom_Vector*)lv2_atom_forge_deref(  		&forge, lv2_atom_forge_vector( -			&forge, 4, forge.Int32, sizeof(int32_t), elems));; +			&forge, sizeof(int32_t), forge.Int32, 4, elems));  	void* vec_body = LV2_ATOM_CONTENTS(LV2_Atom_Vector, vector);  	if (memcmp(elems, vec_body, sizeof(elems))) {  		return test_fail("Corrupt vector\n");  	} +	// eg_vector2 = (Vector<Int32>)1,2,3,4 +	lv2_atom_forge_property_head(&forge, eg_vector2, 0); +	LV2_Atom_Forge_Frame vec_frame; +	LV2_Atom_Vector* vector2 = (LV2_Atom_Vector*)lv2_atom_forge_deref( +		&forge, lv2_atom_forge_vector_head( +			&forge, &vec_frame, sizeof(int32_t), forge.Int32)); +	for (unsigned i = 0; i < sizeof(elems) / sizeof(int32_t); ++i) { +		lv2_atom_forge_int32(&forge, elems[i]); +	} +	lv2_atom_forge_pop(&forge, &vec_frame); +	if (!lv2_atom_equals(&vector->atom, &vector2->atom)) { +		return test_fail("Vector != Vector2\n"); +	} +  	// eg_seq = (Sequence)1, 2  	lv2_atom_forge_property_head(&forge, eg_seq, 0);  	LV2_Atom_Forge_Frame seq_frame; @@ -302,6 +317,7 @@ main()  		const LV2_Atom* literal;  		const LV2_Atom* tuple;  		const LV2_Atom* vector; +		const LV2_Atom* vector2;  		const LV2_Atom* seq;  	} matches; @@ -321,6 +337,7 @@ main()  		{ eg_literal, &matches.literal },  		{ eg_tuple,   &matches.tuple },  		{ eg_vector,  &matches.vector }, +		{ eg_vector2, &matches.vector2 },  		{ eg_seq,     &matches.seq },  		LV2_OBJECT_QUERY_END  	}; @@ -354,6 +371,8 @@ main()  			return test_fail("Bad match tuple\n");  		} else if (!lv2_atom_equals((LV2_Atom*)vector, matches.vector)) {  			return test_fail("Bad match vector\n"); +		} else if (!lv2_atom_equals((LV2_Atom*)vector, matches.vector2)) { +			return test_fail("Bad match vector2\n");  		} else if (!lv2_atom_equals((LV2_Atom*)seq, matches.seq)) {  			return test_fail("Bad match sequence\n");  		} @@ -372,6 +391,7 @@ main()  		                           eg_literal, &matches.literal,  		                           eg_tuple,   &matches.tuple,  		                           eg_vector,  &matches.vector, +		                           eg_vector2, &matches.vector2,  		                           eg_seq,     &matches.seq,  		                           0);  	} diff --git a/lv2/lv2plug.in/ns/ext/atom/atom.h b/lv2/lv2plug.in/ns/ext/atom/atom.h index 2eed233..abb0eea 100644 --- a/lv2/lv2plug.in/ns/ext/atom/atom.h +++ b/lv2/lv2plug.in/ns/ext/atom/atom.h @@ -54,6 +54,7 @@  #define LV2_ATOM__URID          LV2_ATOM_URI "#URID"  #define LV2_ATOM__ValuePort     LV2_ATOM_URI "#ValuePort"  #define LV2_ATOM__Vector        LV2_ATOM_URI "#Vector" +#define LV2_ATOM__childType     LV2_ATOM_URI "#childType"  #define LV2_ATOM__beatTime      LV2_ATOM_URI "#beatTime"  #define LV2_ATOM__bufferType    LV2_ATOM_URI "#bufferType"  #define LV2_ATOM__eventTransfer LV2_ATOM_URI "#eventTransfer" @@ -152,8 +153,8 @@ typedef struct {  /** The body of an atom:Vector. */  typedef struct { -	uint32_t elem_count;  /**< The number of elements in the vector */ -	uint32_t elem_type;   /**< The type of each element in the vector */ +	uint32_t child_size;  /**< The size of each element in the vector. */ +	uint32_t child_type;  /**< The type of each element in the vector. */  	/* Contents (a series of packed atom bodies) follow here. */  } LV2_Atom_Vector_Body; diff --git a/lv2/lv2plug.in/ns/ext/atom/atom.ttl b/lv2/lv2plug.in/ns/ext/atom/atom.ttl index 1a2b92a..1b2ed1d 100644 --- a/lv2/lv2plug.in/ns/ext/atom/atom.ttl +++ b/lv2/lv2plug.in/ns/ext/atom/atom.ttl @@ -262,26 +262,24 @@ atom:Vector  	lv2:documentation """  <p>A homogeneous series of atom bodies with equivalent type and size.</p> -<p>An LV2_Atom_Vector is a 32-bit <code>elem_count</code> and -<code>elem_type</code> followed by <code>elem_count</code> atom bodies of type -<code>elem_type</code>.  The element type must be a fixed size atom:Atom type, -i.e. the size of each element is the vector's <code>size / -elem_count</code>.</p> +<p>An LV2_Atom_Vector is a 32-bit <code>child_size</code> and +<code>child_type</code> followed by <code>size / child_size</code> atom +bodies.</p>  <p>For example, an atom:Vector containing 42 elements of type atom:Float:</p>  <pre class="c-code">  struct VectorOf42Floats { +    uint32_t size;        // sizeof(LV2_Atom_Vector_Body) + (42 * sizeof(float);      uint32_t type;        // map(expand("atom:Vector")) -    uint32_t size;        // sizeof(LV2_Atom_Vector) + (42 * sizeof(float); -    uint32_t elem_count;  // 42 -    uint32_t elem_type;   // map(expand("atom:Float")) +    uint32_t child_size;  // sizeof(float) +    uint32_t child_type;  // map(expand("atom:Float"))      float    elems[42];  };  </pre>  <p>Note that it is possible to construct a valid Atom for each element  of the vector, even by an implementation which does not understand -<code>elem_type</code>.</p> +<code>child_type</code>.</p>  """ .  atom:Tuple @@ -497,6 +495,11 @@ connected to.  It says nothing about the expected contents of containers.  For  that, use atom:supports.</p>  """ . +atom:childType +	a rdf:Property ; +	rdfs:label "Child type" ; +	rdfs:comment "The type of a container's children." . +  atom:supports  	a rdf:Property ;  	rdfs:label "Supports" ; diff --git a/lv2/lv2plug.in/ns/ext/atom/forge.h b/lv2/lv2plug.in/ns/ext/atom/forge.h index b3a5e4d..c1b6d31 100644 --- a/lv2/lv2plug.in/ns/ext/atom/forge.h +++ b/lv2/lv2plug.in/ns/ext/atom/forge.h @@ -65,7 +65,7 @@ typedef LV2_Atom_Forge_Ref (*LV2_Atom_Forge_Sink)(  	LV2_Atom_Forge_Sink_Handle handle, const void* buf, uint32_t size);  /** Function for resolving a reference.  See lv2_atom_forge_set_sink(). */ -typedef void* (*LV2_Atom_Forge_Deref_Func)( +typedef LV2_Atom* (*LV2_Atom_Forge_Deref_Func)(  	LV2_Atom_Forge_Sink_Handle handle, LV2_Atom_Forge_Ref ref);  /** A stack frame used for keeping track of nested Atom containers. */ @@ -261,12 +261,31 @@ lv2_atom_forge_atom(LV2_Atom_Forge* forge, uint32_t size, uint32_t type)  	return lv2_atom_forge_raw(forge, &a, sizeof(a));  } +/** Return true iff the top of the stack has the given type. */ +static inline bool +lv2_atom_forge_top_is(LV2_Atom_Forge* forge, uint32_t type) +{ +	return forge->stack && +		lv2_atom_forge_deref(forge, forge->stack->ref)->type == type; +} + +/** Write a primitive (fixed-size) atom. */ +static inline LV2_Atom_Forge_Ref +lv2_atom_forge_primitive(LV2_Atom_Forge* forge, const LV2_Atom* a) +{ +	if (lv2_atom_forge_top_is(forge, forge->Vector)) { +		return lv2_atom_forge_raw(forge, LV2_ATOM_BODY(a), a->size); +	} else { +		return lv2_atom_forge_write(forge, a, sizeof(LV2_Atom) + a->size); +	} +} +  /** Write an atom:Int32. */  static inline LV2_Atom_Forge_Ref  lv2_atom_forge_int32(LV2_Atom_Forge* forge, int32_t val)  {  	const LV2_Atom_Int32 a = { { sizeof(val), forge->Int32 }, val }; -	return lv2_atom_forge_write(forge, &a, sizeof(a)); +	return lv2_atom_forge_primitive(forge, &a.atom);  }  /** Write an atom:Int64. */ @@ -274,7 +293,7 @@ static inline LV2_Atom_Forge_Ref  lv2_atom_forge_int64(LV2_Atom_Forge* forge, int64_t val)  {  	const LV2_Atom_Int64 a = { { sizeof(val), forge->Int64 }, val }; -	return lv2_atom_forge_write(forge, &a, sizeof(a)); +	return lv2_atom_forge_primitive(forge, &a.atom);  }  /** Write an atom:Float. */ @@ -282,7 +301,7 @@ static inline LV2_Atom_Forge_Ref  lv2_atom_forge_float(LV2_Atom_Forge* forge, float val)  {  	const LV2_Atom_Float a = { { sizeof(val), forge->Float }, val }; -	return lv2_atom_forge_write(forge, &a, sizeof(a)); +	return lv2_atom_forge_primitive(forge, &a.atom);  }  /** Write an atom:Double. */ @@ -290,7 +309,7 @@ static inline LV2_Atom_Forge_Ref  lv2_atom_forge_double(LV2_Atom_Forge* forge, double val)  {  	const LV2_Atom_Double a = { { sizeof(val), forge->Double }, val }; -	return lv2_atom_forge_write(forge, &a, sizeof(a)); +	return lv2_atom_forge_primitive(forge, &a.atom);  }  /** Write an atom:Bool. */ @@ -298,7 +317,7 @@ static inline LV2_Atom_Forge_Ref  lv2_atom_forge_bool(LV2_Atom_Forge* forge, bool val)  {  	const LV2_Atom_Bool a = { { sizeof(val), forge->Bool }, val }; -	return lv2_atom_forge_write(forge, &a, sizeof(a)); +	return lv2_atom_forge_primitive(forge, &a.atom);  }  /** Write an atom:URID. */ @@ -306,7 +325,7 @@ static inline LV2_Atom_Forge_Ref  lv2_atom_forge_urid(LV2_Atom_Forge* forge, LV2_URID id)  {  	const LV2_Atom_URID a = { { sizeof(id), forge->URID }, id }; -	return lv2_atom_forge_write(forge, &a, sizeof(a)); +	return lv2_atom_forge_primitive(forge, &a.atom);  }  /** Write a string body.  Used internally. */ @@ -392,33 +411,36 @@ lv2_atom_forge_literal(LV2_Atom_Forge* forge,  	return out;  } -/** Write an atom:Vector header, but not the vector body. */ +/** Start an atom:Vector. */  static inline LV2_Atom_Forge_Ref -lv2_atom_forge_vector_head(LV2_Atom_Forge* forge, -                           uint32_t        elem_count, -                           uint32_t        elem_type, -                           uint32_t        elem_size) +lv2_atom_forge_vector_head(LV2_Atom_Forge*       forge, +                           LV2_Atom_Forge_Frame* frame, +                           uint32_t              child_size, +                           uint32_t              child_type)  { -	const uint32_t size = sizeof(LV2_Atom_Vector) + (elem_size * elem_count);  	const LV2_Atom_Vector a = { -		{ size - sizeof(LV2_Atom), forge->Vector }, -		{ elem_count, elem_type } +		{ sizeof(LV2_Atom_Vector_Body), forge->Vector }, +		{ child_size, child_type }  	}; -	return lv2_atom_forge_write(forge, &a, sizeof(a)); +	return lv2_atom_forge_push( +		forge, frame, lv2_atom_forge_write(forge, &a, sizeof(a)));  }  /** Write a complete atom:Vector. */  static inline LV2_Atom_Forge_Ref  lv2_atom_forge_vector(LV2_Atom_Forge* forge, -                      uint32_t        elem_count, -                      uint32_t        elem_type, -                      uint32_t        elem_size, +                      uint32_t        child_size, +                      uint32_t        child_type, +                      uint32_t        n_elems,                        const void*     elems)  { -	LV2_Atom_Forge_Ref out = lv2_atom_forge_vector_head( -		forge, elem_count, elem_type, elem_size); +	const LV2_Atom_Vector a = { +		{ sizeof(LV2_Atom_Vector_Body) + n_elems * child_size, forge->Vector }, +		{ child_size, child_type } +	}; +	LV2_Atom_Forge_Ref out = lv2_atom_forge_write(forge, &a, sizeof(a));  	if (out) { -		lv2_atom_forge_write(forge, elems, elem_size * elem_count); +		lv2_atom_forge_write(forge, elems, child_size * n_elems);  	}  	return out;  } @@ -443,9 +465,9 @@ lv2_atom_forge_vector(LV2_Atom_Forge* forge,  static inline LV2_Atom_Forge_Ref  lv2_atom_forge_tuple(LV2_Atom_Forge* forge, LV2_Atom_Forge_Frame* frame)  { -	const LV2_Atom_Tuple a   = { { 0, forge->Tuple } }; -	LV2_Atom_Forge_Ref   out = lv2_atom_forge_write(forge, &a, sizeof(a)); -	return lv2_atom_forge_push(forge, frame, out); +	const LV2_Atom_Tuple a = { { 0, forge->Tuple } }; +	return lv2_atom_forge_push( +		forge, frame, lv2_atom_forge_write(forge, &a, sizeof(a)));  }  /** @@ -462,7 +484,7 @@ lv2_atom_forge_tuple(LV2_Atom_Forge* forge, LV2_Atom_Forge_Frame* frame)     // Write object header     LV2_Atom_Forge_Frame frame; -   LV2_Atom* obj = (LV2_Atom*)lv2_atom_forge_resource(forge, &frame, 1, eg_Cat); +   lv2_atom_forge_resource(forge, &frame, 1, eg_Cat);     // Write property: eg:name = "Hobbes"     lv2_atom_forge_property_head(forge, eg_name, 0); |