aboutsummaryrefslogtreecommitdiffstats
path: root/src/state.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-12-21 02:14:27 +0000
committerDavid Robillard <d@drobilla.net>2011-12-21 02:14:27 +0000
commit06b9ff8c265d7199ad5aebf1c8c7abc90cba934a (patch)
treea4ab15ce6cfd48d46b7fc3fade0b93304b7a0611 /src/state.c
parent1d623932c5c465daa18dce2ce54f8e3b676f7a24 (diff)
downloadjalv-06b9ff8c265d7199ad5aebf1c8c7abc90cba934a.tar.gz
jalv-06b9ff8c265d7199ad5aebf1c8c7abc90cba934a.tar.bz2
jalv-06b9ff8c265d7199ad5aebf1c8c7abc90cba934a.zip
Add first-class PluginState object and make state interface more generic.
git-svn-id: http://svn.drobilla.net/lad/trunk/jalv@3893 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/state.c')
-rw-r--r--src/state.c147
1 files changed, 86 insertions, 61 deletions
diff --git a/src/state.c b/src/state.c
index 59f8785..d28ae90 100644
--- a/src/state.c
+++ b/src/state.c
@@ -36,14 +36,48 @@
#define USTR(s) ((const uint8_t*)s)
+typedef struct {
+ uint32_t key;
+ SerdNode value;
+ SerdNode datatype;
+} Property;
+
+typedef struct {
+ SerdNode symbol;
+ SerdNode value;
+ SerdNode datatype;
+} PortValue;
+
+struct PluginStateImpl {
+ LilvNode* plugin_uri;
+ Property* props;
+ PortValue* values;
+ uint32_t num_props;
+ uint32_t num_values;
+};
+
+const LilvNode*
+plugin_state_get_plugin_uri(const PluginState* state)
+{
+ return state->plugin_uri;
+}
+
static int
property_cmp(const void* a, const void* b)
{
- const struct Property* pa = (const struct Property*)a;
- const struct Property* pb = (const struct Property*)b;
+ const Property* pa = (const Property*)a;
+ const Property* pb = (const Property*)b;
return pa->key - pb->key;
}
+static int
+value_cmp(const void* a, const void* b)
+{
+ const PortValue* pa = (const PortValue*)a;
+ const PortValue* pb = (const PortValue*)b;
+ return strcmp((const char*)pa->symbol.buf, (const char*)pb->symbol.buf);
+}
+
#ifdef HAVE_LV2_STATE
typedef struct {
LV2_URID_Unmap* unmap;
@@ -83,9 +117,9 @@ store_callback(void* handle,
}
typedef struct {
- LV2_URID_Map* map;
- const struct Property* props;
- const uint32_t num_props;
+ LV2_URID_Map* map;
+ const Property* props;
+ const uint32_t num_props;
} RetrieveData;
static const void*
@@ -95,11 +129,11 @@ retrieve_callback(void* handle,
uint32_t* type,
uint32_t* flags)
{
- RetrieveData* data = (RetrieveData*)handle;
- struct Property search_key = { key, SERD_NODE_NULL, SERD_NODE_NULL };
- struct Property* prop = (struct Property*)bsearch(
+ RetrieveData* data = (RetrieveData*)handle;
+ Property search_key = { key, SERD_NODE_NULL, SERD_NODE_NULL };
+ Property* prop = (Property*)bsearch(
&search_key, data->props, data->num_props,
- sizeof(struct Property), property_cmp);
+ sizeof(Property), property_cmp);
if (prop) {
*size = prop->value.n_bytes;
@@ -204,20 +238,14 @@ jalv_save(Jalv* jalv, const char* dir)
}
typedef struct {
- SerdNode symbol;
- SerdNode value;
- SerdNode datatype;
-} PortValue;
-
-typedef struct {
- LilvWorld* world;
- LV2_URID_Map* map;
- LilvNode* plugin_uri;
- struct Property* props;
- PortValue* ports;
- uint32_t num_props;
- uint32_t num_ports;
- bool in_state;
+ LilvWorld* world;
+ LV2_URID_Map* map;
+ LilvNode* plugin_uri;
+ Property* props;
+ PortValue* ports;
+ uint32_t num_props;
+ uint32_t num_ports;
+ bool in_state;
} RestoreData;
static SerdStatus
@@ -232,9 +260,9 @@ on_statement(void* handle,
{
RestoreData* data = (RestoreData*)handle;
if (data->in_state) {
- data->props = (struct Property*)realloc(
- data->props, sizeof(struct Property) * (++data->num_props));
- struct Property* prop = &data->props[data->num_props - 1];
+ data->props = (Property*)realloc(
+ data->props, sizeof(Property) * (++data->num_props));
+ Property* prop = &data->props[data->num_props - 1];
prop->key = data->map->map(data->map->handle,
(const char*)predicate->buf);
prop->value = serd_node_copy(object);
@@ -259,17 +287,17 @@ on_statement(void* handle,
return SERD_SUCCESS;
}
-void
-jalv_restore(Jalv* jalv, const char* dir)
+PluginState*
+jalv_load_state(Jalv* jalv, const char* dir)
{
- RestoreData* data = (RestoreData*)malloc(sizeof(RestoreData));
- memset(data, '\0', sizeof(RestoreData));
- data->world = jalv->world;
- data->map = &jalv->map;
+ RestoreData data;
+ memset(&data, '\0', sizeof(RestoreData));
+ data.world = jalv->world;
+ data.map = &jalv->map;
SerdReader* reader = serd_reader_new(
SERD_TURTLE,
- data, NULL,
+ &data, NULL,
NULL,
NULL,
on_statement,
@@ -284,26 +312,36 @@ jalv_restore(Jalv* jalv, const char* dir)
if (st) {
fprintf(stderr, "Error reading state from %s (%s)\n",
state_uri, serd_strerror(st));
- return;
+ free(state_uri);
+ return NULL;
}
+ free(state_uri);
serd_reader_free(reader);
- const LilvPlugins* plugins = lilv_world_get_all_plugins(data->world);
- jalv->plugin = lilv_plugins_get_by_uri(plugins, data->plugin_uri);
- if (!jalv->plugin) {
- fprintf(stderr, "Failed to find plugin <%s> to restore\n",
- lilv_node_as_string(data->plugin_uri));
- return;
+ PluginState* state = (PluginState*)malloc(sizeof(PluginState));
+ state->plugin_uri = data.plugin_uri;
+ state->props = data.props;
+ state->num_props = data.num_props;
+ state->values = data.ports;
+ state->num_values = data.num_ports;
+
+ if (state->props) {
+ qsort(state->props, state->num_props, sizeof(Property), property_cmp);
+ }
+ if (state->values) {
+ qsort(state->values, state->num_values, sizeof(PortValue), value_cmp);
}
-
- jalv->num_ports = lilv_plugin_get_num_ports(jalv->plugin);
- jalv->ports = calloc(data->num_ports, sizeof(struct Port));
-
- jalv_create_ports(jalv);
- for (uint32_t i = 0; i < data->num_ports; ++i) {
- PortValue* dport = &data->ports[i];
+ return state;
+}
+
+void
+jalv_apply_state(Jalv* jalv, PluginState* state)
+{
+ /* Set port values */
+ for (uint32_t i = 0; i < state->num_values; ++i) {
+ PortValue* dport = &state->values[i];
const char* sym = (const char*)dport->symbol.buf;
struct Port* const jport = jalv_port_by_symbol(jalv, sym);
if (jport) {
@@ -313,25 +351,12 @@ jalv_restore(Jalv* jalv, const char* dir)
}
}
- if (jalv->props) {
- qsort(jalv->props, jalv->num_props, sizeof(struct Property), property_cmp);
- }
-
- jalv->props = data->props;
- jalv->num_props = data->num_props;
- free(data->ports);
- free(data);
-}
-
-void
-jalv_restore_instance(Jalv* jalv, const char* dir)
-{
#ifdef HAVE_LV2_STATE
const LV2_State_Interface* state_iface = (const LV2_State_Interface*)
lilv_instance_get_extension_data(jalv->instance, LV2_STATE_INTERFACE_URI);
if (state_iface) {
- RetrieveData data = { &jalv->map, jalv->props, jalv->num_props };
+ RetrieveData data = { &jalv->map, state->props, state->num_props };
state_iface->restore(lilv_instance_get_handle(jalv->instance),
retrieve_callback,
&data, 0, NULL);