aboutsummaryrefslogtreecommitdiffstats
path: root/src/state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/state.c')
-rw-r--r--src/state.c151
1 files changed, 93 insertions, 58 deletions
diff --git a/src/state.c b/src/state.c
index 282b907..472244e 100644
--- a/src/state.c
+++ b/src/state.c
@@ -1,30 +1,39 @@
-// Copyright 2007-2016 David Robillard <d@drobilla.net>
+// Copyright 2007-2024 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC
#include "state.h"
-#include "jalv_internal.h"
+#include "comm.h"
+#include "jalv.h"
#include "log.h"
+#include "mapper.h"
#include "port.h"
-
-#include "lilv/lilv.h"
-#include "lv2/core/lv2.h"
-#include "lv2/state/state.h"
-#include "zix/attributes.h"
-#include "zix/sem.h"
+#include "process.h"
+#include "types.h"
+
+#include <lilv/lilv.h>
+#include <lv2/core/lv2.h>
+#include <lv2/state/state.h>
+#include <lv2/urid/urid.h>
+#include <zix/attributes.h>
+#include <zix/path.h>
+#include <zix/ring.h>
+#include <zix/sem.h>
+#include <zix/status.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
-char*
+ZIX_MALLOC_FUNC char*
jalv_make_path(LV2_State_Make_Path_Handle handle, const char* path)
{
Jalv* jalv = (Jalv*)handle;
// Create in save directory if saving, otherwise use temp directory
- return jalv_strjoin(jalv->save_dir ? jalv->save_dir : jalv->temp_dir, path);
+ const char* const dir = jalv->save_dir ? jalv->save_dir : jalv->temp_dir;
+ return zix_path_join(NULL, dir, path);
}
static const void*
@@ -33,12 +42,12 @@ get_port_value(const char* port_symbol,
uint32_t* size,
uint32_t* type)
{
- Jalv* jalv = (Jalv*)user_data;
- struct Port* port = jalv_port_by_symbol(jalv, port_symbol);
+ Jalv* const jalv = (Jalv*)user_data;
+ const JalvPort* const port = jalv_port_by_symbol(jalv, port_symbol);
if (port && port->flow == FLOW_INPUT && port->type == TYPE_CONTROL) {
*size = sizeof(float);
*type = jalv->forge.Float;
- return &port->control;
+ return &jalv->process.controls_buf[port->index];
}
*size = *type = 0;
return NULL;
@@ -47,12 +56,15 @@ get_port_value(const char* port_symbol,
void
jalv_save(Jalv* jalv, const char* dir)
{
- jalv->save_dir = jalv_strjoin(dir, "/");
+ LV2_URID_Map* const map = jalv_mapper_urid_map(jalv->mapper);
+ LV2_URID_Unmap* const unmap = jalv_mapper_urid_unmap(jalv->mapper);
+
+ jalv->save_dir = zix_path_join(NULL, dir, NULL);
LilvState* const state =
lilv_state_new_from_instance(jalv->plugin,
- jalv->instance,
- &jalv->map,
+ jalv->process.instance,
+ map,
jalv->temp_dir,
dir,
dir,
@@ -62,11 +74,8 @@ jalv_save(Jalv* jalv, const char* dir)
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE,
NULL);
- lilv_state_save(
- jalv->world, &jalv->map, &jalv->unmap, state, NULL, dir, "state.ttl");
-
+ lilv_state_save(jalv->world, map, unmap, state, NULL, dir, "state.ttl");
lilv_state_free(state);
-
free(jalv->save_dir);
jalv->save_dir = NULL;
}
@@ -121,8 +130,9 @@ set_port_value(const char* port_symbol,
uint32_t ZIX_UNUSED(size),
uint32_t type)
{
- Jalv* jalv = (Jalv*)user_data;
- struct Port* port = jalv_port_by_symbol(jalv, port_symbol);
+ Jalv* const jalv = (Jalv*)user_data;
+ JalvProcess* const proc = &jalv->process;
+ const JalvPort* const port = jalv_port_by_symbol(jalv, port_symbol);
if (!port) {
jalv_log(JALV_LOG_ERR, "Preset port `%s' is missing\n", port_symbol);
return;
@@ -141,51 +151,71 @@ set_port_value(const char* port_symbol,
jalv_log(JALV_LOG_ERR,
"Preset `%s' value has bad type <%s>\n",
port_symbol,
- jalv->unmap.unmap(jalv->unmap.handle, type));
+ jalv_mapper_unmap_uri(jalv->mapper, type));
return;
}
- if (jalv->play_state != JALV_RUNNING) {
+ ZixStatus st = ZIX_STATUS_SUCCESS;
+ if (proc->run_state != JALV_RUNNING) {
// Set value on port struct directly
- port->control = fvalue;
+ proc->controls_buf[port->index] = fvalue;
} else {
// Send value to plugin (as if from UI)
- jalv_write_control(jalv, jalv->ui_to_plugin, port->index, fvalue);
+ st = jalv_write_control(proc->ui_to_plugin, port->index, fvalue);
}
- if (jalv->has_ui) {
+ if (proc->has_ui) {
// Update UI (as if from plugin)
- jalv_write_control(jalv, jalv->plugin_to_ui, port->index, fvalue);
+ st = jalv_write_control(proc->plugin_to_ui, port->index, fvalue);
+ }
+
+ if (st) {
+ jalv_log(
+ JALV_LOG_ERR, "Failed to write control change (%s)\n", zix_strerror(st));
}
}
void
-jalv_apply_state(Jalv* jalv, LilvState* state)
+jalv_apply_state(Jalv* jalv, const LilvState* state)
{
- bool must_pause = !jalv->safe_restore && jalv->play_state == JALV_RUNNING;
- if (state) {
- if (must_pause) {
- jalv->play_state = JALV_PAUSE_REQUESTED;
- zix_sem_wait(&jalv->paused);
- }
+ JalvProcess* const proc = &jalv->process;
- const LV2_Feature* state_features[9] = {
- &jalv->features.map_feature,
- &jalv->features.unmap_feature,
- &jalv->features.make_path_feature,
- &jalv->features.state_sched_feature,
- &jalv->features.safe_restore_feature,
- &jalv->features.log_feature,
- &jalv->features.options_feature,
- NULL};
-
- lilv_state_restore(
- state, jalv->instance, set_port_value, jalv, 0, state_features);
-
- if (must_pause) {
- jalv->request_update = true;
- jalv->play_state = JALV_RUNNING;
- }
+ typedef struct {
+ JalvMessageHeader head;
+ JalvRunStateChange body;
+ } PauseMessage;
+
+ const bool must_pause =
+ !jalv->safe_restore && proc->run_state == JALV_RUNNING;
+ if (must_pause) {
+ const PauseMessage pause_msg = {
+ {RUN_STATE_CHANGE, sizeof(JalvRunStateChange)}, {JALV_PAUSED}};
+ zix_ring_write(proc->ui_to_plugin, &pause_msg, sizeof(pause_msg));
+
+ zix_sem_wait(&proc->paused);
+ }
+
+ const LV2_Feature* state_features[9] = {
+ &jalv->features.map_feature,
+ &jalv->features.unmap_feature,
+ &jalv->features.make_path_feature,
+ &jalv->features.state_sched_feature,
+ &jalv->features.safe_restore_feature,
+ &jalv->features.log_feature,
+ &jalv->features.options_feature,
+ NULL,
+ };
+
+ lilv_state_restore(
+ state, proc->instance, set_port_value, jalv, 0, state_features);
+
+ if (must_pause) {
+ const JalvMessageHeader state_msg = {STATE_REQUEST, 0U};
+ zix_ring_write(proc->ui_to_plugin, &state_msg, sizeof(state_msg));
+
+ const PauseMessage run_msg = {
+ {RUN_STATE_CHANGE, sizeof(JalvRunStateChange)}, {JALV_RUNNING}};
+ zix_ring_write(proc->ui_to_plugin, &run_msg, sizeof(run_msg));
}
}
@@ -193,8 +223,11 @@ int
jalv_apply_preset(Jalv* jalv, const LilvNode* preset)
{
lilv_state_free(jalv->preset);
- jalv->preset = lilv_state_new_from_world(jalv->world, &jalv->map, preset);
- jalv_apply_state(jalv, jalv->preset);
+ jalv->preset = lilv_state_new_from_world(
+ jalv->world, jalv_mapper_urid_map(jalv->mapper), preset);
+ if (jalv->preset) {
+ jalv_apply_state(jalv, jalv->preset);
+ }
return 0;
}
@@ -205,10 +238,13 @@ jalv_save_preset(Jalv* jalv,
const char* label,
const char* filename)
{
+ LV2_URID_Map* const map = jalv_mapper_urid_map(jalv->mapper);
+ LV2_URID_Unmap* const unmap = jalv_mapper_urid_unmap(jalv->mapper);
+
LilvState* const state =
lilv_state_new_from_instance(jalv->plugin,
- jalv->instance,
- &jalv->map,
+ jalv->process.instance,
+ map,
jalv->temp_dir,
dir,
dir,
@@ -222,8 +258,7 @@ jalv_save_preset(Jalv* jalv,
lilv_state_set_label(state, label);
}
- int ret = lilv_state_save(
- jalv->world, &jalv->map, &jalv->unmap, state, uri, dir, filename);
+ int ret = lilv_state_save(jalv->world, map, unmap, state, uri, dir, filename);
lilv_state_free(jalv->preset);
jalv->preset = state;