ladishd: save connections and load them in hidden state

This commit is contained in:
Nedko Arnaudov 2009-11-29 00:07:40 +02:00
parent effcdfca27
commit 6cd9754d56
6 changed files with 287 additions and 2 deletions

View File

@ -47,6 +47,8 @@
#define PARSE_CONTEXT_PORT 8
#define PARSE_CONTEXT_DICT 9
#define PARSE_CONTEXT_KEY 10
#define PARSE_CONTEXT_CONNECTIONS 11
#define PARSE_CONTEXT_CONNECTION 12
#define MAX_STACK_DEPTH 10
#define MAX_DATA_SIZE 1024
@ -62,6 +64,7 @@ struct parse_context
ladish_client_handle client;
ladish_port_handle port;
ladish_dict_handle dict;
uint64_t connection_id;
};
#define context_ptr ((struct parse_context *)data)
@ -91,6 +94,9 @@ static void callback_chrdata(void * data, const XML_Char * s, int len)
static void callback_elstart(void * data, const char * el, const char ** attr)
{
uuid_t uuid;
uuid_t uuid2;
ladish_port_handle port1;
ladish_port_handle port2;
if (context_ptr->error)
{
@ -375,6 +381,73 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
return;
}
if (strcmp(el, "connections") == 0)
{
//log_info("<connections>");
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_CONNECTIONS;
return;
}
if (strcmp(el, "connection") == 0)
{
//log_info("<connection>");
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_CONNECTION;
if (attr[0] == NULL ||
attr[1] == NULL ||
attr[2] == NULL ||
attr[3] == NULL ||
attr[4] != NULL ||
strcmp(attr[0], "port1") != 0 ||
strcmp(attr[2], "port2") != 0)
{
log_error("studio/connections/connection XML element must contain exactly two attributes, named \"port1\" and \"port2\", in this order");
context_ptr->error = XML_TRUE;
return;
}
if (uuid_parse(attr[1], uuid) != 0)
{
log_error("cannot parse uuid \"%s\"", attr[1]);
context_ptr->error = XML_TRUE;
return;
}
if (uuid_parse(attr[3], uuid2) != 0)
{
log_error("cannot parse uuid \"%s\"", attr[3]);
context_ptr->error = XML_TRUE;
return;
}
log_info("studio connection between port %s and port %s", attr[1], attr[3]);
port1 = ladish_graph_find_port_by_uuid(g_studio.studio_graph, uuid);
if (port1 == NULL)
{
log_error("studio client with unknown port %s", attr[1]);
context_ptr->error = XML_TRUE;
return;
}
port2 = ladish_graph_find_port_by_uuid(g_studio.studio_graph, uuid2);
if (port2 == NULL)
{
log_error("studio client with unknown port %s", attr[3]);
context_ptr->error = XML_TRUE;
return;
}
context_ptr->connection_id = ladish_graph_add_connection(g_studio.studio_graph, port1, port2, true);
if (context_ptr->connection_id == 0)
{
log_error("ladish_graph_add_connection() failed.");
return;
}
return;
}
if (strcmp(el, "dict") == 0)
{
//log_info("<dict>");
@ -407,6 +480,13 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
context_ptr->dict = ladish_port_get_dict(context_ptr->port);
ASSERT(context_ptr->dict != NULL);
}
else if (context_ptr->depth > 0 &&
context_ptr->element[context_ptr->depth - 1] == PARSE_CONTEXT_CONNECTION)
{
ASSERT(context_ptr->port != NULL);
context_ptr->dict = ladish_graph_get_connection_dict(g_studio.studio_graph, context_ptr->connection_id);
ASSERT(context_ptr->dict != NULL);
}
else
{
log_error("unexpected dict XML element");

View File

@ -498,6 +498,68 @@ save_studio_port(
return true;
}
bool save_studio_connection(void * context, ladish_port_handle port1_handle, ladish_port_handle port2_handle, ladish_dict_handle dict)
{
uuid_t uuid;
char str[37];
log_info("saving studio connection");
if (!write_string(fd, " <connection port1=\""))
{
return false;
}
ladish_port_get_uuid(port1_handle, uuid);
uuid_unparse(uuid, str);
if (!write_string(fd, str))
{
return false;
}
if (!write_string(fd, "\" port2=\""))
{
return false;
}
ladish_port_get_uuid(port2_handle, uuid);
uuid_unparse(uuid, str);
if (!write_string(fd, str))
{
return false;
}
if (ladish_dict_is_empty(dict))
{
if (!write_string(fd, "\" />\n"))
{
return false;
}
}
else
{
if (!write_string(fd, "\">\n"))
{
return false;
}
if (!write_dict(fd, " ", dict))
{
return false;
}
if (!write_string(fd, " </connection>\n"))
{
return false;
}
}
return true;
return true;
}
#undef indent
#undef fd
@ -689,6 +751,22 @@ static bool run(void * command_context)
goto close;
}
if (!write_string(fd, " <connections>\n"))
{
goto close;
}
if (!ladish_graph_iterate_connections(g_studio.studio_graph, &save_context, save_studio_connection))
{
log_error("ladish_graph_iterate_connections() failed");
goto close;
}
if (!write_string(fd, " </connections>\n"))
{
goto close;
}
if (!write_dict(fd, " ", ladish_graph_get_dict(g_studio.studio_graph)))
{
return false;

View File

@ -60,6 +60,7 @@ struct ladish_graph_connection
bool hidden;
struct ladish_graph_port * port1_ptr;
struct ladish_graph_port * port2_ptr;
ladish_dict_handle dict;
};
struct ladish_graph
@ -329,6 +330,11 @@ static void get_graph(struct dbus_method_call * call_ptr)
{
connection_ptr = list_entry(connection_node_ptr, struct ladish_graph_connection, siblings);
if (connection_ptr->hidden)
{
continue;
}
if (!dbus_message_iter_open_container(&connections_array_iter, DBUS_TYPE_STRUCT, NULL, &connection_struct_iter))
{
goto nomem_close_connections_array;
@ -824,6 +830,42 @@ ladish_dict_handle ladish_graph_get_dict(ladish_graph_handle graph_handle)
return graph_ptr->dict;
}
void ladish_graph_show_connection(ladish_graph_handle graph_handle, uint64_t connection_id)
{
struct ladish_graph_connection * connection_ptr;
log_info("ladish_graph_show_connection() called.");
connection_ptr = ladish_graph_find_connection_by_id(graph_ptr, connection_id);
if (connection_ptr == NULL)
{
ASSERT_NO_PASS;
return;
}
ASSERT(graph_ptr->opath != NULL);
ASSERT(connection_ptr->hidden);
connection_ptr->hidden = false;
graph_ptr->graph_version++;
dbus_signal_emit(
g_dbus_connection,
graph_ptr->opath,
JACKDBUS_IFACE_PATCHBAY,
"PortsConnected",
"ttstststst",
&graph_ptr->graph_version,
&connection_ptr->port1_ptr->client_ptr->id,
&connection_ptr->port1_ptr->client_ptr->name,
&connection_ptr->port1_ptr->id,
&connection_ptr->port1_ptr->name,
&connection_ptr->port2_ptr->client_ptr->id,
&connection_ptr->port2_ptr->client_ptr->name,
&connection_ptr->port2_ptr->id,
&connection_ptr->port2_ptr->name,
&connection_ptr->id);
}
void ladish_graph_show_port(ladish_graph_handle graph_handle, ladish_port_handle port_handle)
{
struct ladish_graph_port * port_ptr;
@ -1150,6 +1192,13 @@ ladish_graph_add_connection(
return 0;
}
if (!ladish_dict_create(&connection_ptr->dict))
{
log_error("ladish_dict_create() failed for connection");
free(connection_ptr);
return 0;
}
connection_ptr->id = graph_ptr->next_connection_id++;
connection_ptr->port1_ptr = port1_ptr;
connection_ptr->port2_ptr = port2_ptr;
@ -1218,6 +1267,7 @@ ladish_graph_remove_connection(
&connection_ptr->id);
}
ladish_dict_destroy(connection_ptr->dict);
free(connection_ptr);
}
@ -1242,6 +1292,19 @@ ladish_graph_get_connection_ports(
return true;
}
ladish_dict_handle ladish_graph_get_connection_dict(ladish_graph_handle graph_handle, uint64_t connection_id)
{
struct ladish_graph_connection * connection_ptr;
connection_ptr = ladish_graph_find_connection_by_id(graph_ptr, connection_id);
if (connection_ptr == NULL)
{
return NULL;
}
return connection_ptr->dict;
}
bool
ladish_graph_find_connection(
ladish_graph_handle graph_handle,
@ -1583,6 +1646,28 @@ ladish_graph_iterate_nodes(
return true;
}
bool
ladish_graph_iterate_connections(
ladish_graph_handle graph_handle,
void * callback_context,
bool (* callback)(void * context, ladish_port_handle port1_handle, ladish_port_handle port2_handle, ladish_dict_handle dict))
{
struct list_head * node_ptr;
struct ladish_graph_connection * connection_ptr;
list_for_each(node_ptr, &graph_ptr->connections)
{
connection_ptr = list_entry(node_ptr, struct ladish_graph_connection, siblings);
if (!callback(callback_context, connection_ptr->port1_ptr->port, connection_ptr->port2_ptr->port, connection_ptr->dict))
{
return false;
}
}
return true;
}
static
bool
dump_dict_entry(
@ -1615,6 +1700,8 @@ void ladish_graph_dump(ladish_graph_handle graph_handle)
struct ladish_graph_client * client_ptr;
struct list_head * port_node_ptr;
struct ladish_graph_port * port_ptr;
struct list_head * connection_node_ptr;
struct ladish_graph_connection * connection_ptr;
log_info("graph %s", graph_ptr->opath != NULL ? graph_ptr->opath : "JACK");
log_info(" version %"PRIu64, graph_ptr->graph_version);
@ -1634,6 +1721,20 @@ void ladish_graph_dump(ladish_graph_handle graph_handle)
dump_dict(" ", ladish_port_get_dict(port_ptr->port));
}
}
log_info(" connections:");
list_for_each(connection_node_ptr, &graph_ptr->connections)
{
connection_ptr = list_entry(connection_node_ptr, struct ladish_graph_connection, siblings);
log_info(
" %s connection '%s':'%s' - '%s':'%s'",
connection_ptr->hidden ? "invisible" : "visible",
connection_ptr->port1_ptr->client_ptr->name,
connection_ptr->port1_ptr->name,
connection_ptr->port2_ptr->client_ptr->name,
connection_ptr->port2_ptr->name);
dump_dict(" ", ladish_port_get_dict(port_ptr->port));
}
}
#undef graph_ptr

View File

@ -60,6 +60,7 @@ ladish_graph_set_connection_handlers(
void ladish_graph_clear(ladish_graph_handle graph_handle, bool destroy_ports);
void * ladish_graph_get_dbus_context(ladish_graph_handle graph_handle);
ladish_dict_handle ladish_graph_get_dict(ladish_graph_handle graph_handle);
ladish_dict_handle ladish_graph_get_connection_dict(ladish_graph_handle graph_handle, uint64_t connection_id);
bool ladish_graph_add_client(ladish_graph_handle graph_handle, ladish_client_handle client_handle, const char * name, bool hidden);
void
@ -127,6 +128,7 @@ void ladish_graph_hide_port(ladish_graph_handle graph_handle, ladish_port_handle
void ladish_graph_show_client(ladish_graph_handle graph_handle, ladish_client_handle client_handle);
void ladish_graph_hide_client(ladish_graph_handle graph_handle, ladish_client_handle client_handle);
void ladish_graph_adjust_port(ladish_graph_handle graph_handle, ladish_port_handle port_handle, uint32_t type, uint32_t flags);
void ladish_graph_show_connection(ladish_graph_handle graph_handle, uint64_t connection_id);
void ladish_graph_dump(ladish_graph_handle graph_handle);
@ -157,6 +159,12 @@ ladish_graph_iterate_nodes(
const char * client_name,
void * client_iteration_context_ptr));
bool
ladish_graph_iterate_connections(
ladish_graph_handle graph_handle,
void * callback_context,
bool (* callback)(void * context, ladish_port_handle port1_handle, ladish_port_handle port2_handle, ladish_dict_handle dict));
extern const struct dbus_interface_descriptor g_interface_patchbay;
#endif /* #ifndef PATCHBAY_H__30334B9A_8847_4E8C_AFF9_73DB13406C8E__INCLUDED */

View File

@ -36,6 +36,7 @@ bool find_dict(struct dbus_method_call * call_ptr, uint32_t object_type, uint64_
{
ladish_client_handle client;
ladish_port_handle port;
ladish_dict_handle dict;
switch (object_type)
{
@ -61,7 +62,13 @@ bool find_dict(struct dbus_method_call * call_ptr, uint32_t object_type, uint64_
*dict_handle_ptr = ladish_port_get_dict(port);
return true;
case GRAPH_DICT_OBJECT_TYPE_CONNECTION:
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "find_dict() not implemented for connections.");
dict = ladish_graph_get_connection_dict(graph_handle, object_id);
if (dict == NULL)
{
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "cannot find connection %"PRIu64".", object_id);
}
*dict_handle_ptr = dict;
return false;
}

View File

@ -358,6 +358,7 @@ static void ports_connected(void * context, uint64_t client1_id, uint64_t port1_
{
ladish_port_handle port1;
ladish_port_handle port2;
uint64_t connection_id;
log_info("ports_connected %"PRIu64":%"PRIu64" %"PRIu64":%"PRIu64"", client1_id, port1_id, client2_id, port2_id);
@ -376,7 +377,17 @@ static void ports_connected(void * context, uint64_t client1_id, uint64_t port1_
}
ladish_graph_add_connection(virtualizer_ptr->jack_graph, port1, port2, false);
ladish_graph_add_connection(virtualizer_ptr->studio_graph, port1, port2, false);
if (ladish_graph_find_connection(virtualizer_ptr->studio_graph, port1, port2, &connection_id))
{
log_info("showing hidden connection");
ladish_graph_show_connection(virtualizer_ptr->studio_graph, connection_id);
}
else
{
log_info("creating new connection");
ladish_graph_add_connection(virtualizer_ptr->studio_graph, port1, port2, false);
}
}
static void ports_disconnected(void * context, uint64_t client1_id, uint64_t port1_id, uint64_t client2_id, uint64_t port2_id)