Move graph iteration filtering to callbacks

This commit is contained in:
Nedko Arnaudov 2010-12-24 17:43:30 +02:00
parent 1f6822c5e9
commit 1d029ffd76
7 changed files with 258 additions and 204 deletions

View File

@ -47,6 +47,7 @@ bool
ladish_check_vgraph_integrity_client_begin_callback(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
ladish_client_handle client_handle,
const char * client_name,
void ** client_iteration_context_ptr_ptr)
@ -58,6 +59,7 @@ bool
ladish_check_vgraph_integrity_port_callback(
void * context,
ladish_graph_handle vgraph,
bool hidden,
void * client_iteration_context_ptr,
ladish_client_handle client_handle,
const char * client_name,
@ -100,6 +102,7 @@ bool
ladish_check_vgraph_integrity_client_end_callback(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
ladish_client_handle client_handle,
const char * client_name,
void * client_iteration_context_ptr)
@ -113,7 +116,6 @@ bool ladish_check_vgraph_integrity(void * context, ladish_graph_handle graph, la
{
ladish_graph_iterate_nodes(
graph,
true,
context,
ladish_check_vgraph_integrity_client_begin_callback,
ladish_check_vgraph_integrity_port_callback,

View File

@ -2231,12 +2231,12 @@ ladish_graph_set_link_port_override_uuid(
bool
ladish_graph_iterate_nodes(
ladish_graph_handle graph_handle,
bool skip_hidden,
void * callback_context,
bool
(* client_begin_callback)(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
ladish_client_handle client_handle,
const char * client_name,
void ** client_iteration_context_ptr_ptr),
@ -2244,6 +2244,7 @@ ladish_graph_iterate_nodes(
(* port_callback)(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
void * client_iteration_context_ptr,
ladish_client_handle client_handle,
const char * client_name,
@ -2255,6 +2256,7 @@ ladish_graph_iterate_nodes(
(* client_end_callback)(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
ladish_client_handle client_handle,
const char * client_name,
void * client_iteration_context_ptr))
@ -2270,14 +2272,9 @@ ladish_graph_iterate_nodes(
{
client_ptr = list_entry(client_node_ptr, struct ladish_graph_client, siblings);
if (skip_hidden && client_ptr->hidden && !ladish_client_has_app(client_ptr->client))
{
continue;
}
if (client_begin_callback != NULL)
{
if (!client_begin_callback(callback_context, graph_handle, client_ptr->client, client_ptr->name, &client_context))
if (!client_begin_callback(callback_context, graph_handle, client_ptr->hidden, client_ptr->client, client_ptr->name, &client_context))
{
return false;
}
@ -2296,14 +2293,10 @@ ladish_graph_iterate_nodes(
{
port_ptr = list_entry(port_node_ptr, struct ladish_graph_port, siblings_client);
if (skip_hidden && port_ptr->hidden && !ladish_port_has_app(port_ptr->port))
{
continue;
}
if (!port_callback(
callback_context,
graph_handle,
port_ptr->hidden,
client_context,
client_ptr->client,
client_ptr->name,
@ -2318,7 +2311,7 @@ ladish_graph_iterate_nodes(
if (client_end_callback != NULL)
{
if (!client_end_callback(callback_context, graph_handle, client_ptr->client, client_ptr->name, &client_context))
if (!client_end_callback(callback_context, graph_handle, client_ptr->hidden, client_ptr->client, client_ptr->name, &client_context))
{
return false;
}
@ -2328,28 +2321,17 @@ ladish_graph_iterate_nodes(
return true;
}
static bool is_system_client(ladish_client_handle client)
{
uuid_t uuid;
ladish_client_get_uuid(client, uuid);
return ladish_virtualizer_is_system_client(uuid);
}
#define is_port_interesting(port_ptr) ( \
ladish_port_has_app(port_ptr->port) || \
ladish_port_is_link(port_ptr->port) || \
is_system_client(port_ptr->client_ptr->client) \
)
bool
ladish_graph_iterate_connections(
ladish_graph_handle graph_handle,
bool skip_hidden,
void * callback_context,
bool (* callback)(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
ladish_client_handle client1_handle,
ladish_port_handle port1_handle,
ladish_client_handle client2_handle,
ladish_port_handle port2_handle,
ladish_dict_handle dict))
{
@ -2360,15 +2342,15 @@ ladish_graph_iterate_connections(
{
connection_ptr = list_entry(node_ptr, struct ladish_graph_connection, siblings);
if (skip_hidden &&
connection_ptr->hidden &&
(!is_port_interesting(connection_ptr->port1_ptr) ||
!is_port_interesting(connection_ptr->port2_ptr)))
{
continue;
}
if (!callback(callback_context, graph_handle, connection_ptr->port1_ptr->port, connection_ptr->port2_ptr->port, connection_ptr->dict))
if (!callback(
callback_context,
graph_handle,
connection_ptr->hidden,
connection_ptr->port1_ptr->client_ptr->client,
connection_ptr->port1_ptr->port,
connection_ptr->port2_ptr->client_ptr->client,
connection_ptr->port2_ptr->port,
connection_ptr->dict))
{
return false;
}
@ -2626,6 +2608,7 @@ bool
ladish_graph_copy_client_begin_callback(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
ladish_client_handle client_handle,
const char * client_name,
void ** client_iteration_context_ptr_ptr)
@ -2653,6 +2636,7 @@ bool
ladish_graph_copy_port_callback(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
void * client_iteration_context_ptr,
ladish_client_handle client_handle,
const char * client_name,
@ -2683,7 +2667,6 @@ bool ladish_graph_copy(ladish_graph_handle src, ladish_graph_handle dest)
{
return ladish_graph_iterate_nodes(
src,
false,
dest,
ladish_graph_copy_client_begin_callback,
ladish_graph_copy_port_callback,

View File

@ -182,12 +182,12 @@ void ladish_graph_dump(ladish_graph_handle graph_handle);
bool
ladish_graph_iterate_nodes(
ladish_graph_handle graph_handle,
bool skip_hidden,
void * callback_context,
bool
(* client_begin_callback)(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
ladish_client_handle client_handle,
const char * client_name,
void ** client_iteration_context_ptr_ptr),
@ -195,6 +195,7 @@ ladish_graph_iterate_nodes(
(* port_callback)(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
void * client_iteration_context_ptr,
ladish_client_handle client_handle,
const char * client_name,
@ -206,6 +207,7 @@ ladish_graph_iterate_nodes(
(* client_end_callback)(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
ladish_client_handle client_handle,
const char * client_name,
void * client_iteration_context_ptr));
@ -213,12 +215,14 @@ ladish_graph_iterate_nodes(
bool
ladish_graph_iterate_connections(
ladish_graph_handle graph_handle,
bool skip_hidden,
void * callback_context,
bool (* callback)(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
ladish_client_handle client1_handle,
ladish_port_handle port1_handle,
ladish_client_handle client2_handle,
ladish_port_handle port2_handle,
ladish_dict_handle dict));

View File

@ -287,6 +287,7 @@ bool
interlink_client(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
ladish_client_handle jclient,
const char * name,
void ** client_iteration_context_ptr_ptr)
@ -369,5 +370,5 @@ void ladish_interlink_clients(ladish_graph_handle vgraph, ladish_app_supervisor_
ctx.vgraph = vgraph;
ctx.app_supervisor = app_supervisor;
ladish_graph_iterate_nodes(ladish_studio_get_jack_graph(), false, &ctx, interlink_client, NULL, NULL);
ladish_graph_iterate_nodes(ladish_studio_get_jack_graph(), &ctx, interlink_client, NULL, NULL);
}

View File

@ -208,6 +208,7 @@ bool
destroy_port_link(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
void * client_iteration_context_ptr,
ladish_client_handle client_handle,
const char * client_name,
@ -470,6 +471,7 @@ bool
ladish_room_iterate_link_ports_client_callback(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
ladish_client_handle client_handle,
const char * client_name,
void ** client_iteration_context_ptr_ptr)
@ -496,6 +498,7 @@ bool
ladish_room_iterate_link_ports_port_callback(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
void * client_iteration_context_ptr,
ladish_client_handle client_handle,
const char * client_name,
@ -534,7 +537,6 @@ ladish_room_iterate_link_ports(
return ladish_graph_iterate_nodes(
room_ptr->graph,
false,
&context,
ladish_room_iterate_link_ports_client_callback,
ladish_room_iterate_link_ports_port_callback,
@ -571,7 +573,7 @@ void ladish_room_initiate_stop(ladish_room_handle room_handle, bool clear_persis
ladish_graph_clear_persist(room_ptr->graph);
}
ladish_graph_iterate_nodes(room_ptr->graph, false, room_ptr, NULL, destroy_port_link, NULL);
ladish_graph_iterate_nodes(room_ptr->graph, room_ptr, NULL, destroy_port_link, NULL);
ladish_app_supervisor_stop(room_ptr->app_supervisor);
}

View File

@ -30,6 +30,26 @@
#include "escape.h"
#include "studio.h"
struct ladish_write_vgraph_context
{
int fd;
int indent;
bool client_visible;
};
static bool is_system_client(ladish_client_handle client)
{
uuid_t uuid;
ladish_client_get_uuid(client, uuid);
return ladish_virtualizer_is_system_client(uuid);
}
#define is_port_interesting(client, port) ( \
ladish_port_has_app(port) || \
ladish_port_is_link(port) || \
is_system_client(client) \
)
bool ladish_write_string(int fd, const char * string)
{
size_t len;
@ -135,11 +155,172 @@ write_dict_entry(
return true;
}
static
bool
ladish_write_room_port(
void * context,
ladish_port_handle port,
const char * name,
uint32_t type,
uint32_t flags)
{
uuid_t uuid;
char str[37];
bool midi;
const char * type_str;
bool playback;
const char * direction_str;
ladish_dict_handle dict;
ladish_port_get_uuid(port, uuid);
uuid_unparse(uuid, str);
playback = (flags & JACKDBUS_PORT_FLAG_INPUT) != 0;
ASSERT(playback || (flags & JACKDBUS_PORT_FLAG_OUTPUT) != 0); /* playback or capture */
ASSERT(!(playback && (flags & JACKDBUS_PORT_FLAG_OUTPUT) != 0)); /* but not both */
direction_str = playback ? "playback" : "capture";
midi = type == JACKDBUS_PORT_TYPE_MIDI;
ASSERT(midi || type == JACKDBUS_PORT_TYPE_AUDIO); /* midi or audio */
ASSERT(!(midi && type == JACKDBUS_PORT_TYPE_AUDIO)); /* but not both */
type_str = midi ? "midi" : "audio";
log_info("saving room %s %s port '%s' (%s)", direction_str, type_str, name, str);
if (!ladish_write_indented_string(fd, indent, "<port name=\""))
{
return false;
}
if (!ladish_write_string_escape_ex(fd, name, LADISH_ESCAPE_FLAG_XML_ATTR))
{
return false;
}
if (!ladish_write_string(fd, "\" uuid=\""))
{
return false;
}
if (!ladish_write_string(fd, str))
{
return false;
}
if (!ladish_write_string(fd, "\" type=\""))
{
return false;
}
if (!ladish_write_string(fd, type_str))
{
return false;
}
if (!ladish_write_string(fd, "\" direction=\""))
{
return false;
}
if (!ladish_write_string(fd, direction_str))
{
return false;
}
dict = ladish_port_get_dict(port);
if (ladish_dict_is_empty(dict))
{
if (!ladish_write_string(fd, "\" />\n"))
{
return false;
}
}
else
{
if (!ladish_write_string(fd, "\">\n"))
{
return false;
}
if (!ladish_write_dict(fd, indent + 1, dict))
{
return false;
}
if (!ladish_write_indented_string(fd, indent, "</port>\n"))
{
return false;
}
}
return true;
}
#undef indent
#undef fd
bool ladish_write_dict(int fd, int indent, ladish_dict_handle dict)
{
struct ladish_write_context context;
if (ladish_dict_is_empty(dict))
{
return true;
}
context.fd = fd;
context.indent = indent + 1;
if (!ladish_write_indented_string(fd, indent, "<dict>\n"))
{
return false;
}
if (!ladish_dict_iterate(dict, &context, write_dict_entry))
{
return false;
}
if (!ladish_write_indented_string(fd, indent, "</dict>\n"))
{
return false;
}
return true;
}
bool ladish_write_room_link_ports(int fd, int indent, ladish_room_handle room)
{
struct ladish_write_context context;
ladish_check_integrity();
context.fd = fd;
context.indent = indent;
if (!ladish_room_iterate_link_ports(room, &context, ladish_write_room_port))
{
log_error("ladish_room_iterate_link_ports() failed");
return false;
}
return true;
}
/****************/
/* write vgraph */
/****************/
#define fd (((struct ladish_write_vgraph_context *)context)->fd)
#define indent (((struct ladish_write_vgraph_context *)context)->indent)
#define ctx_ptr ((struct ladish_write_vgraph_context *)context)
static
bool
ladish_save_vgraph_client_begin(
void * context,
ladish_graph_handle graph,
bool hidden,
ladish_client_handle client_handle,
const char * client_name,
void ** client_iteration_context_ptr_ptr)
@ -147,6 +328,12 @@ ladish_save_vgraph_client_begin(
uuid_t uuid;
char str[37];
ctx_ptr->client_visible = !hidden || ladish_client_has_app(client_handle);
if (!ctx_ptr->client_visible)
{
return true;
}
ladish_client_get_uuid(client_handle, uuid);
uuid_unparse(uuid, str);
@ -200,10 +387,16 @@ bool
ladish_save_vgraph_client_end(
void * context,
ladish_graph_handle graph,
bool hidden,
ladish_client_handle client_handle,
const char * client_name,
void * client_iteration_context_ptr)
{
if (!ctx_ptr->client_visible)
{
return true;
}
if (!ladish_write_indented_string(fd, indent + 1, "</ports>\n"))
{
return false;
@ -254,6 +447,7 @@ bool
ladish_save_vgraph_port(
void * context,
ladish_graph_handle graph,
bool hidden,
void * client_iteration_context_ptr,
ladish_client_handle client_handle,
const char * client_name,
@ -269,6 +463,11 @@ ladish_save_vgraph_port(
char link_str[37];
ladish_dict_handle dict;
if (!ctx_ptr->client_visible)
{
return true;
}
link = ladish_get_vgraph_port_uuids(graph, port_handle, uuid, link_uuid);
uuid_unparse(uuid, str);
if (link)
@ -368,13 +567,23 @@ bool
ladish_save_vgraph_connection(
void * context,
ladish_graph_handle graph,
ladish_port_handle port1_handle,
ladish_port_handle port2_handle,
bool hidden,
ladish_client_handle client1,
ladish_port_handle port1,
ladish_client_handle client2,
ladish_port_handle port2,
ladish_dict_handle dict)
{
uuid_t uuid;
char str[37];
if (hidden &&
(!is_port_interesting(client1, port1) ||
!is_port_interesting(client2, port2)))
{
return true;
}
log_info("saving vgraph connection");
if (!ladish_write_indented_string(fd, indent, "<connection port1=\""))
@ -382,7 +591,7 @@ ladish_save_vgraph_connection(
return false;
}
ladish_get_vgraph_port_uuids(graph, port1_handle, uuid, NULL);
ladish_get_vgraph_port_uuids(graph, port1, uuid, NULL);
uuid_unparse(uuid, str);
if (!ladish_write_string(fd, str))
@ -395,7 +604,7 @@ ladish_save_vgraph_connection(
return false;
}
ladish_get_vgraph_port_uuids(graph, port2_handle, uuid, NULL);
ladish_get_vgraph_port_uuids(graph, port2, uuid, NULL);
uuid_unparse(uuid, str);
if (!ladish_write_string(fd, str))
@ -534,143 +743,13 @@ exit:
return ret;
}
static
bool
ladish_write_room_port(
void * context,
ladish_port_handle port,
const char * name,
uint32_t type,
uint32_t flags)
{
uuid_t uuid;
char str[37];
bool midi;
const char * type_str;
bool playback;
const char * direction_str;
ladish_dict_handle dict;
ladish_port_get_uuid(port, uuid);
uuid_unparse(uuid, str);
playback = (flags & JACKDBUS_PORT_FLAG_INPUT) != 0;
ASSERT(playback || (flags & JACKDBUS_PORT_FLAG_OUTPUT) != 0); /* playback or capture */
ASSERT(!(playback && (flags & JACKDBUS_PORT_FLAG_OUTPUT) != 0)); /* but not both */
direction_str = playback ? "playback" : "capture";
midi = type == JACKDBUS_PORT_TYPE_MIDI;
ASSERT(midi || type == JACKDBUS_PORT_TYPE_AUDIO); /* midi or audio */
ASSERT(!(midi && type == JACKDBUS_PORT_TYPE_AUDIO)); /* but not both */
type_str = midi ? "midi" : "audio";
log_info("saving room %s %s port '%s' (%s)", direction_str, type_str, name, str);
if (!ladish_write_indented_string(fd, indent, "<port name=\""))
{
return false;
}
if (!ladish_write_string_escape_ex(fd, name, LADISH_ESCAPE_FLAG_XML_ATTR))
{
return false;
}
if (!ladish_write_string(fd, "\" uuid=\""))
{
return false;
}
if (!ladish_write_string(fd, str))
{
return false;
}
if (!ladish_write_string(fd, "\" type=\""))
{
return false;
}
if (!ladish_write_string(fd, type_str))
{
return false;
}
if (!ladish_write_string(fd, "\" direction=\""))
{
return false;
}
if (!ladish_write_string(fd, direction_str))
{
return false;
}
dict = ladish_port_get_dict(port);
if (ladish_dict_is_empty(dict))
{
if (!ladish_write_string(fd, "\" />\n"))
{
return false;
}
}
else
{
if (!ladish_write_string(fd, "\">\n"))
{
return false;
}
if (!ladish_write_dict(fd, indent + 1, dict))
{
return false;
}
if (!ladish_write_indented_string(fd, indent, "</port>\n"))
{
return false;
}
}
return true;
}
#undef ctx_ptr
#undef indent
#undef fd
bool ladish_write_dict(int fd, int indent, ladish_dict_handle dict)
{
struct ladish_write_context context;
if (ladish_dict_is_empty(dict))
{
return true;
}
context.fd = fd;
context.indent = indent + 1;
if (!ladish_write_indented_string(fd, indent, "<dict>\n"))
{
return false;
}
if (!ladish_dict_iterate(dict, &context, write_dict_entry))
{
return false;
}
if (!ladish_write_indented_string(fd, indent, "</dict>\n"))
{
return false;
}
return true;
}
bool ladish_write_vgraph(int fd, int indent, ladish_graph_handle vgraph, ladish_app_supervisor_handle app_supervisor)
{
struct ladish_write_context context;
struct ladish_write_vgraph_context context;
ladish_check_integrity();
@ -684,7 +763,6 @@ bool ladish_write_vgraph(int fd, int indent, ladish_graph_handle vgraph, ladish_
if (!ladish_graph_iterate_nodes(
vgraph,
true,
&context,
ladish_save_vgraph_client_begin,
ladish_save_vgraph_port,
@ -704,7 +782,7 @@ bool ladish_write_vgraph(int fd, int indent, ladish_graph_handle vgraph, ladish_
return false;
}
if (!ladish_graph_iterate_connections(vgraph, true, &context, ladish_save_vgraph_connection))
if (!ladish_graph_iterate_connections(vgraph, &context, ladish_save_vgraph_connection))
{
log_error("ladish_graph_iterate_connections() failed");
return false;
@ -733,24 +811,6 @@ bool ladish_write_vgraph(int fd, int indent, ladish_graph_handle vgraph, ladish_
return true;
}
bool ladish_write_room_link_ports(int fd, int indent, ladish_room_handle room)
{
struct ladish_write_context context;
ladish_check_integrity();
context.fd = fd;
context.indent = indent;
if (!ladish_room_iterate_link_ports(room, &context, ladish_write_room_port))
{
log_error("ladish_room_iterate_link_ports() failed");
return false;
}
return true;
}
/********************/
/* write jack graph */
/********************/
@ -817,6 +877,7 @@ bool
ladish_save_jack_client_begin(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
ladish_client_handle client_handle,
const char * client_name,
void ** client_iteration_context_ptr_ptr)
@ -830,8 +891,7 @@ ladish_save_jack_client_begin(
/* for the a2j client vgraph is always the studio graph.
However if studio has no a2j ports, lets not write a2j client.
If there is a a2j port that matched the vgraph, the prolog will get written anyway */
ctx_ptr->client_visible = ctx_ptr->client_vgraph_match && !ctx_ptr->a2j;
ctx_ptr->client_visible = ctx_ptr->client_vgraph_match && !ctx_ptr->a2j && ladish_client_has_app(client_handle);
if (!ctx_ptr->client_visible)
{
return true;
@ -845,6 +905,7 @@ bool
ladish_save_jack_client_end(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
ladish_client_handle client_handle,
const char * client_name,
void * client_iteration_context_ptr)
@ -872,6 +933,7 @@ bool
ladish_save_jack_port(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
void * client_iteration_context_ptr,
ladish_client_handle client_handle,
const char * client_name,
@ -884,7 +946,7 @@ ladish_save_jack_port(
char str[37];
/* check vgraph for a2j ports */
if (ctx_ptr->a2j && ctx_ptr->vgraph_filter == ladish_port_get_vgraph(port_handle))
if (ctx_ptr->a2j && ctx_ptr->vgraph_filter == ladish_port_get_vgraph(port_handle) && ladish_port_has_app(port_handle))
{
if (!ctx_ptr->client_visible)
{
@ -956,7 +1018,6 @@ bool ladish_write_jgraph(int fd, int indent, ladish_graph_handle vgraph)
if (!ladish_graph_iterate_nodes(
ladish_studio_get_jack_graph(),
true,
&context,
ladish_save_jack_client_begin,
ladish_save_jack_port,

View File

@ -1223,6 +1223,7 @@ bool
remove_app_port(
void * context,
ladish_graph_handle graph_handle,
bool hidden,
void * client_iteration_context_ptr,
ladish_client_handle client_handle,
const char * client_name,
@ -1293,7 +1294,7 @@ ladish_virtualizer_remove_app(
uuid_copy(ctx.app_uuid, app_uuid);
ctx.app_name = app_name;
ladish_graph_iterate_nodes(jack_graph, false, &ctx, NULL, remove_app_port, NULL);
ladish_graph_iterate_nodes(jack_graph, &ctx, NULL, remove_app_port, NULL);
jclient = ladish_graph_find_client_by_app(jack_graph, app_uuid);
if (jclient == NULL)