1 |
/* |
2 |
Copyright 2010-2011 David Robillard <http://drobilla.net> |
3 |
Copyright 2010 Leonard Ritter <paniq@paniq.org> |
4 |
|
5 |
Permission to use, copy, modify, and/or distribute this software for any |
6 |
purpose with or without fee is hereby granted, provided that the above |
7 |
copyright notice and this permission notice appear in all copies. |
8 |
|
9 |
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
10 |
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
11 |
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
12 |
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
13 |
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
14 |
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
15 |
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 |
*/ |
17 |
|
18 |
/** |
19 |
@file |
20 |
C API for the LV2 State extension <http://lv2plug.in/ns/ext/state>. |
21 |
*/ |
22 |
|
23 |
#ifndef LV2_STATE_H |
24 |
#define LV2_STATE_H |
25 |
|
26 |
#include <stdbool.h> |
27 |
#include <stddef.h> |
28 |
#include <stdint.h> |
29 |
|
30 |
#include <lv2.h> |
31 |
|
32 |
#ifdef __cplusplus |
33 |
extern "C" { |
34 |
#endif |
35 |
|
36 |
#define LV2_STATE_URI "http://lv2plug.in/ns/ext/state" |
37 |
|
38 |
#define LV2_STATE_INTERFACE_URI LV2_STATE_URI "#Interface" |
39 |
#define LV2_STATE_PATH_URI LV2_STATE_URI "#Path" |
40 |
#define LV2_STATE_MAP_PATH_URI LV2_STATE_URI "#pathMap" |
41 |
#define LV2_STATE_MAKE_PATH_URI LV2_STATE_URI "#newPath" |
42 |
|
43 |
typedef void* LV2_State_Handle; |
44 |
typedef void* LV2_State_Map_Path_Handle; |
45 |
typedef void* LV2_State_Make_Path_Handle; |
46 |
|
47 |
/** |
48 |
Flags describing value characteristics. |
49 |
|
50 |
These flags are used along with the value's type URI to determine how to |
51 |
(de-)serialise the value data, or whether it is even possible to do so. |
52 |
*/ |
53 |
typedef enum { |
54 |
|
55 |
/** |
56 |
Plain Old Data. |
57 |
|
58 |
Values with this flag contain no references to non-stateent or |
59 |
non-global resources (e.g. pointers, handles, local paths, etc.). It is |
60 |
safe to copy POD values with a simple memcpy and store them for use at |
61 |
any time in the future on a machine with a compatible architecture |
62 |
(e.g. the same endianness and alignment). |
63 |
|
64 |
Implementations MUST NOT attempt to copy or serialise a non-POD value if |
65 |
they do not understand its type (and thus know how to correctly do so). |
66 |
*/ |
67 |
LV2_STATE_IS_POD = 1, |
68 |
|
69 |
/** |
70 |
Portable (architecture independent) data. |
71 |
|
72 |
Values with this flag are in a format that is usable on any |
73 |
architecture, i.e. if the value is saved on one machine it can safely be |
74 |
restored on another machine regardless of endianness, alignment, etc. |
75 |
*/ |
76 |
LV2_STATE_IS_PORTABLE = 1 << 1, |
77 |
|
78 |
/** |
79 |
Native data. |
80 |
|
81 |
This flag is used by the host to indicate that the saved data is only |
82 |
going to be used locally in the currently running process (e.g. for |
83 |
instance duplication or snapshots), so the plugin should use the most |
84 |
efficient representation possible and not worry about serialisation |
85 |
and portability. |
86 |
*/ |
87 |
LV2_STATE_IS_NATIVE = 1 << 2 |
88 |
|
89 |
} LV2_State_Flags; |
90 |
|
91 |
/** |
92 |
A host-provided function to store a property. |
93 |
@param handle Must be the handle passed to LV2_State_Interface.save(). |
94 |
@param key The key (predicate) to store @c value under (URI mapped integer). |
95 |
@param value Pointer to the value (object) to be stored. |
96 |
@param size The size of the data at @c value in bytes. |
97 |
@param type The type of @c value (URI). |
98 |
@param flags LV2_State_Flags for @c value. |
99 |
@return 0 on success, otherwise a non-zero error code. |
100 |
|
101 |
The host passes a callback of this type to LV2_State_Interface.save(). This callback |
102 |
is called repeatedly by the plugin within LV2_State_Interface.save() to store all |
103 |
the statements that describe its current state. |
104 |
|
105 |
The host MAY fail to store a property if the type is not understood and is |
106 |
not LV2_STATE_IS_POD and/or LV2_STATE_IS_PORTABLE. Implementations are |
107 |
encouraged to use POD and portable values (e.g. string literals) wherever |
108 |
possible, and use common types (e.g. types from |
109 |
http://lv2plug.in/ns/ext/atom) regardless, since hosts are likely to already |
110 |
contain the necessary implementation. |
111 |
|
112 |
Note that @c size MUST be > 0, and @c value MUST point to a valid region of |
113 |
memory @c size bytes long (this is required to make restore unambiguous). |
114 |
|
115 |
The plugin MUST NOT attempt to use this function outside of the |
116 |
LV2_State_Interface.restore() context. |
117 |
*/ |
118 |
typedef int (*LV2_State_Store_Function)(LV2_State_Handle handle, |
119 |
uint32_t key, |
120 |
const void* value, |
121 |
size_t size, |
122 |
uint32_t type, |
123 |
uint32_t flags); |
124 |
|
125 |
/** |
126 |
A host-provided function to retrieve a property. |
127 |
@param handle Must be the handle passed to |
128 |
LV2_State_Interface.restore(). |
129 |
@param key The key (predicate) of the property to retrieve (URI). |
130 |
@param size (Output) If non-NULL, set to the size of the restored value. |
131 |
@param type (Output) If non-NULL, set to the type of the restored value. |
132 |
@param flags (Output) If non-NULL, set to the LV2_State_Flags for |
133 |
the returned value. |
134 |
@return A pointer to the restored value (object), or NULL if no value |
135 |
has been stored under @c key. |
136 |
|
137 |
A callback of this type is passed by the host to |
138 |
LV2_State_Interface.restore(). This callback is called repeatedly by the |
139 |
plugin within LV2_State_Interface.restore() to retrieve any properties it |
140 |
requires to restore its state. |
141 |
|
142 |
The returned value MUST remain valid until LV2_State_Interface.restore() |
143 |
returns. |
144 |
|
145 |
The plugin MUST NOT attempt to use this function, or any value returned from |
146 |
it, outside of the LV2_State_Interface.restore() context. Returned values |
147 |
MAY be copied for later use if necessary, assuming the plugin knows how to |
148 |
do so correctly (e.g. the value is POD, or the plugin understands the type). |
149 |
*/ |
150 |
typedef const void* (*LV2_State_Retrieve_Function)(LV2_State_Handle handle, |
151 |
uint32_t key, |
152 |
size_t* size, |
153 |
uint32_t* type, |
154 |
uint32_t* flags); |
155 |
|
156 |
/** |
157 |
State Extension Data. |
158 |
|
159 |
When the plugin's extension_data is called with argument LV2_STATE_URI, |
160 |
the plugin MUST return an LV2_State structure, which remains valid for the |
161 |
lifetime of the plugin. |
162 |
|
163 |
The host can use the contained function pointers to save and restore the |
164 |
state of a plugin instance at any time (provided the threading restrictions |
165 |
for the given function are met). |
166 |
|
167 |
The typical use case is to save the plugin's state when a project is saved, |
168 |
and to restore the state when a project has been loaded. Other uses are |
169 |
possible (e.g. cloning plugin instances or taking a snapshot of plugin |
170 |
state). |
171 |
|
172 |
Stored data is only guaranteed to be compatible between instances of plugins |
173 |
with the same URI (i.e. if a change to a plugin would cause a fatal error |
174 |
when restoring state saved by a previous version of that plugin, the plugin |
175 |
URI MUST change just as it must when ports change incompatibly). Plugin |
176 |
authors should consider this possibility, and always store sensible data |
177 |
with meaningful types to avoid such compatibility issues in the future. |
178 |
*/ |
179 |
typedef struct _LV2_State_Interface { |
180 |
|
181 |
/** |
182 |
Save plugin state using a host-provided @c store callback. |
183 |
|
184 |
@param instance The instance handle of the plugin. |
185 |
@param store The host-provided store callback. |
186 |
@param handle An opaque pointer to host data, e.g. the map or |
187 |
file where the values are to be stored. If @c store is called, this MUST |
188 |
be passed as its handle parameter. |
189 |
@param flags Flags describing desires properties of this save. The |
190 |
plugin SHOULD use these values to determine the most appropriate and/or |
191 |
efficient serialisation, but is not required to do so. |
192 |
@param features Extensible parameter for passing any additional |
193 |
features to be used for this save. |
194 |
|
195 |
The plugin is expected to store everything necessary to completely |
196 |
restore its state later (possibly much later, in a different process, on |
197 |
a completely different machine, etc.) |
198 |
|
199 |
The @c handle pointer and @c store function MUST NOT be used |
200 |
beyond the scope of save(). |
201 |
|
202 |
This function has its own special threading class: it may not be called |
203 |
concurrently with any "Instantiation" function, but it may be called |
204 |
concurrently with functions in any other class, unless the definition of |
205 |
that class prohibits it (e.g. it may not be called concurrently with a |
206 |
"Discovery" function, but it may be called concurrently with an "Audio" |
207 |
function. The plugin is responsible for any locking or lock-free |
208 |
techniques necessary to make this possible. |
209 |
|
210 |
Note that in the simple case where state is only modified by restore(), |
211 |
there are no synchronization issues since save() is never called |
212 |
concurrently with restore() (though run() may read it during a save). |
213 |
|
214 |
Plugins that dynamically modify state while running, however, must take |
215 |
care to do so in such a way that a concurrent call to save() will save a |
216 |
consistent representation of plugin state for a single instant in time. |
217 |
*/ |
218 |
void (*save)(LV2_Handle instance, |
219 |
LV2_State_Store_Function store, |
220 |
LV2_State_Handle handle, |
221 |
uint32_t flags, |
222 |
const LV2_Feature *const * features); |
223 |
|
224 |
|
225 |
/** |
226 |
Restore plugin state using a host-provided @c retrieve callback. |
227 |
|
228 |
@param instance The instance handle of the plugin. |
229 |
@param retrieve The host-provided retrieve callback. |
230 |
@param handle An opaque pointer to host data, e.g. the map or |
231 |
file from which the values are to be restored. If @c retrieve is |
232 |
called, this MUST be passed as its handle parameter. |
233 |
@param flags Currently unused. |
234 |
@param features Extensible parameter for passing any additional |
235 |
features to be used for this restore. |
236 |
|
237 |
The plugin MAY assume a restored value was set by a previous call to |
238 |
LV2_State_Interface.save() by a plugin with the same URI. |
239 |
|
240 |
The plugin MUST gracefully fall back to a default value when a value can |
241 |
not be retrieved. This allows the host to reset the plugin state with an |
242 |
empty map. |
243 |
|
244 |
The @c handle pointer and @c store function MUST NOT be used |
245 |
beyond the scope of restore(). |
246 |
|
247 |
This function is in the "Instantiation" threading class as defined by |
248 |
LV2. This means it MUST NOT be called concurrently with any other |
249 |
function on the same plugin instance. |
250 |
*/ |
251 |
void (*restore)(LV2_Handle instance, |
252 |
LV2_State_Retrieve_Function retrieve, |
253 |
LV2_State_Handle handle, |
254 |
uint32_t flags, |
255 |
const LV2_Feature *const * features); |
256 |
|
257 |
} LV2_State_Interface; |
258 |
|
259 |
/** |
260 |
Feature data for state:pathMap (LV2_STATE_MAP_PATH_URI). |
261 |
*/ |
262 |
typedef struct { |
263 |
|
264 |
/** |
265 |
Opaque host data. |
266 |
*/ |
267 |
LV2_State_Map_Path_Handle handle; |
268 |
|
269 |
/** |
270 |
Map an absolute path to an abstract path for use in plugin state. |
271 |
@param handle MUST be the @a handle member of this struct. |
272 |
@param absolute_path The absolute path of a file. |
273 |
@return An abstract path suitable for use in plugin state. |
274 |
|
275 |
The plugin MUST use this function to map any paths that will be stored |
276 |
in files in plugin state. The returned value is an abstract path which |
277 |
MAY not be an actual file system path; @ref absolute_path MUST be used |
278 |
to map it to an actual path in order to use the file. |
279 |
|
280 |
Hosts MAY map paths in any way (e.g. by creating symbolic links within |
281 |
the plugin's state directory or storing a list of referenced files |
282 |
elsewhere). Plugins MUST NOT make any assumptions about abstract paths |
283 |
except that they can be mapped back to an absolute path using @ref |
284 |
absolute_path. |
285 |
|
286 |
This function may only be called within the context of |
287 |
LV2_State_Interface.save() or LV2_State_Interface.restore(). The caller |
288 |
is responsible for freeing the returned value. |
289 |
*/ |
290 |
char* (*abstract_path)(LV2_State_Map_Path_Handle handle, |
291 |
const char* absolute_path); |
292 |
|
293 |
/** |
294 |
Map an abstract path from plugin state to an absolute path. |
295 |
@param handle MUST be the @a handle member of this struct. |
296 |
@param abstract_path An abstract path (e.g. a path from plugin state). |
297 |
@return An absolute file system path. |
298 |
|
299 |
Since abstract paths are not necessarily actual file paths (or at least |
300 |
not necessarily absolute paths), this function MUST be used in order to |
301 |
actually open or otherwise use the file referred to by an abstract path. |
302 |
|
303 |
This function may only be called within the context of |
304 |
LV2_State_Interface.save() or LV2_State_Interface.restore(). The caller |
305 |
is responsible for freeing the returned value. |
306 |
*/ |
307 |
char* (*absolute_path)(LV2_State_Map_Path_Handle handle, |
308 |
const char* abstract_path); |
309 |
|
310 |
} LV2_State_Map_Path; |
311 |
|
312 |
/** |
313 |
Feature data for state:makePath (@ref LV2_STATE_MAKE_PATH_URI). |
314 |
*/ |
315 |
typedef struct { |
316 |
|
317 |
/** |
318 |
Opaque host data. |
319 |
*/ |
320 |
LV2_State_Make_Path_Handle handle; |
321 |
|
322 |
/** |
323 |
Return a path the plugin may use to create a new file. |
324 |
@param handle MUST be the @a handle member of this struct. |
325 |
@param path The path of the new file relative to a namespace unique |
326 |
to this plugin instance. |
327 |
@return The absolute path to use for the new file. |
328 |
|
329 |
This function can be used by plugins to create files and directories, |
330 |
either at state saving time (if this feature is passed to |
331 |
LV2_State_Interface.save()) or any time (if this feature is passed to |
332 |
LV2_Descriptor.instantiate()). |
333 |
|
334 |
The host must do whatever is necessary for the plugin to be able to |
335 |
create a file at the returned path (e.g. using fopen), including |
336 |
creating any leading directories. |
337 |
|
338 |
If this function is passed to LV2_Descriptor.instantiate(), it may be |
339 |
called from any non-realtime context. If it is passed to |
340 |
LV2_State_Interface.save(), it may only be called within the dynamic |
341 |
scope of that function call. |
342 |
|
343 |
The caller is responsible for freeing the returned value with free(). |
344 |
*/ |
345 |
char* (*path)(LV2_State_Make_Path_Handle handle, |
346 |
const char* path); |
347 |
|
348 |
} LV2_State_Make_Path; |
349 |
|
350 |
#ifdef __cplusplus |
351 |
} /* extern "C" */ |
352 |
#endif |
353 |
|
354 |
#endif /* LV2_STATE_H */ |