From 73137d533a3e853aa13064cb76d040bcab16dceb Mon Sep 17 00:00:00 2001
From: David Robillard
Date: Wed, 23 Nov 2011 07:25:51 +0000
Subject: Merge files extension into state extension.
---
lv2/ns/ext/files/ext.pc.in | 1 -
lv2/ns/ext/files/files.h | 134 ----------------------
lv2/ns/ext/files/files.ttl | 115 -------------------
lv2/ns/ext/files/manifest.ttl | 9 --
lv2/ns/ext/files/waf | 1 -
lv2/ns/ext/files/wscript | 1 -
lv2/ns/ext/state/manifest.ttl | 5 +-
lv2/ns/ext/state/state.h | 96 ++++++++++++++++
lv2/ns/ext/state/state.ttl | 253 ++++++++++++++++++++++++++++++------------
9 files changed, 281 insertions(+), 334 deletions(-)
delete mode 120000 lv2/ns/ext/files/ext.pc.in
delete mode 100644 lv2/ns/ext/files/files.h
delete mode 100644 lv2/ns/ext/files/files.ttl
delete mode 100644 lv2/ns/ext/files/manifest.ttl
delete mode 120000 lv2/ns/ext/files/waf
delete mode 120000 lv2/ns/ext/files/wscript
(limited to 'lv2/ns/ext')
diff --git a/lv2/ns/ext/files/ext.pc.in b/lv2/ns/ext/files/ext.pc.in
deleted file mode 120000
index 82b50df..0000000
--- a/lv2/ns/ext/files/ext.pc.in
+++ /dev/null
@@ -1 +0,0 @@
-../../../../ext.pc.in
\ No newline at end of file
diff --git a/lv2/ns/ext/files/files.h b/lv2/ns/ext/files/files.h
deleted file mode 100644
index 623587a..0000000
--- a/lv2/ns/ext/files/files.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- Copyright 2010-2011 David Robillard
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-/**
- @file files.h
- C API for the LV2 Files extension .
-*/
-
-#ifndef LV2_FILES_H
-#define LV2_FILES_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define LV2_FILES_URI "http://lv2plug.in/ns/ext/files"
-#define LV2_FILES_PATH_SUPPORT_URI LV2_FILES_URI "#pathSupport"
-#define LV2_FILES_NEW_FILE_SUPPORT_URI LV2_FILES_URI "#newFileSupport"
-
-typedef void* LV2_Files_Host_Data;
-
-/**
- files:pathSupport feature struct.
-
- To support this feature, the host MUST pass an LV2_Feature struct with @a
- URI @ref LV2_FILES_PATH_SUPPORT_URI and @a data pointed to an instance of
- this struct.
-*/
-typedef struct {
-
- /**
- Opaque host data.
- */
- LV2_Files_Host_Data host_data;
-
- /**
- Map an absolute path to an abstract path for use in plugin state.
- @param host_data MUST be the @a host_data member of this struct.
- @param absolute_path The absolute path of a file.
- @return An abstract path suitable for use in plugin state.
-
- The plugin MUST use this function to map any paths that will be stored
- in plugin state. The returned value is an abstract path which MAY not
- be an actual file system path; @ref absolute_path MUST be used to map it
- to an actual path in order to use the file.
-
- Hosts MAY map paths in any way (e.g. by creating symbolic links within
- the plugin's state directory or storing a list of referenced files for
- later export). Plugins MUST NOT make any assumptions about abstract
- paths except that they can be mapped to an absolute path using @ref
- absolute_path. Particularly when restoring from state, this absolute
- path MAY not be the same as the original absolute path, but the host
- MUST guarantee it refers to a file with contents equivalent to the
- original.
-
- This function may only be called within the context of
- LV2_Persist.save() or LV2_Persist.restore(). The caller is responsible
- for freeing the returned value.
- */
- char* (*abstract_path)(LV2_Files_Host_Data host_data,
- const char* absolute_path);
-
- /**
- Map an abstract path from plugin state to an absolute path.
- @param host_data MUST be the @a host_data member of this struct.
- @param abstract_path An abstract path (e.g. a path from plugin state).
- @return An absolute file system path.
-
- Since abstract paths are not necessarily actual file paths (or at least
- not necessarily absolute paths), this function MUST be used in order to
- actually open or otherwise use the file referred to by an abstract path.
-
- This function may only be called within the context of
- LV2_Persist.save() or LV2_Persist.restore(). The caller is responsible
- for freeing the returned value.
- */
- char* (*absolute_path)(LV2_Files_Host_Data host_data,
- const char* abstract_path);
-
-} LV2_Files_Path_Support;
-
-/**
- files:newFileSupport feature struct.
-
- To support this feature, the host MUST pass an LV2_Feature struct with @a
- URI @ref LV2_FILES_NEW_FILE_SUPPORT_URI and @a data pointed to an instance
- of this struct.
-*/
-typedef struct {
-
- /**
- Opaque host data.
- */
- LV2_Files_Host_Data host_data;
-
- /**
- Return an absolute path the plugin may use to create a new file.
- @param host_data MUST be the @a host_data member of this struct.
- @param relative_path The relative path of the file.
- @return The absolute path to use for the new file.
-
- The plugin can assume @a relative_path is relative to a namespace
- dedicated to that plugin instance; hosts MUST ensure this, e.g. by
- giving each plugin instance its own state directory. The returned path
- is absolute and thus suitable for creating and using a file, but NOT
- suitable for storing in plugin state (it MUST be mapped to an abstract
- path using @ref LV2_Files_Path_Support::abstract_path to do so).
-
- This function may be called from any non-realtime context. The caller
- is responsible for freeing the returned value.
- */
- char* (*new_file_path)(LV2_Files_Host_Data host_data,
- const char* relative_path);
-
-} LV2_Files_New_File_Support;
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* LV2_FILES_H */
diff --git a/lv2/ns/ext/files/files.ttl b/lv2/ns/ext/files/files.ttl
deleted file mode 100644
index fc32c9a..0000000
--- a/lv2/ns/ext/files/files.ttl
+++ /dev/null
@@ -1,115 +0,0 @@
-# LV2 Files Extension
-# Copyright 2010-2011 David Robillard
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-@prefix atom: .
-@prefix doap: .
-@prefix files: .
-@prefix foaf: .
-@prefix lv2: .
-@prefix rdf: .
-@prefix rdfs: .
-@prefix xsd: .
-
-
- a lv2:Specification ;
- doap:name "LV2 Files" ;
- doap:shortdesc "A standard for referring to files in plugin state." ;
- doap:license ;
- doap:release [
- doap:revision "0.2" ;
- doap:created "2011-04-05"
- ] ;
- doap:maintainer [
- a foaf:Person ;
- foaf:name "David Robillard" ;
- foaf:homepage ;
- rdfs:seeAlso
- ] ;
- lv2:documentation """
-This extension provides a mechanism for plugins to portably refer to files
-in persistent plugin state (using the LV2 State extension), and create
-instance-local files in host-defined locations (e.g. for recording).
-
-The motivating idea behind this extension is that all details of file
-management MUST be handled by the host since different hosts may have very
-different requirements. Plugins MUST NOT make any assumption about file system
-locations beyond what is explicitly guaranteed by this extension.
-
-This extension defines two features: files:newFileSupport allows plugins to
-create new files within an instance-specific namespace at any time (except in
-realtime contexts); while files:pathSupport allows plugins to refer to file
-paths in plugin state in a way transparent to the host.
-
-To create a new file, the plugin MUST request a path from the host using
-LV2_Files_New_File_Support::new_file_path(). Thus, the host may choose an
-appropriate location for the file (e.g. a writable path on the appropriate disk
-volume or a path within a session directory) using information not available to
-the plugin.
-
-To store a path in persistent state, the plugin MUST map it to an
-abstract path
using LV2_Files_Path_Support::abstract_path(). To use a
-path loaded from persistent state, the plugin MUST map the (abstract) path to
-an absolute path using LV2_Files_Path_Support::absolute_path(). Thus, the host
-can manage all paths used in a session and support exporting sessions to a
-portable self-contained format for archival or distribution.
""" .
-
-files:pathSupport a lv2:Feature ;
- rdfs:label "Support for storing file paths in plugin state" ;
- lv2:documentation """
-This feature allows plugins to refer to pre-existing or newly created files
-in persistent plugin state in a portable way. To support this feature a host
-MUST pass a LV2_Files_Path_Support structure to the plugin's
-LV2_Descriptor::instantiate() method as an LV2_Feature with LV2_Feature::URI =
-LV2_FILES_PATH_SUPPORT_URI and LV2_Feature::data pointed to an instance of
-LV2_Files_Path_Support.
-
-Plugins MUST use the functions provided by this feature to handle
-all paths saved to, or restored from, persistent plugin state;
-otherwise broken and/or non-portable state will silently be created resulting
-in a broken user experience.
-""" .
-
-files:newFileSupport a lv2:Feature ;
- rdfs:label "Support for creating new files" ;
- lv2:documentation """
-This feature allows plugins to create new files local to that plugin
-instance. To support this feature a host MUST pass a
-LV2_Files_New_File_Support structure to the plugin's
-LV2_Descriptor::instantiate() method as an LV2_Feature with LV2_Feature::URI =
-LV2_FILES_NEW_FILE_SUPPORT_URI and LV2_Feature::data pointed to an instance of
-LV2_Files_New_File_Support.
-""" .
-
-files:AbstractPath a rdfs:Class ;
- rdfs:label "File Path" ;
- lv2:documentation """
-An abstract path to a file in persistent plugin state.
-
-The format of a files:AbstractPath is a C string escaped or otherwise
-restricted in a system-specific manner. This URI,
-http://lv2plug.in/ns/ext/files#AbstractPath
, mapped to an integer,
-should be used as the type
parameter to a
-LV2_Persist_Store_Function; and will likewise be returned by the corresponding
-call to a LV2_Persist_Retrieve_Function.
-
-Abstract paths reside in a namespace specific to a plugin instance.
-Typical hosts are expected to implement this by giving each plugin instance its
-own state directory.
-
-When storing and retrieving an abstract path, the plugin MUST NOT assume the
-same path will be restored. However, the restored path will refer to a file
-with equivalent contents to the original.
-""" .
diff --git a/lv2/ns/ext/files/manifest.ttl b/lv2/ns/ext/files/manifest.ttl
deleted file mode 100644
index d0233c4..0000000
--- a/lv2/ns/ext/files/manifest.ttl
+++ /dev/null
@@ -1,9 +0,0 @@
-@prefix lv2: .
-@prefix rdfs: .
-
-
- a lv2:Specification ;
- lv2:minorVersion 0 ;
- lv2:microVersion 2 ;
- rdfs:seeAlso .
-
diff --git a/lv2/ns/ext/files/waf b/lv2/ns/ext/files/waf
deleted file mode 120000
index b955110..0000000
--- a/lv2/ns/ext/files/waf
+++ /dev/null
@@ -1 +0,0 @@
-../../../../waf
\ No newline at end of file
diff --git a/lv2/ns/ext/files/wscript b/lv2/ns/ext/files/wscript
deleted file mode 120000
index ec20a77..0000000
--- a/lv2/ns/ext/files/wscript
+++ /dev/null
@@ -1 +0,0 @@
-../../../../ext.wscript
\ No newline at end of file
diff --git a/lv2/ns/ext/state/manifest.ttl b/lv2/ns/ext/state/manifest.ttl
index 7894a22..4c589bd 100644
--- a/lv2/ns/ext/state/manifest.ttl
+++ b/lv2/ns/ext/state/manifest.ttl
@@ -1,9 +1,8 @@
-@prefix lv2: .
+@prefix lv2: .
@prefix rdfs: .
a lv2:Specification ;
lv2:minorVersion 0 ;
- lv2:microVersion 2 ;
+ lv2:microVersion 4 ;
rdfs:seeAlso .
-
diff --git a/lv2/ns/ext/state/state.h b/lv2/ns/ext/state/state.h
index 4e1c28a..3d39012 100644
--- a/lv2/ns/ext/state/state.h
+++ b/lv2/ns/ext/state/state.h
@@ -36,8 +36,13 @@ extern "C" {
#define LV2_STATE_URI "http://lv2plug.in/ns/ext/state"
#define LV2_STATE_INTERFACE_URI LV2_STATE_URI "#Interface"
+#define LV2_STATE_PATH_URI LV2_STATE_URI "#Path"
+#define LV2_STATE_MAP_PATH_URI LV2_STATE_URI "#pathMap"
+#define LV2_STATE_MAKE_PATH_URI LV2_STATE_URI "#newPath"
typedef void* LV2_State_Handle;
+typedef void* LV2_State_Map_Path_Handle;
+typedef void* LV2_State_Make_Path_Handle;
/**
Flags describing value characteristics.
@@ -251,6 +256,97 @@ typedef struct _LV2_State_Interface {
} LV2_State_Interface;
+/**
+ Feature data for state:pathMap (LV2_STATE_MAP_PATH_URI).
+*/
+typedef struct {
+
+ /**
+ Opaque host data.
+ */
+ LV2_State_Map_Path_Handle handle;
+
+ /**
+ Map an absolute path to an abstract path for use in plugin state.
+ @param handle MUST be the @a handle member of this struct.
+ @param absolute_path The absolute path of a file.
+ @return An abstract path suitable for use in plugin state.
+
+ The plugin MUST use this function to map any paths that will be stored
+ in files in plugin state. The returned value is an abstract path which
+ MAY not be an actual file system path; @ref absolute_path MUST be used
+ to map it to an actual path in order to use the file.
+
+ Hosts MAY map paths in any way (e.g. by creating symbolic links within
+ the plugin's state directory or storing a list of referenced files
+ elsewhere). Plugins MUST NOT make any assumptions about abstract paths
+ except that they can be mapped back to an absolute path using @ref
+ absolute_path.
+
+ This function may only be called within the context of
+ LV2_State_Interface.save() or LV2_State_Interface.restore(). The caller
+ is responsible for freeing the returned value.
+ */
+ char* (*abstract_path)(LV2_State_Map_Path_Handle handle,
+ const char* absolute_path);
+
+ /**
+ Map an abstract path from plugin state to an absolute path.
+ @param handle MUST be the @a handle member of this struct.
+ @param abstract_path An abstract path (e.g. a path from plugin state).
+ @return An absolute file system path.
+
+ Since abstract paths are not necessarily actual file paths (or at least
+ not necessarily absolute paths), this function MUST be used in order to
+ actually open or otherwise use the file referred to by an abstract path.
+
+ This function may only be called within the context of
+ LV2_State_Interface.save() or LV2_State_Interface.restore(). The caller
+ is responsible for freeing the returned value.
+ */
+ char* (*absolute_path)(LV2_State_Map_Path_Handle handle,
+ const char* abstract_path);
+
+} LV2_State_Map_Path;
+
+/**
+ Feature data for state:makePath (@ref LV2_STATE_MAKE_PATH_URI).
+*/
+typedef struct {
+
+ /**
+ Opaque host data.
+ */
+ LV2_State_Make_Path_Handle handle;
+
+ /**
+ Return a path the plugin may use to create a new file.
+ @param handle MUST be the @a handle member of this struct.
+ @param path The path of the new file relative to a namespace unique
+ to this plugin instance.
+ @return The absolute path to use for the new file.
+
+ This function can be used by plugins to create files and directories,
+ either at state saving time (if this feature is passed to
+ LV2_State_Interface.save()) or any time (if this feature is passed to
+ LV2_Descriptor.instantiate()).
+
+ The host must do whatever is necessary for the plugin to be able to
+ create a file at the returned path (e.g. using fopen), including
+ creating any leading directories.
+
+ If this function is passed to LV2_Descriptor.instantiate(), it may be
+ called from any non-realtime context. If it is passed to
+ LV2_State_Interface.save(), it may only be called within the dynamic
+ scope of that function call.
+
+ The caller is responsible for freeing the returned value with free().
+ */
+ char* (*path)(LV2_State_Make_Path_Handle handle,
+ const char* path);
+
+} LV2_State_Make_Path;
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/lv2/ns/ext/state/state.ttl b/lv2/ns/ext/state/state.ttl
index 9367a53..b029aa6 100644
--- a/lv2/ns/ext/state/state.ttl
+++ b/lv2/ns/ext/state/state.ttl
@@ -22,58 +22,72 @@
@prefix rdfs: .
- a lv2:Specification ;
- doap:name "LV2 State" ;
- doap:shortdesc "An interface for LV2 plugins to save and restore state." ;
- doap:license ;
- doap:release [
- doap:revision "0.2" ;
- doap:created "2011-11-14"
- ] ;
- doap:developer [
- a foaf:Person ;
- foaf:name "Leonard Ritter" ;
- foaf:homepage ;
- ] ;
- doap:maintainer [
- a foaf:Person ;
- foaf:name "David Robillard" ;
- foaf:homepage ;
- rdfs:seeAlso
- ] ;
- lv2:documentation """
+ a lv2:Specification ;
+ doap:name "LV2 State" ;
+ doap:shortdesc "An interface for LV2 plugins to save and restore state." ;
+ doap:license ;
+ doap:release [
+ doap:revision "0.4" ;
+ doap:created "2011-11-22"
+ ] ;
+ doap:developer [
+ a foaf:Person ;
+ foaf:name "Leonard Ritter" ;
+ foaf:homepage
+ ] ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage ;
+ rdfs:seeAlso
+ ] ;
+ lv2:documentation """
This extension provides a mechanism for plugins to save and restore state
across instances, allowing hosts to save, restore, clone, or take a snapshot of
a plugin instance's state at any point in time. The intention is for a plugin
instance's state to be completely described by port values (as with all
LV2 plugins) and a simple dictionary.
-The state
described by this extension is conceptually a single
-key/value dictionary, where keys are URIDs and values are type-tagged blobs of
-any type. The plugin provides an LV2_State_Interface for working with this
-state. To save or restore, the host calls LV2_State_Interface::save() or
+
The state
described by this extension is conceptually a simple
+key:value dictionary, where keys are URIDs (URIs mapped to integers) and values
+are type-tagged blobs of any type. A single key:value pair is called a
+property
. The plugin provides an LV2_State_Interface for working with
+this state. 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 key/value pair. The host is free to implement saving and restoring in
-any way; the actual mechanism is completely abstract from the plugin's
-perspective.
-
-Because state is a simple dictionary, hosts and plugins can work with it
-easily from many languages and protocols. Keys are URIDs for performance
-reasons as well as RDF compatibility, which makes it simple to serialise state
-in many formats (e.g. any RDF syntax, JSON, XML, key/value databases such as
-BDB, etc.). In particular, state can be elegantly described in a plugin's
-Turtle description, which is useful for e.g. presets or default state.
-Specific keys may be described in Turtle on the fly or in extensions,
-allowing plugins to use common well-defined keys.
-
-This extension defines a conceptual model of state and a mechanism for
-saving and restoring it, but no interface for manipulating it dynamically.
-While no such mechanism is defined here, dynamic control of plugins SHOULD be
-achieved by generic manipulations of the same conceptual state dictionary used
-by this extension (e.g. plugin->set(key, value)
). Accordingly,
-plugins SHOULD use meaningful and well-defined keys wherever possible.
-
-In pseudo code, a typical use case in a plugin is:
+single property. The host is free to implement property storage and retrieval
+in any way.
+
+This state model is simple yet has many benefits:
+
+ - URID keys provide both fast performance and RDF compatibility.
+ - Fully extensible, no limitations on keys or value types.
+ - Easy to serialise in many formats (e.g. any RDF syntax, plain
+ text, JSON, XML, key:value databases, SQL, s-expressions, etc.).
+ - Elegantly described in Turtle, which is useful for describing presets
+ or default state in LV2 data files (the predicate state:instanceState is
+ provided for this purpose).
+ - Does not impose any file formats, data structures, or file system
+ requirements.
+ - Suitable for portable persistent state as well as fast in-memory
+ snapshots.
+ - Easily stored in a typical
map
or dictionary
data
+ structure.
+ - Keys may be defined by extensions, making state meaningful between
+ implementations and enabling dynamic state control.
+
+
+This extension defines a conceptual state model and a mechanism for saving
+and restoring it, but no interface for manipulating it dynamically. However,
+any such mechanism SHOULD work with the same properties used in this extension
+to avoid complicating the concept of plugin state. For example, an extension
+to the example plugin below could be to support a message like
+set(eg:greeting, "Bonjour")
, which could be sent by the host, UIs,
+or other plugins (via the host) to dynamically control the plugin's state.
+Accordingly, plugins SHOULD use meaningful and well-defined keys wherever
+possible.
+
+Plugin Code Example
+
#define NS_EG "http://example.org/"
#define NS_ATOM "http://lv2plug.in/ns/ext/atom#"
@@ -92,7 +106,6 @@ void my_save(LV2_Handle instance,
void* handle,
uint32_t flags,
const LV2_Feature *const * features)
-
{
MyPlugin* plugin = (MyPlugin*)instance;
const char* greeting = plugin->state.greeting;
@@ -109,18 +122,15 @@ void my_restore(LV2_Handle instance,
LV2_State_Retrieve_Function retrieve,
void* handle,
uint32_t flags,
- const LV2_Feature *const * features)
+ const LV2_Feature *const * features)
{
MyPlugin* plugin = (MyPlugin*)instance;
size_t size;
uint32_t type;
uint32_t flags;
- const char* greeting = retrieve(handle,
- plugin->uris.eg_greeting,
- &size,
- &type,
- &flags);
+ const char* greeting = retrieve(
+ handle, plugin->uris.eg_greeting, &size, &type, &flags);
if (greeting) {
free(plugin->state->greeting);
@@ -139,7 +149,8 @@ const void* my_extension_data(const char* uri)
}
-Similarly, a typical use case in a host is:
+Host Code Example
+
int store_callback(void* handle,
uint32_t key,
@@ -171,12 +182,33 @@ Map get_plugin_state(LV2_Handle instance)
return state_map;
}
+
+Referring to Existing Files
+
+This extension deliberately avoids imposing any file formats or file system
+dependencies on implementations. However, some plugins need to refer to
+files in their state. This is done by storing the file's path as a property
+just like any other value.
+
+Plugins MUST use the type state:Path for all paths in their state. This
+allows hosts to know about all such files, which is necessary for making
+session export and archival possible (among other things). Hosts are free to
+map paths in any way, and plugins MUST NOT assume the restored path will be
+identical to the saved path.
+
+Creating New Files or Directories
+
+New implementations and basic plugins are strongly encouraged to simply
+store all state as properties using this API. However, some plugins have an
+existing file or directory formats for state. Plugins MAY create new files
+or directories by using the state:newPath feature, if it is provided by the
+host.
""" .
state:Interface
- a rdfs:Class ;
- rdfs:subClassOf lv2:ExtensionData ;
- lv2:documentation """
+ a rdfs:Class ;
+ rdfs:subClassOf 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
@@ -194,23 +226,23 @@ LV2_STATE_INTERFACE_URI.
""" .
state:InstanceState
- a rdfs:Class ;
- rdfs:label "Plugin Instance State" ;
- rdfs:comment """
-This class is used to express a plugin instance's state in RDF. The key/value
+ a rdfs:Class ;
+ rdfs:label "Plugin Instance State" ;
+ lv2:documentation """
+This class is used to express a plugin instance's state in RDF. The key/value
properties of the instance form the predicate/object (respectively) of triples
with a state:InstanceState as the subject (see state:instanceState for an
example). This may be used wherever it is useful to express a plugin instance's
state in RDF (e.g. for serialisation, storing in a model, or transmitting over
a network). Note that this class is provided because it may be useful for
hosts, plugins, or extensions that work with instance state, but its use is not
-required to support the LV2 State extension.
+required to support the LV2 State extension.
""" .
state:instanceState
- a rdf:Property ;
- rdfs:range state:InstanceState ;
- lv2:documentation """
+ a rdf:Property ;
+ rdfs:range state:InstanceState ;
+ lv2:documentation """
Predicate to relate a plugin instance to an InstanceState. This may be used
wherever the state of a particular plugin instance needs to be represented.
Note that the domain of this property is unspecified, since LV2 does not define
@@ -219,13 +251,94 @@ sense to do so, e.g.:
@prefix eg: <http://example.org/> .
-<plugininstance> state:instanceState [
- eg:somekey "some value" ;
- eg:someotherkey "some other value" ;
- eg:favourite-number 2
-] .
+<plugininstance>
+ state:instanceState [
+ eg:somekey "some value" ;
+ eg:someotherkey "some other value" ;
+ eg:favourite-number 2
+ ] .
Note that this property is provided because it may be useful for hosts,
plugins, or extensions that work with instance state, but its use is not
-required to support the LV2 State extension.
+required to support this extension.
+""" .
+
+state:mapPath
+ a lv2:Feature ;
+ rdfs:label "Support for storing paths in files" ;
+ lv2:documentation """
+This feature allows plugins to store paths inside files stored in its state
+(if, for example, a plugin saves to an existing file format which contains
+paths). To support this feature a host must pass an LV2_Feature with URI
+LV2_STATE_MAP_PATH_URI and data pointed to an LV2_State_Map_Path to the
+plugin's LV2_State_Interface methods.
+
+The plugin MUST use the provided functions to map all paths stored
+in any files it creates (using state:makePath) and stores in the state. This
+is necessary to enable host to handle file system references correctly, e.g.
+for session export or archival.
+
+For example, a plugin may write a path to a state file like so:
+
+
+void write_path(LV2_State_Map_Path* map_path, FILE* myfile, const char* path)
+{
+ char* abstract_path = map_path->abstract_path(map_path->handle, path);
+ fprintf(myfile, "%s", abstract_path);
+ free(abstract_path);
+}
+
+
+Then, later reload the path like so:
+
+
+char* read_path(LV2_State_Map_Path* map_path, FILE* myfile)
+{
+ /* Obviously this is not production quality code! */
+ char abstract_path[1024];
+ fscanf(myfile, "%s", abstract_path);
+ return map_path->absolute_path(map_path->handle, abstract_path);
+}
+
+""" .
+
+state:makePath
+ a lv2:Feature ;
+ rdfs:label "Support for creating new files and directories" ;
+ lv2:documentation """
+
+This feature allows plugins to create new files or directories. To support
+this feature the host passes an LV2_Feature with URI LV2_STATE_MAKE_PATH_URI
+and data pointed to an LV2_State_Make_Path to the plugin. The host may provide
+this feature during state saving only or at any time, by passing the feature to
+LV2_State_Interface::save() or LV2_Descriptor::instantiate(), respectively.
+
+For example, a plugin may create a file in a subdirectory like so:
+
+
+void 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");
+ fclose(myfile);
+}
+
+""" .
+
+state:Path
+ a rdfs:Class ;
+ rdfs:label "Path" ;
+ lv2:documentation """
+A path to a file or directory.
+
+The format of a state:Path is a C string escaped or otherwise restricted in
+a system-specific manner. This URI (LV2_STATE_PATH_URI), mapped to an integer,
+MUST be used as the type
parameter for any files passed to the
+LV2_State_Store_Function; and will likewise be returned by the corresponding
+call to the LV2_State_Retrieve_Function.
+
+When storing and retrieving a path, the plugin MUST NOT assume the same path
+will be restored. However, the restored path will refer to a file with
+equivalent contents to the original.
""" .
--
cgit v1.2.1