1 |
/* |
2 |
Copyright 2010-2012 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 state.h |
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 <stddef.h> |
27 |
#include <stdint.h> |
28 |
|
29 |
#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 |
41 |
extern "C" { |
42 |
#else |
43 |
# include <stdbool.h> |
44 |
#endif |
45 |
|
46 |
typedef void* LV2_State_Handle; |
47 |
typedef void* LV2_State_Map_Path_Handle; |
48 |
typedef void* LV2_State_Make_Path_Handle; |
49 |
|
50 |
/** |
51 |
Flags describing value characteristics. |
52 |
|
53 |
These flags are used along with the value's type URI to determine how to |
54 |
(de-)serialise the value data, or whether it is even possible to do so. |
55 |
*/ |
56 |
typedef enum { |
57 |
|
58 |
/** |
59 |
Plain Old Data. |
60 |
|
61 |
Values with this flag contain no pointers or references to other areas |
62 |
of memory. It is safe to copy POD values with a simple memcpy and store |
63 |
them for the duration of the process. A POD value is not necessarily |
64 |
safe to trasmit between processes or machines (e.g. filenames are POD), |
65 |
see LV2_STATE_IS_PORTABLE for details. |
66 |
|
67 |
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). |
69 |
*/ |
70 |
LV2_STATE_IS_POD = 1, |
71 |
|
72 |
/** |
73 |
Portable (architecture independent) data. |
74 |
|
75 |
Values with this flag are in a format that is usable on any |
76 |
architecture. A portable value saved on one machine can be restored on |
77 |
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, |
82 |
|
83 |
/** |
84 |
Native data. |
85 |
|
86 |
This flag is used by the host to indicate that the saved data is only |
87 |
going to be used locally in the currently running process (e.g. for |
88 |
instance duplication or snapshots), so the plugin should use the most |
89 |
efficient representation possible and not worry about serialisation |
90 |
and portability. |
91 |
*/ |
92 |
LV2_STATE_IS_NATIVE = 1 << 2 |
93 |
|
94 |
} 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. |
108 |
@param handle Must be the handle passed to LV2_State_Interface.save(). |
109 |
@param key The key to store @p value under (URID). |
110 |
@param value Pointer to the value to be stored. |
111 |
@param size The size of @p value in bytes. |
112 |
@param type The type of @p value (URID). |
113 |
@param flags LV2_State_Flags for @p value. |
114 |
@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 |
117 |
callback is called repeatedly by the plugin to store all the properties that |
118 |
describe its current state. |
119 |
|
120 |
DO NOT INVENT NONSENSE URI SCHEMES FOR THE KEY. Best is to use keys from |
121 |
existing vocabularies. If nothing appropriate is available, use http URIs |
122 |
that point to somewhere you can host documents so documentation can be made |
123 |
resolvable (e.g. a child of the plugin or project URI). If this is not |
124 |
possible, invent a URN scheme, e.g. urn:myproj:whatever. The plugin MUST |
125 |
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 @p size MUST be > 0, and @p value MUST point to a valid region of |
134 |
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 |
137 |
LV2_State_Interface.restore() context. |
138 |
*/ |
139 |
typedef LV2_State_Status (*LV2_State_Store_Function)( |
140 |
LV2_State_Handle handle, |
141 |
uint32_t key, |
142 |
const void* value, |
143 |
size_t size, |
144 |
uint32_t type, |
145 |
uint32_t flags); |
146 |
|
147 |
/** |
148 |
A host-provided function to retrieve a property. |
149 |
@param handle Must be the handle passed to LV2_State_Interface.restore(). |
150 |
@param key The key of the property to retrieve (URID). |
151 |
@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. |
153 |
@param flags (Output) If non-NULL, set to the flags for the restored value. |
154 |
@return A pointer to the restored value (object), or NULL if no value |
155 |
has been stored under @p key. |
156 |
|
157 |
A callback of this type is passed by the host to |
158 |
LV2_State_Interface.restore(). This callback is called repeatedly by the |
159 |
plugin to retrieve any properties it requires to restore its state. |
160 |
|
161 |
The returned value MUST remain valid until LV2_State_Interface.restore() |
162 |
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. |
164 |
*/ |
165 |
typedef const void* (*LV2_State_Retrieve_Function)( |
166 |
LV2_State_Handle handle, |
167 |
uint32_t key, |
168 |
size_t* size, |
169 |
uint32_t* type, |
170 |
uint32_t* flags); |
171 |
|
172 |
/** |
173 |
LV2 Plugin State Interface. |
174 |
|
175 |
When the plugin's extension_data is called with argument |
176 |
LV2_STATE__interface, the plugin MUST return an LV2_State_Interface |
177 |
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 |
180 |
state of a plugin instance at any time, provided the threading restrictions |
181 |
of the functions are met. |
182 |
|
183 |
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 |
185 |
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 |
187 |
authors should consider this possibility, and always store sensible data |
188 |
with meaningful types to avoid such problems in the future. |
189 |
*/ |
190 |
typedef struct _LV2_State_Interface { |
191 |
|
192 |
/** |
193 |
Save plugin state using a host-provided @p store callback. |
194 |
|
195 |
@param instance The instance handle of the plugin. |
196 |
@param store The host-provided store callback. |
197 |
@param handle An opaque pointer to host data which MUST be passed as the |
198 |
handle parameter to @p store if it is called. |
199 |
@param flags Flags describing desired properties of this save. These |
200 |
flags may be used to determine the most appropriate values to store. |
201 |
@param features Extensible parameter for passing any additional |
202 |
features to be used for this save. |
203 |
|
204 |
The plugin is expected to store everything necessary to completely |
205 |
restore its state later. Plugins SHOULD store simple POD data whenever |
206 |
possible, and consider the possibility of state being restored much |
207 |
later on a different machine. |
208 |
|
209 |
The @p handle pointer and @p store function MUST NOT be used |
210 |
beyond the scope of save(). |
211 |
|
212 |
This function has its own special threading class: it may not be called |
213 |
concurrently with any "Instantiation" function, but it may be called |
214 |
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 |
216 |
"Discovery" function, but it may be called concurrently with an "Audio" |
217 |
function. The plugin is responsible for any locking or lock-free |
218 |
techniques necessary to make this possible. |
219 |
|
220 |
Note that in the simple case where state is only modified by restore(), |
221 |
there are no synchronization issues since save() is never called |
222 |
concurrently with restore() (though run() may read it during a save). |
223 |
|
224 |
Plugins that dynamically modify state while running, however, must take |
225 |
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. |
227 |
*/ |
228 |
LV2_State_Status (*save)(LV2_Handle instance, |
229 |
LV2_State_Store_Function store, |
230 |
LV2_State_Handle handle, |
231 |
uint32_t flags, |
232 |
const LV2_Feature *const * features); |
233 |
|
234 |
/** |
235 |
Restore plugin state using a host-provided @p retrieve callback. |
236 |
|
237 |
@param instance The instance handle of the plugin. |
238 |
@param retrieve The host-provided retrieve callback. |
239 |
@param handle An opaque pointer to host data which MUST be passed as the |
240 |
handle parameter to @p retrieve if it is called. |
241 |
@param flags Currently unused. |
242 |
@param features Extensible parameter for passing any additional |
243 |
features to be used for this restore. |
244 |
|
245 |
The plugin MAY assume a restored value was set by a previous call to |
246 |
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 |
249 |
not be retrieved. This allows the host to reset the plugin state with |
250 |
an empty map. |
251 |
|
252 |
The @p handle pointer and @p store function MUST NOT be used |
253 |
beyond the scope of restore(). |
254 |
|
255 |
This function is in the "Instantiation" threading class as defined by |
256 |
LV2. This means it MUST NOT be called concurrently with any other |
257 |
function on the same plugin instance. |
258 |
*/ |
259 |
LV2_State_Status (*restore)(LV2_Handle instance, |
260 |
LV2_State_Retrieve_Function retrieve, |
261 |
LV2_State_Handle handle, |
262 |
uint32_t flags, |
263 |
const LV2_Feature *const * features); |
264 |
|
265 |
} LV2_State_Interface; |
266 |
|
267 |
/** |
268 |
Feature data for state:mapPath (LV2_STATE__mapPath). |
269 |
*/ |
270 |
typedef struct { |
271 |
|
272 |
/** |
273 |
Opaque host data. |
274 |
*/ |
275 |
LV2_State_Map_Path_Handle handle; |
276 |
|
277 |
/** |
278 |
Map an absolute path to an abstract path for use in plugin state. |
279 |
@param handle MUST be the @p handle member of this struct. |
280 |
@param absolute_path The absolute path of a file. |
281 |
@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 |
284 |
in plugin state. The returned value is an abstract path which MAY not |
285 |
be an actual file system path; @ref absolute_path() MUST be used to map |
286 |
it to an actual path in order to use the file. |
287 |
|
288 |
Plugins MUST NOT make any assumptions about abstract paths except that |
289 |
they can be mapped back to the absolute path of the "same" file (though |
290 |
not necessarily the same original path) using @ref absolute_path(). |
291 |
|
292 |
This function may only be called within the context of |
293 |
LV2_State_Interface methods. The caller is responsible for freeing the |
294 |
returned value with free(). |
295 |
*/ |
296 |
char* (*abstract_path)(LV2_State_Map_Path_Handle handle, |
297 |
const char* absolute_path); |
298 |
|
299 |
/** |
300 |
Map an abstract path from plugin state to an absolute path. |
301 |
@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). |
303 |
@return An absolute file system path. |
304 |
|
305 |
The plugin MUST use this function in order to actually open or otherwise |
306 |
use any paths loaded from plugin state. |
307 |
|
308 |
This function may only be called within the context of |
309 |
LV2_State_Interface methods. The caller is responsible for freeing the |
310 |
returned value with free(). |
311 |
*/ |
312 |
char* (*absolute_path)(LV2_State_Map_Path_Handle handle, |
313 |
const char* abstract_path); |
314 |
|
315 |
} LV2_State_Map_Path; |
316 |
|
317 |
/** |
318 |
Feature data for state:makePath (@ref LV2_STATE__makePath). |
319 |
*/ |
320 |
typedef struct { |
321 |
|
322 |
/** |
323 |
Opaque host data. |
324 |
*/ |
325 |
LV2_State_Make_Path_Handle handle; |
326 |
|
327 |
/** |
328 |
Return a path the plugin may use to create a new file. |
329 |
@param handle MUST be the @p handle member of this struct. |
330 |
@param path The path of the new file within a namespace unique to this |
331 |
plugin instance. |
332 |
@return The absolute path to use for the new file. |
333 |
|
334 |
This function can be used by plugins to create files and directories, |
335 |
either at state saving time (if this feature is passed to |
336 |
LV2_State_Interface.save()) or any time (if this feature is passed to |
337 |
LV2_Descriptor.instantiate()). |
338 |
|
339 |
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 |
341 |
creating any leading directories. |
342 |
|
343 |
If this function is passed to LV2_Descriptor.instantiate(), it may be |
344 |
called from any non-realtime context. If it is passed to |
345 |
LV2_State_Interface.save(), it may only be called within the dynamic |
346 |
scope of that function call. |
347 |
|
348 |
The caller is responsible for freeing the returned value with free(). |
349 |
*/ |
350 |
char* (*path)(LV2_State_Make_Path_Handle handle, |
351 |
const char* path); |
352 |
|
353 |
} LV2_State_Make_Path; |
354 |
|
355 |
#ifdef __cplusplus |
356 |
} /* extern "C" */ |
357 |
#endif |
358 |
|
359 |
#endif /* LV2_STATE_H */ |