From 17c6df0bc3043c57d2c02c58284ec4794f656b3c Mon Sep 17 00:00:00 2001
From: David Robillard property
.
To implement state, the plugin provides a state:Interface to the host. To +
To implement state, the plugin provides a state:interface to the host. To save or restore, the host calls LV2_State_Interface::save() or LV2_State_Interface::restore(), passing a callback to be used for handling a single property. The host is free to implement property storage and retrieval @@ -85,15 +85,15 @@ is simply a C string.
Plugins may need to refer to existing files (e.g. loaded samples) in their state. This is done by storing the file's path as a property just like any other value. However, there are some rules which MUST be followed when storing -paths, see state:mapPath for details. Plugins MUST use -the type atom:Path for all -paths in their state.
+paths, see state:mapPath for details. Plugins MUST use the type atom:Path for all paths in their +state.Plugins are strongly encouraged to avoid creating files, instead storing all state as properties. However, occasionally the ability to create files is -necessary. To make this possible, the host can provide the feature state:makePath which allocates paths for plugin-created -files. Plugins MUST NOT create files in any other locations.
+necessary. To make this possible, the host can provide the feature +state:makePath which allocates paths for plugin-created files. Plugins MUST +NOT create files in any other locations.
-int store_callback(LV2_State_Handle handle,
- uint32_t key,
- const void* value,
- size_t size,
- uint32_t type,
- uint32_t flags)
+LV2_State_Status
+store_callback(LV2_State_Handle handle,
+ uint32_t key,
+ const void* value,
+ size_t size,
+ uint32_t type,
+ uint32_t flags)
{
if ((flags & LV2_STATE_IS_POD)) {
/* We only care about POD since we're keeping state in memory only.
@@ -183,9 +194,10 @@ int store_callback(LV2_State_Handle handle,
}
}
-Map get_plugin_state(LV2_Handle instance)
+Map
+get_plugin_state(LV2_Handle instance)
{
- LV2_State* state = instance.extension_data(LV2_STATE__Interface);
+ LV2_State* state = instance.extension_data(LV2_STATE__interface);
Map state_map;
/** Request a fast/native/POD save, since we're just copying in memory */
state.save(instance, store_callback, &state_map,
@@ -209,26 +221,36 @@ instance, at least well enough that saving and restoring will yield an
plugin instance.
-The recommended way to add new functionality that may affect state is to
-simply define it in terms of properties. For example, instead of defining a
-new set of commands, define properties whose values can be set appropriately.
-This provides persistence for free
, since rather than having to define a
-set of commands and a set of properties for storing their effects,
-only the properties need to be defined.
-
-This property principle
is summed up in the phrase: Don't
-stop; set playing to false
.
+The Property Principle
+
+The main benefit of this meaningful state model is that it can double as a
+plugin control/query mechanism. For plugins that require more advanced control
+than simple control ports, instead of defining a set of commands, define
+properties whose values can be set appropriately. This provides both a way to
+control and save that state for free
, since there is no need to define
+commands and a set of properties for storing their effects. In
+particular, this is a good way for UIs to achieve more advanced control of
+plugins.
+
+This property principle
is summed up in the phrase:
+Don't stop; set playing to false
.
+
+This extension does not define a dynamic mechanism for state access and
+manipulation. The LV2 Patch
+extension defines a generic set of messages which can be used to access or
+manipulate properties, and the LV2
+Atom extension defines a port type and data container capable of
+transmitting those messages.
""" .
-state:Interface
- a rdfs:Class ;
- rdfs:subClassOf lv2:ExtensionData ;
+state:interface
+ a lv2:ExtensionData ;
lv2:documentation """
A structure (LV2_State_Interface) which contains functions to be called by
the host to save and restore state. In order to support this extension, the
plugin must return a valid LV2_State_Interface from
LV2_Descriptor::extension_data() when it is called with URI
-LV2_STATE__Interface.
+LV2_STATE__interface.
The plugin data file should describe this like so:
@@ -236,7 +258,7 @@ LV2_STATE__Interface.
<plugin>
a lv2:Plugin ;
- lv2:extensionData state:Interface .
+ lv2:extensionData state:interface .
""" .
@@ -245,9 +267,9 @@ state:State
rdfs:label "Plugin Instance State" ;
lv2:documentation """
A state dictionary. This type should be used wherever instance state is
-described in RDF, or any other context that uses type URIs. The properties of
-a resource with this type correspond directly to the properties of the state
-dictionary (except the property that states it has this type).
+described. The properties of a resource with this type correspond directly to
+the properties of the state dictionary (except the property that states it has
+this type).
""" .
state:state
@@ -255,13 +277,13 @@ state:state
rdfs:label "State" ;
rdfs:range state:State ;
lv2:documentation """
-The state of this plugin instance, or similar resource. This property may
-be used anywhere a state needs to be described, for example:
+The state of this instance. This property may be used anywhere a state
+needs to be described, for example:
@prefix eg: <http://example.org/> .
-<plugininstance>
+<plugin-instance>
state:state [
eg:somekey "some value" ;
eg:someotherkey "some other value" ;
@@ -313,24 +335,23 @@ state:makePath
lv2:documentation """
This feature allows plugins to create new files and/or directories. To
support this feature the host passes an LV2_Feature with URI
-LV2_STATE__makePath and data pointed to an LV2_State_Make_Path to the
-plugin. The host may make this feature available only during save by passing
-it to LV2_State_Interface::save(), or available any time by passing it to
+LV2_STATE__makePath and data pointed to an LV2_State_Make_Path to the plugin.
+The host may make this feature available only during save by passing it to
+LV2_State_Interface::save(), or available any time by passing it to
LV2_Descriptor::instantiate(). If passed to LV2_State_Interface::save(), the
feature MUST NOT be used beyond the scope of that call.
-The plugin is guaranteed a hierarchial namespace unique to that plugin
+
The plugin is guaranteed a hierarchical namespace unique to that plugin
instance, and may expect the returned path to have the requested path as a
suffix. There is one such namespace, even if the feature is passed to
-both LV2_Descriptor::instantiate() and
-LV2_State_Interface::save(). Beyond this, the plugin MUST NOT make any
-assumptions about the returned paths.
+both LV2_Descriptor::instantiate() and LV2_State_Interface::save().
+Beyond this, the plugin MUST NOT make any assumptions about the returned
+paths.
-Like any other paths, the plugin MUST map these paths using state:mapPath before storing them in state. The plugin
-MUST NOT assume these paths will be available across a save/restore otherwise,
-i.e. only mapped paths saved to state are persistent, any other created paths
-are temporary.
+Like any other paths, the plugin MUST map these paths using state:mapPath
+before storing them in state. The plugin MUST NOT assume these paths will be
+available across a save/restore otherwise, i.e. only mapped paths saved to
+state are persistent, any other created paths are temporary.
For example, a plugin may create a file in a subdirectory like so:
@@ -339,7 +360,7 @@ char* save_myfile(LV2_State_Make_Path* make_path)
{
char* path = make_path->path(make_path->handle, "foo/bar/myfile.txt");
FILE* myfile = fopen(path, 'w');
- fprintf(myfile, "Hello");
+ fprintf(myfile, "I am some data");
fclose(myfile);
return path;
}
diff --git a/lv2/lv2plug.in/ns/ext/worker/worker.h b/lv2/lv2plug.in/ns/ext/worker/worker.h
index b0d87ec..74ac45b 100644
--- a/lv2/lv2plug.in/ns/ext/worker/worker.h
+++ b/lv2/lv2plug.in/ns/ext/worker/worker.h
@@ -29,7 +29,7 @@
#define LV2_WORKER_URI "http://lv2plug.in/ns/ext/worker"
#define LV2_WORKER_PREFIX LV2_WORKER_URI "#"
-#define LV2_WORKER__Interface LV2_WORKER_PREFIX "Interface"
+#define LV2_WORKER__interface LV2_WORKER_PREFIX "interface"
#define LV2_WORKER__schedule LV2_WORKER_PREFIX "schedule"
/**
@@ -60,7 +60,7 @@ typedef LV2_Worker_Status (*LV2_Worker_Respond_Function)(
This is the interface provided by the plugin to implement a worker method.
The plugin's extension_data() method should return an LV2_Worker_Interface
- when called with LV2_WORKER__Interface as its argument.
+ when called with LV2_WORKER__interface as its argument.
*/
typedef struct _LV2_Worker_Interface {
/**
diff --git a/lv2/lv2plug.in/ns/ext/worker/worker.ttl b/lv2/lv2plug.in/ns/ext/worker/worker.ttl
index 517aabb..09f7249 100644
--- a/lv2/lv2plug.in/ns/ext/worker/worker.ttl
+++ b/lv2/lv2plug.in/ns/ext/worker/worker.ttl
@@ -49,14 +49,13 @@ offline rendering, or in real-time with non-real-time work taking place in a
separate thread.
""" .
-work:Interface
- a rdfs:Class ;
- rdfs:subClassOf lv2:ExtensionData ;
+work:interface
+ a lv2:ExtensionData ;
lv2:documentation """
The interface provided by the plugin to implement a worker. To implement
this extension, the plugin must return a valid LV2_Worker_Interface from
LV2_Descriptor::extension_data() when it is called with URI
-LV2_WORKER__Interface.
+LV2_WORKER__interface.
The plugin data file should describe this like so:
@@ -64,7 +63,7 @@ LV2_WORKER__Interface.
<plugin>
a lv2:Plugin ;
- lv2:extensionData work:Interface .
+ lv2:extensionData work:interface .
""" .
--
cgit v1.2.1