1 |
/* |
/* |
2 |
Copyright 2010-2011 David Robillard <http://drobilla.net> |
Copyright 2010-2012 David Robillard <http://drobilla.net> |
3 |
Copyright 2010 Leonard Ritter <paniq@paniq.org> |
Copyright 2010 Leonard Ritter <paniq@paniq.org> |
4 |
|
|
5 |
Permission to use, copy, modify, and/or distribute this software for any |
Permission to use, copy, modify, and/or distribute this software for any |
16 |
*/ |
*/ |
17 |
|
|
18 |
/** |
/** |
19 |
@file |
@file state.h |
20 |
C API for the LV2 State extension <http://lv2plug.in/ns/ext/state>. |
C API for the LV2 State extension <http://lv2plug.in/ns/ext/state>. |
21 |
*/ |
*/ |
22 |
|
|
23 |
#ifndef LV2_STATE_H |
#ifndef LV2_STATE_H |
24 |
#define LV2_STATE_H |
#define LV2_STATE_H |
25 |
|
|
|
#include <stdbool.h> |
|
26 |
#include <stddef.h> |
#include <stddef.h> |
27 |
#include <stdint.h> |
#include <stdint.h> |
28 |
|
|
29 |
#include <lv2.h> |
#include "lv2/lv2plug.in/ns/lv2core/lv2.h" |
30 |
|
|
31 |
|
#define LV2_STATE_URI "http://lv2plug.in/ns/ext/state" |
32 |
|
#define LV2_STATE_PREFIX LV2_STATE_URI "#" |
33 |
|
|
34 |
|
#define LV2_STATE__State LV2_STATE_PREFIX "State" |
35 |
|
#define LV2_STATE__interface LV2_STATE_PREFIX "interface" |
36 |
|
#define LV2_STATE__makePath LV2_STATE_PREFIX "makePath" |
37 |
|
#define LV2_STATE__mapPath LV2_STATE_PREFIX "mapPath" |
38 |
|
#define LV2_STATE__state LV2_STATE_PREFIX "state" |
39 |
|
|
40 |
#ifdef __cplusplus |
#ifdef __cplusplus |
41 |
extern "C" { |
extern "C" { |
42 |
|
#else |
43 |
|
# include <stdbool.h> |
44 |
#endif |
#endif |
45 |
|
|
|
#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 "#mapPath" |
|
|
#define LV2_STATE_MAKE_PATH_URI LV2_STATE_URI "#makePath" |
|
|
|
|
46 |
typedef void* LV2_State_Handle; |
typedef void* LV2_State_Handle; |
47 |
typedef void* LV2_State_Map_Path_Handle; |
typedef void* LV2_State_Map_Path_Handle; |
48 |
typedef void* LV2_State_Make_Path_Handle; |
typedef void* LV2_State_Make_Path_Handle; |
58 |
/** |
/** |
59 |
Plain Old Data. |
Plain Old Data. |
60 |
|
|
61 |
Values with this flag contain no references to non-persistent or |
Values with this flag contain no pointers or references to other areas |
62 |
non-global resources (e.g. pointers, handles, local paths, etc.). It is |
of memory. It is safe to copy POD values with a simple memcpy and store |
63 |
safe to copy POD values with a simple memcpy and store them for use at |
them for the duration of the process. A POD value is not necessarily |
64 |
any time in the future on a machine with a compatible architecture |
safe to trasmit between processes or machines (e.g. filenames are POD), |
65 |
(e.g. the same endianness and alignment). |
see LV2_STATE_IS_PORTABLE for details. |
66 |
|
|
67 |
Implementations MUST NOT attempt to copy or serialise a non-POD value if |
Implementations MUST NOT attempt to copy or serialise a non-POD value if |
68 |
they do not understand its type (and thus know how to correctly do so). |
they do not understand its type (and thus know how to correctly do so). |
73 |
Portable (architecture independent) data. |
Portable (architecture independent) data. |
74 |
|
|
75 |
Values with this flag are in a format that is usable on any |
Values with this flag are in a format that is usable on any |
76 |
architecture, i.e. if the value is saved on one machine it can safely be |
architecture. A portable value saved on one machine can be restored on |
77 |
restored on another machine regardless of endianness, alignment, etc. |
another machine regardless of architecture. The format of portable |
78 |
|
values MUST NOT depend on architecture-specific properties like |
79 |
|
endianness or alignment. Portable values MUST NOT contain filenames. |
80 |
*/ |
*/ |
81 |
LV2_STATE_IS_PORTABLE = 1 << 1, |
LV2_STATE_IS_PORTABLE = 1 << 1, |
82 |
|
|
93 |
|
|
94 |
} LV2_State_Flags; |
} LV2_State_Flags; |
95 |
|
|
96 |
|
/** A status code for state functions. */ |
97 |
|
typedef enum { |
98 |
|
LV2_STATE_SUCCESS = 0, /**< Completed successfully. */ |
99 |
|
LV2_STATE_ERR_UNKNOWN = 1, /**< Unknown error. */ |
100 |
|
LV2_STATE_ERR_BAD_TYPE = 2, /**< Failed due to unsupported type. */ |
101 |
|
LV2_STATE_ERR_BAD_FLAGS = 3, /**< Failed due to unsupported flags. */ |
102 |
|
LV2_STATE_ERR_NO_FEATURE = 4, /**< Failed due to missing features. */ |
103 |
|
LV2_STATE_ERR_NO_PROPERTY = 5 /**< Failed due to missing property. */ |
104 |
|
} LV2_State_Status; |
105 |
|
|
106 |
/** |
/** |
107 |
A host-provided function to store a property. |
A host-provided function to store a property. |
108 |
@param handle Must be the handle passed to LV2_State_Interface.save(). |
@param handle Must be the handle passed to LV2_State_Interface.save(). |
109 |
@param key The key (predicate) to store @c value under (URI mapped integer). |
@param key The key to store @p value under (URID). |
110 |
@param value Pointer to the value (object) to be stored. |
@param value Pointer to the value to be stored. |
111 |
@param size The size of the data at @c value in bytes. |
@param size The size of @p value in bytes. |
112 |
@param type The type of @c value (URI). |
@param type The type of @p value (URID). |
113 |
@param flags LV2_State_Flags for @c value. |
@param flags LV2_State_Flags for @p value. |
114 |
@return 0 on success, otherwise a non-zero error code. |
@return 0 on success, otherwise a non-zero error code. |
115 |
|
|
116 |
The host passes a callback of this type to LV2_State_Interface.save(). This callback |
The host passes a callback of this type to LV2_State_Interface.save(). This |
117 |
is called repeatedly by the plugin within LV2_State_Interface.save() to store all |
callback is called repeatedly by the plugin to store all the properties that |
118 |
the statements that describe its current state. |
describe its current state. |
119 |
|
|
120 |
The host MAY fail to store a property if the type is not understood and is |
DO NOT INVENT NONSENSE URI SCHEMES FOR THE KEY. Best is to use keys from |
121 |
not LV2_STATE_IS_POD and/or LV2_STATE_IS_PORTABLE. Implementations are |
existing vocabularies. If nothing appropriate is available, use http URIs |
122 |
encouraged to use POD and portable values (e.g. string literals) wherever |
that point to somewhere you can host documents so documentation can be made |
123 |
possible, and use common types (e.g. types from |
resolvable (e.g. a child of the plugin or project URI). If this is not |
124 |
http://lv2plug.in/ns/ext/atom) regardless, since hosts are likely to already |
possible, invent a URN scheme, e.g. urn:myproj:whatever. The plugin MUST |
125 |
contain the necessary implementation. |
NOT pass an invalid URI key. |
126 |
|
|
127 |
|
The host MAY fail to store a property for whatever reason, but SHOULD |
128 |
|
store any property that is LV2_STATE_IS_POD and LV2_STATE_IS_PORTABLE. |
129 |
|
Implementations SHOULD use the types from the LV2 Atom extension |
130 |
|
(http://lv2plug.in/ns/ext/atom) wherever possible. The plugin SHOULD |
131 |
|
attempt to fall-back and avoid the error if possible. |
132 |
|
|
133 |
Note that @c size MUST be > 0, and @c value MUST point to a valid region of |
Note that @p size MUST be > 0, and @p value MUST point to a valid region of |
134 |
memory @c size bytes long (this is required to make restore unambiguous). |
memory @p size bytes long (this is required to make restore unambiguous). |
135 |
|
|
136 |
The plugin MUST NOT attempt to use this function outside of the |
The plugin MUST NOT attempt to use this function outside of the |
137 |
LV2_State_Interface.restore() context. |
LV2_State_Interface.restore() context. |
138 |
*/ |
*/ |
139 |
typedef int (*LV2_State_Store_Function)(LV2_State_Handle handle, |
typedef LV2_State_Status (*LV2_State_Store_Function)( |
140 |
uint32_t key, |
LV2_State_Handle handle, |
141 |
const void* value, |
uint32_t key, |
142 |
size_t size, |
const void* value, |
143 |
uint32_t type, |
size_t size, |
144 |
uint32_t flags); |
uint32_t type, |
145 |
|
uint32_t flags); |
146 |
|
|
147 |
/** |
/** |
148 |
A host-provided function to retrieve a property. |
A host-provided function to retrieve a property. |
149 |
@param handle Must be the handle passed to |
@param handle Must be the handle passed to LV2_State_Interface.restore(). |
150 |
LV2_State_Interface.restore(). |
@param key The key of the property to retrieve (URID). |
|
@param key The key (predicate) of the property to retrieve (URI). |
|
151 |
@param size (Output) If non-NULL, set to the size of the restored value. |
@param size (Output) If non-NULL, set to the size of the restored value. |
152 |
@param type (Output) If non-NULL, set to the type of the restored value. |
@param type (Output) If non-NULL, set to the type of the restored value. |
153 |
@param flags (Output) If non-NULL, set to the LV2_State_Flags for |
@param flags (Output) If non-NULL, set to the flags for the restored value. |
|
the returned value. |
|
154 |
@return A pointer to the restored value (object), or NULL if no value |
@return A pointer to the restored value (object), or NULL if no value |
155 |
has been stored under @c key. |
has been stored under @p key. |
156 |
|
|
157 |
A callback of this type is passed by the host to |
A callback of this type is passed by the host to |
158 |
LV2_State_Interface.restore(). This callback is called repeatedly by the |
LV2_State_Interface.restore(). This callback is called repeatedly by the |
159 |
plugin within LV2_State_Interface.restore() to retrieve any properties it |
plugin to retrieve any properties it requires to restore its state. |
|
requires to restore its state. |
|
160 |
|
|
161 |
The returned value MUST remain valid until LV2_State_Interface.restore() |
The returned value MUST remain valid until LV2_State_Interface.restore() |
162 |
returns. |
returns. The plugin MUST NOT attempt to use this function, or any value |
163 |
|
returned from it, outside of the LV2_State_Interface.restore() context. |
|
The plugin MUST NOT attempt to use this function, or any value returned from |
|
|
it, outside of the LV2_State_Interface.restore() context. Returned values |
|
|
MAY be copied for later use if necessary, assuming the plugin knows how to |
|
|
do so correctly (e.g. the value is POD, or the plugin understands the type). |
|
164 |
*/ |
*/ |
165 |
typedef const void* (*LV2_State_Retrieve_Function)(LV2_State_Handle handle, |
typedef const void* (*LV2_State_Retrieve_Function)( |
166 |
uint32_t key, |
LV2_State_Handle handle, |
167 |
size_t* size, |
uint32_t key, |
168 |
uint32_t* type, |
size_t* size, |
169 |
uint32_t* flags); |
uint32_t* type, |
170 |
|
uint32_t* flags); |
171 |
|
|
172 |
/** |
/** |
173 |
State Extension Data. |
LV2 Plugin State Interface. |
174 |
|
|
175 |
When the plugin's extension_data is called with argument LV2_STATE_URI, |
When the plugin's extension_data is called with argument |
176 |
the plugin MUST return an LV2_State structure, which remains valid for the |
LV2_STATE__interface, the plugin MUST return an LV2_State_Interface |
177 |
lifetime of the plugin. |
structure, which remains valid for the lifetime of the plugin. |
178 |
|
|
179 |
The host can use the contained function pointers to save and restore the |
The host can use the contained function pointers to save and restore the |
180 |
state of a plugin instance at any time (provided the threading restrictions |
state of a plugin instance at any time, provided the threading restrictions |
181 |
for the given function are met). |
of the functions are met. |
|
|
|
|
The typical use case is to save the plugin's state when a project is saved, |
|
|
and to restore the state when a project has been loaded. Other uses are |
|
|
possible (e.g. cloning plugin instances or taking a snapshot of plugin |
|
|
state). |
|
182 |
|
|
183 |
Stored data is only guaranteed to be compatible between instances of plugins |
Stored data is only guaranteed to be compatible between instances of plugins |
184 |
with the same URI (i.e. if a change to a plugin would cause a fatal error |
with the same URI (i.e. if a change to a plugin would cause a fatal error |
185 |
when restoring state saved by a previous version of that plugin, the plugin |
when restoring state saved by a previous version of that plugin, the plugin |
186 |
URI MUST change just as it must when ports change incompatibly). Plugin |
URI MUST change just as it must when ports change incompatibly). Plugin |
187 |
authors should consider this possibility, and always store sensible data |
authors should consider this possibility, and always store sensible data |
188 |
with meaningful types to avoid such compatibility issues in the future. |
with meaningful types to avoid such problems in the future. |
189 |
*/ |
*/ |
190 |
typedef struct _LV2_State_Interface { |
typedef struct _LV2_State_Interface { |
191 |
|
|
192 |
/** |
/** |
193 |
Save plugin state using a host-provided @c store callback. |
Save plugin state using a host-provided @p store callback. |
194 |
|
|
195 |
@param instance The instance handle of the plugin. |
@param instance The instance handle of the plugin. |
196 |
@param store The host-provided store callback. |
@param store The host-provided store callback. |
197 |
@param handle An opaque pointer to host data, e.g. the map or |
@param handle An opaque pointer to host data which MUST be passed as the |
198 |
file where the values are to be stored. If @c store is called, this MUST |
handle parameter to @p store if it is called. |
199 |
be passed as its handle parameter. |
@param flags Flags describing desired properties of this save. These |
200 |
@param flags Flags describing desires properties of this save. The |
flags may be used to determine the most appropriate values to store. |
|
plugin SHOULD use these values to determine the most appropriate and/or |
|
|
efficient serialisation, but is not required to do so. |
|
201 |
@param features Extensible parameter for passing any additional |
@param features Extensible parameter for passing any additional |
202 |
features to be used for this save. |
features to be used for this save. |
203 |
|
|
204 |
The plugin is expected to store everything necessary to completely |
The plugin is expected to store everything necessary to completely |
205 |
restore its state later (possibly much later, in a different process, on |
restore its state later. Plugins SHOULD store simple POD data whenever |
206 |
a completely different machine, etc.) |
possible, and consider the possibility of state being restored much |
207 |
|
later on a different machine. |
208 |
|
|
209 |
The @c handle pointer and @c store function MUST NOT be used |
The @p handle pointer and @p store function MUST NOT be used |
210 |
beyond the scope of save(). |
beyond the scope of save(). |
211 |
|
|
212 |
This function has its own special threading class: it may not be called |
This function has its own special threading class: it may not be called |
214 |
concurrently with functions in any other class, unless the definition of |
concurrently with functions in any other class, unless the definition of |
215 |
that class prohibits it (e.g. it may not be called concurrently with a |
that class prohibits it (e.g. it may not be called concurrently with a |
216 |
"Discovery" function, but it may be called concurrently with an "Audio" |
"Discovery" function, but it may be called concurrently with an "Audio" |
217 |
function. The plugin is responsible for any locking or lock-free |
function. The plugin is responsible for any locking or lock-free |
218 |
techniques necessary to make this possible. |
techniques necessary to make this possible. |
219 |
|
|
220 |
Note that in the simple case where state is only modified by restore(), |
Note that in the simple case where state is only modified by restore(), |
225 |
care to do so in such a way that a concurrent call to save() will save a |
care to do so in such a way that a concurrent call to save() will save a |
226 |
consistent representation of plugin state for a single instant in time. |
consistent representation of plugin state for a single instant in time. |
227 |
*/ |
*/ |
228 |
void (*save)(LV2_Handle instance, |
LV2_State_Status (*save)(LV2_Handle instance, |
229 |
LV2_State_Store_Function store, |
LV2_State_Store_Function store, |
230 |
LV2_State_Handle handle, |
LV2_State_Handle handle, |
231 |
uint32_t flags, |
uint32_t flags, |
232 |
const LV2_Feature *const * features); |
const LV2_Feature *const * features); |
233 |
|
|
234 |
/** |
/** |
235 |
Restore plugin state using a host-provided @c retrieve callback. |
Restore plugin state using a host-provided @p retrieve callback. |
236 |
|
|
237 |
@param instance The instance handle of the plugin. |
@param instance The instance handle of the plugin. |
238 |
@param retrieve The host-provided retrieve callback. |
@param retrieve The host-provided retrieve callback. |
239 |
@param handle An opaque pointer to host data, e.g. the map or |
@param handle An opaque pointer to host data which MUST be passed as the |
240 |
file from which the values are to be restored. If @c retrieve is |
handle parameter to @p retrieve if it is called. |
|
called, this MUST be passed as its handle parameter. |
|
241 |
@param flags Currently unused. |
@param flags Currently unused. |
242 |
@param features Extensible parameter for passing any additional |
@param features Extensible parameter for passing any additional |
243 |
features to be used for this restore. |
features to be used for this restore. |
246 |
LV2_State_Interface.save() by a plugin with the same URI. |
LV2_State_Interface.save() by a plugin with the same URI. |
247 |
|
|
248 |
The plugin MUST gracefully fall back to a default value when a value can |
The plugin MUST gracefully fall back to a default value when a value can |
249 |
not be retrieved. This allows the host to reset the plugin state with an |
not be retrieved. This allows the host to reset the plugin state with |
250 |
empty map. |
an empty map. |
251 |
|
|
252 |
The @c handle pointer and @c store function MUST NOT be used |
The @p handle pointer and @p store function MUST NOT be used |
253 |
beyond the scope of restore(). |
beyond the scope of restore(). |
254 |
|
|
255 |
This function is in the "Instantiation" threading class as defined by |
This function is in the "Instantiation" threading class as defined by |
256 |
LV2. This means it MUST NOT be called concurrently with any other |
LV2. This means it MUST NOT be called concurrently with any other |
257 |
function on the same plugin instance. |
function on the same plugin instance. |
258 |
*/ |
*/ |
259 |
void (*restore)(LV2_Handle instance, |
LV2_State_Status (*restore)(LV2_Handle instance, |
260 |
LV2_State_Retrieve_Function retrieve, |
LV2_State_Retrieve_Function retrieve, |
261 |
LV2_State_Handle handle, |
LV2_State_Handle handle, |
262 |
uint32_t flags, |
uint32_t flags, |
263 |
const LV2_Feature *const * features); |
const LV2_Feature *const * features); |
264 |
|
|
265 |
} LV2_State_Interface; |
} LV2_State_Interface; |
266 |
|
|
267 |
/** |
/** |
268 |
Feature data for state:mapPath (LV2_STATE_MAP_PATH_URI). |
Feature data for state:mapPath (LV2_STATE__mapPath). |
269 |
*/ |
*/ |
270 |
typedef struct { |
typedef struct { |
271 |
|
|
276 |
|
|
277 |
/** |
/** |
278 |
Map an absolute path to an abstract path for use in plugin state. |
Map an absolute path to an abstract path for use in plugin state. |
279 |
@param handle MUST be the @a handle member of this struct. |
@param handle MUST be the @p handle member of this struct. |
280 |
@param absolute_path The absolute path of a file. |
@param absolute_path The absolute path of a file. |
281 |
@return An abstract path suitable for use in plugin state. |
@return An abstract path suitable for use in plugin state. |
282 |
|
|
283 |
The plugin MUST use this function to map any paths that will be stored |
The plugin MUST use this function to map any paths that will be stored |
284 |
in files in plugin state. The returned value is an abstract path which |
in plugin state. The returned value is an abstract path which MAY not |
285 |
MAY not be an actual file system path; @ref absolute_path MUST be used |
be an actual file system path; @ref absolute_path() MUST be used to map |
286 |
to map it to an actual path in order to use the file. |
it to an actual path in order to use the file. |
287 |
|
|
288 |
Hosts MAY map paths in any way (e.g. by creating symbolic links within |
Plugins MUST NOT make any assumptions about abstract paths except that |
289 |
the plugin's state directory or storing a list of referenced files |
they can be mapped back to the absolute path of the "same" file (though |
290 |
elsewhere). Plugins MUST NOT make any assumptions about abstract paths |
not necessarily the same original path) using @ref absolute_path(). |
|
except that they can be mapped back to an absolute path using @ref |
|
|
absolute_path. |
|
291 |
|
|
292 |
This function may only be called within the context of |
This function may only be called within the context of |
293 |
LV2_State_Interface.save() or LV2_State_Interface.restore(). The caller |
LV2_State_Interface methods. The caller is responsible for freeing the |
294 |
is responsible for freeing the returned value. |
returned value with free(). |
295 |
*/ |
*/ |
296 |
char* (*abstract_path)(LV2_State_Map_Path_Handle handle, |
char* (*abstract_path)(LV2_State_Map_Path_Handle handle, |
297 |
const char* absolute_path); |
const char* absolute_path); |
298 |
|
|
299 |
/** |
/** |
300 |
Map an abstract path from plugin state to an absolute path. |
Map an abstract path from plugin state to an absolute path. |
301 |
@param handle MUST be the @a handle member of this struct. |
@param handle MUST be the @p handle member of this struct. |
302 |
@param abstract_path An abstract path (e.g. a path from plugin state). |
@param abstract_path An abstract path (e.g. a path from plugin state). |
303 |
@return An absolute file system path. |
@return An absolute file system path. |
304 |
|
|
305 |
Since abstract paths are not necessarily actual file paths (or at least |
The plugin MUST use this function in order to actually open or otherwise |
306 |
not necessarily absolute paths), this function MUST be used in order to |
use any paths loaded from plugin state. |
|
actually open or otherwise use the file referred to by an abstract path. |
|
307 |
|
|
308 |
This function may only be called within the context of |
This function may only be called within the context of |
309 |
LV2_State_Interface.save() or LV2_State_Interface.restore(). The caller |
LV2_State_Interface methods. The caller is responsible for freeing the |
310 |
is responsible for freeing the returned value. |
returned value with free(). |
311 |
*/ |
*/ |
312 |
char* (*absolute_path)(LV2_State_Map_Path_Handle handle, |
char* (*absolute_path)(LV2_State_Map_Path_Handle handle, |
313 |
const char* abstract_path); |
const char* abstract_path); |
315 |
} LV2_State_Map_Path; |
} LV2_State_Map_Path; |
316 |
|
|
317 |
/** |
/** |
318 |
Feature data for state:makePath (@ref LV2_STATE_MAKE_PATH_URI). |
Feature data for state:makePath (@ref LV2_STATE__makePath). |
319 |
*/ |
*/ |
320 |
typedef struct { |
typedef struct { |
321 |
|
|
326 |
|
|
327 |
/** |
/** |
328 |
Return a path the plugin may use to create a new file. |
Return a path the plugin may use to create a new file. |
329 |
@param handle MUST be the @a handle member of this struct. |
@param handle MUST be the @p handle member of this struct. |
330 |
@param path The path of the new file relative to a namespace unique |
@param path The path of the new file within a namespace unique to this |
331 |
to this plugin instance. |
plugin instance. |
332 |
@return The absolute path to use for the new file. |
@return The absolute path to use for the new file. |
333 |
|
|
334 |
This function can be used by plugins to create files and directories, |
This function can be used by plugins to create files and directories, |
336 |
LV2_State_Interface.save()) or any time (if this feature is passed to |
LV2_State_Interface.save()) or any time (if this feature is passed to |
337 |
LV2_Descriptor.instantiate()). |
LV2_Descriptor.instantiate()). |
338 |
|
|
339 |
The host must do whatever is necessary for the plugin to be able to |
The host MUST do whatever is necessary for the plugin to be able to |
340 |
create a file at the returned path (e.g. using fopen), including |
create a file at the returned path (e.g. using fopen), including |
341 |
creating any leading directories. |
creating any leading directories. |
342 |
|
|