daemon: load studios with rooms

This commit is contained in:
Nedko Arnaudov 2010-07-21 05:53:48 +03:00
parent 5bb96d51e7
commit 00cc1087dc
7 changed files with 467 additions and 115 deletions

View File

@ -52,6 +52,8 @@
#define PARSE_CONTEXT_CONNECTION 12
#define PARSE_CONTEXT_APPLICATIONS 13
#define PARSE_CONTEXT_APPLICATION 14
#define PARSE_CONTEXT_ROOMS 15
#define PARSE_CONTEXT_ROOM 16
#define MAX_STACK_DEPTH 10
#define MAX_DATA_SIZE 10240
@ -67,13 +69,14 @@ struct parse_context
ladish_client_handle client;
ladish_port_handle port;
ladish_dict_handle dict;
ladish_room_handle room;
uint64_t connection_id;
bool terminal;
bool autorun;
uint8_t level;
};
static const char * get_string_attribute(const char * const * attr, const char * key)
static const char * get_string_attribute_internal(const char * const * attr, const char * key, bool optional)
{
while (attr[0] != NULL)
{
@ -85,15 +88,24 @@ static const char * get_string_attribute(const char * const * attr, const char *
attr += 2;
}
log_error("attribute \"%s\" is missing");
if (!optional)
{
log_error("attribute \"%s\" is missing", key);
}
return NULL;
}
static const char * get_uuid_attribute(const char * const * attr, const char * key, uuid_t uuid)
static const char * get_string_attribute(const char * const * attr, const char * key)
{
return get_string_attribute_internal(attr, key, false);
}
static const char * get_uuid_attribute(const char * const * attr, const char * key, uuid_t uuid, bool optional)
{
const char * value;
value = get_string_attribute(attr, key);
value = get_string_attribute_internal(attr, key, optional);
if (value == NULL)
{
return NULL;
@ -183,7 +195,7 @@ get_name_and_uuid_attributes(
return false;
}
uuid_str = get_uuid_attribute(attr, "uuid", uuid);
uuid_str = get_uuid_attribute(attr, "uuid", uuid, false);
if (uuid_str == NULL)
{
log_error("%s \"uuid\" attribute is not available. name=\"%s\"", element_description, name_str);
@ -195,6 +207,134 @@ get_name_and_uuid_attributes(
return true;
}
static
bool
parse_port_type_and_direction_attributes(
const char * element_description,
const char * const * attr,
uint32_t * type_ptr,
uint32_t * flags_ptr)
{
const char * type_str;
const char * direction_str;
type_str = get_string_attribute(attr, "type");
if (type_str == NULL)
{
log_error("%s \"type\" attribute is not available", element_description);
return false;
}
direction_str = get_string_attribute(attr, "direction");
if (direction_str == NULL)
{
log_error("%s \"direction\" attribute is not available", element_description);
return false;
}
if (strcmp(type_str, "midi") == 0)
{
*type_ptr = JACKDBUS_PORT_TYPE_MIDI;
}
else if (strcmp(type_str, "audio") == 0)
{
*type_ptr = JACKDBUS_PORT_TYPE_AUDIO;
}
else
{
log_error("%s \"type\" attribute contains unknown value \"%s\"", element_description, type_str);
return false;
}
if (strcmp(direction_str, "playback") == 0)
{
*flags_ptr = 0;
JACKDBUS_PORT_SET_INPUT(*flags_ptr);
}
else if (strcmp(direction_str, "capture") == 0)
{
*flags_ptr = 0;
JACKDBUS_PORT_SET_OUTPUT(*flags_ptr);
}
else
{
log_error("%s \"direction\" attribute contains unknown value \"%s\"", element_description, direction_str);
return false;
}
return true;
}
static void dump_element_stack(struct parse_context * context_ptr)
{
signed int depth;
const char * descr;
log_info("depth=%d", context_ptr->depth);
for (depth = context_ptr->depth; depth >= 0; depth--)
{
switch (context_ptr->element[depth])
{
case PARSE_CONTEXT_ROOT:
descr = "root";
break;
case PARSE_CONTEXT_STUDIO:
descr = "studio";
break;
case PARSE_CONTEXT_JACK:
descr = "jack";
break;
case PARSE_CONTEXT_CONF:
descr = "conf";
break;
case PARSE_CONTEXT_PARAMETER:
descr = "parameter";
break;
case PARSE_CONTEXT_CLIENTS:
descr = "clients";
break;
case PARSE_CONTEXT_CLIENT:
descr = "client";
break;
case PARSE_CONTEXT_PORTS:
descr = "ports";
break;
case PARSE_CONTEXT_PORT:
descr = "port";
break;
case PARSE_CONTEXT_DICT:
descr = "dict";
break;
case PARSE_CONTEXT_KEY:
descr = "key";
break;
case PARSE_CONTEXT_CONNECTIONS:
descr = "connections";
break;
case PARSE_CONTEXT_CONNECTION:
descr = "connection";
break;
case PARSE_CONTEXT_APPLICATIONS:
descr = "applications";
break;
case PARSE_CONTEXT_APPLICATION:
descr = "application";
break;
case PARSE_CONTEXT_ROOMS:
descr = "rooms";
break;
case PARSE_CONTEXT_ROOM:
descr = "room";
break;
default:
descr = "?";
}
log_info("%d - %u (%s)", depth, context_ptr->element[depth], descr);
}
}
#define context_ptr ((struct parse_context *)data)
static void callback_chrdata(void * data, const XML_Char * s, int len)
@ -230,6 +370,8 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
uuid_t uuid2;
ladish_port_handle port1;
ladish_port_handle port2;
uint32_t port_type;
uint32_t port_flags;
if (context_ptr->error)
{
@ -295,6 +437,50 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
return;
}
if (strcmp(el, "rooms") == 0)
{
//log_info("<rooms>");
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_ROOMS;
return;
}
if (strcmp(el, "room") == 0)
{
//log_info("<room>");
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_ROOM;
if (context_ptr->room != NULL)
{
log_error("nested rooms");
context_ptr->error = XML_TRUE;
return;
}
if (context_ptr->depth == 2 &&
context_ptr->element[0] == PARSE_CONTEXT_STUDIO &&
context_ptr->element[1] == PARSE_CONTEXT_ROOMS)
{
if (!get_name_and_uuid_attributes("/studio/rooms/room", attr, &name, &uuid_str, uuid))
{
context_ptr->error = XML_TRUE;
return;
}
if (!ladish_room_create(uuid, name, NULL, g_studio.studio_graph, &context_ptr->room))
{
log_error("ladish_room_create() failed.");
context_ptr->error = XML_TRUE;
ASSERT(context_ptr->room == NULL);
return;
}
return;
}
log_error("ignoring <room> element in wrong context");
return;
}
if (strcmp(el, "client") == 0)
{
//log_info("<client>");
@ -349,6 +535,13 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
log_info("studio client \"%s\" with uuid %s", name, uuid_str);
context_ptr->client = ladish_graph_find_client_by_uuid(g_studio.studio_graph, uuid);
if (context_ptr->client != NULL)
{
log_info("Found existing client");
return;
}
if (!ladish_client_create(uuid, &context_ptr->client))
{
log_error("ladish_client_create() failed.");
@ -389,73 +582,125 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
return;
}
if (context_ptr->client == NULL)
if (context_ptr->depth >= 3 &&
context_ptr->element[context_ptr->depth - 3] == PARSE_CONTEXT_CLIENTS &&
context_ptr->element[context_ptr->depth - 2] == PARSE_CONTEXT_CLIENT &&
context_ptr->element[context_ptr->depth - 1] == PARSE_CONTEXT_PORTS)
{
//log_info("client port");
if (context_ptr->client == NULL)
{
log_error("client-less port");
context_ptr->error = XML_TRUE;
return;
}
if (context_ptr->depth == 5 &&
context_ptr->element[0] == PARSE_CONTEXT_STUDIO &&
context_ptr->element[1] == PARSE_CONTEXT_JACK &&
context_ptr->element[2] == PARSE_CONTEXT_CLIENTS &&
context_ptr->element[3] == PARSE_CONTEXT_CLIENT &&
context_ptr->element[4] == PARSE_CONTEXT_PORTS)
{
if (!get_name_and_uuid_attributes("/studio/jack/clients/client/ports/port", attr, &name, &uuid_str, uuid))
{
context_ptr->error = XML_TRUE;
return;
}
log_info("jack port \"%s\" with uuid %s", name, uuid_str);
if (!ladish_port_create(uuid, false, &context_ptr->port))
if (context_ptr->depth == 5 && context_ptr->element[0] == PARSE_CONTEXT_STUDIO && context_ptr->element[1] == PARSE_CONTEXT_JACK)
{
log_error("ladish_port_create() failed.");
if (!get_name_and_uuid_attributes("/studio/jack/clients/client/ports/port", attr, &name, &uuid_str, uuid))
{
context_ptr->error = XML_TRUE;
return;
}
log_info("jack port \"%s\" with uuid %s", name, uuid_str);
if (!ladish_port_create(uuid, false, &context_ptr->port))
{
log_error("ladish_port_create() failed.");
return;
}
if (!ladish_graph_add_port(g_studio.jack_graph, context_ptr->client, context_ptr->port, name, 0, 0, true))
{
log_error("ladish_graph_add_port() failed.");
ladish_port_destroy(context_ptr->port);
context_ptr->port = NULL;
}
return;
}
if (!ladish_graph_add_port(g_studio.jack_graph, context_ptr->client, context_ptr->port, name, 0, 0, true))
else if (context_ptr->depth == 4 && context_ptr->element[0] == PARSE_CONTEXT_STUDIO)
{
log_error("ladish_graph_add_port() failed.");
ladish_port_destroy(context_ptr->port);
context_ptr->port = NULL;
if (!get_name_and_uuid_attributes("/studio/clients/client/ports/port", attr, &name, &uuid_str, uuid))
{
context_ptr->error = XML_TRUE;
return;
}
uuid2_str = get_uuid_attribute(attr, "link_uuid", uuid2, true);
log_info("studio port \"%s\" with uuid %s (%s)", name, uuid_str, uuid_str == NULL ? "normal" : "room link");
if (uuid2_str == NULL)
{ /* normal studio port */
context_ptr->port = ladish_graph_find_port_by_uuid(g_studio.jack_graph, uuid, false);
if (context_ptr->port == NULL)
{
log_error("studio client with non-jack port %s", uuid_str);
context_ptr->error = XML_TRUE;
return;
}
if (!ladish_graph_add_port(g_studio.studio_graph, context_ptr->client, context_ptr->port, name, 0, 0, true))
{
log_error("ladish_graph_add_port() failed.");
ladish_port_destroy(context_ptr->port);
context_ptr->port = NULL;
return;
}
return;
}
/* room link port */
context_ptr->port = ladish_graph_find_port_by_uuid(g_studio.studio_graph, uuid2, false);
if (context_ptr->port == NULL)
{
log_error("room link port not found");
context_ptr->port = NULL;
}
ladish_graph_set_link_port_override_uuid(g_studio.studio_graph, uuid2, uuid);
return;
}
}
else if (context_ptr->depth == 4 &&
else if (context_ptr->depth == 3 &&
context_ptr->element[0] == PARSE_CONTEXT_STUDIO &&
context_ptr->element[1] == PARSE_CONTEXT_CLIENTS &&
context_ptr->element[2] == PARSE_CONTEXT_CLIENT &&
context_ptr->element[3] == PARSE_CONTEXT_PORTS)
context_ptr->element[1] == PARSE_CONTEXT_ROOMS &&
context_ptr->element[2] == PARSE_CONTEXT_ROOM)
{
if (!get_name_and_uuid_attributes("/studio/clients/client/ports/port", attr, &name, &uuid_str, uuid))
ASSERT(context_ptr->room != NULL);
//log_info("room port");
if (!get_name_and_uuid_attributes("/studio/rooms/room/port", attr, &name, &uuid_str, uuid))
{
context_ptr->error = XML_TRUE;
return;
}
log_info("studio port \"%s\" with uuid %s", name, uuid_str);
log_info("room port \"%s\" with uuid %s", name, uuid_str);
context_ptr->port = ladish_graph_find_port_by_uuid(g_studio.jack_graph, uuid, false);
if (!parse_port_type_and_direction_attributes("/studio/rooms/room/port", attr, &port_type, &port_flags))
{
context_ptr->error = XML_TRUE;
return;
}
context_ptr->port = ladish_room_add_port(context_ptr->room, uuid, name, port_type, port_flags);
if (context_ptr->port == NULL)
{
log_error("studio client with non-jack port %s", uuid_str);
context_ptr->error = XML_TRUE;
return;
log_error("ladish_room_add_port() failed.");
context_ptr->port = NULL;
}
if (!ladish_graph_add_port(g_studio.studio_graph, context_ptr->client, context_ptr->port, name, 0, 0, true))
{
log_error("ladish_graph_add_port() failed.");
ladish_port_destroy(context_ptr->port);
context_ptr->port = NULL;
return;
}
return;
}
log_error("port element in wrong place");
dump_element_stack(context_ptr);
context_ptr->error = XML_TRUE;
return;
}
@ -471,7 +716,7 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
//log_info("<connection>");
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_CONNECTION;
uuid_str = get_uuid_attribute(attr, "port1", uuid);
uuid_str = get_uuid_attribute(attr, "port1", uuid, false);
if (uuid_str == NULL)
{
log_error("/studio/connections/connection \"port1\" attribute is not available.");
@ -479,7 +724,7 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
return;
}
uuid2_str = get_uuid_attribute(attr, "port2", uuid2);
uuid2_str = get_uuid_attribute(attr, "port2", uuid2, false);
if (uuid2_str == NULL)
{
log_error("/studio/connections/connection \"port2\" attribute is not available.");
@ -489,7 +734,7 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
log_info("studio connection between port %s and port %s", uuid_str, uuid2_str);
port1 = ladish_graph_find_port_by_uuid(g_studio.studio_graph, uuid, false);
port1 = ladish_graph_find_port_by_uuid(g_studio.studio_graph, uuid, true);
if (port1 == NULL)
{
log_error("studio client with unknown port %s", uuid_str);
@ -497,7 +742,7 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
return;
}
port2 = ladish_graph_find_port_by_uuid(g_studio.studio_graph, uuid2, false);
port2 = ladish_graph_find_port_by_uuid(g_studio.studio_graph, uuid2, true);
if (port2 == NULL)
{
log_error("studio client with unknown port %s", uuid2_str);
@ -800,6 +1045,12 @@ static void callback_elend(void * data, const char * el)
return;
}
}
else if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_ROOM)
{
//log_info("</room>");
ASSERT(context_ptr->room != NULL);
context_ptr->room = NULL;
}
else if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_DICT)
{
//log_info("</dict>");
@ -979,6 +1230,7 @@ static bool run(void * command_context)
parse_context.client = NULL;
parse_context.port = NULL;
parse_context.dict = NULL;
parse_context.room = NULL;
XML_SetElementHandler(parser, callback_elstart, callback_elend);
XML_SetCharacterDataHandler(parser, callback_chrdata);

View File

@ -135,9 +135,9 @@ create_room_template_port(
bool playback;
ladish_client_handle client;
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 */
playback = JACKDBUS_PORT_IS_INPUT(flags);
ASSERT(playback || JACKDBUS_PORT_IS_OUTPUT(flags)); /* playback or capture */
ASSERT(!(playback && JACKDBUS_PORT_IS_OUTPUT(flags))); /* but not both */
client = playback ? room_descriptor_ptr->playback : room_descriptor_ptr->capture;
if (!ladish_port_create(uuid_ptr, true, &port))

View File

@ -101,6 +101,49 @@ static struct ladish_graph_port * ladish_graph_find_port_by_id_internal(struct l
return NULL;
}
static struct ladish_graph_port *
ladish_graph_find_port_by_uuid_internal(
struct ladish_graph * graph_ptr,
const uuid_t uuid,
bool use_link_override_uuids)
{
struct list_head * node_ptr;
struct ladish_graph_port * port_ptr;
uuid_t current_uuid;
/* char uuid1_str[37]; */
/* char uuid2_str[37]; */
/* log_info("searching by uuid for port in graph %s", ladish_graph_get_description(graph_handle)); */
/* uuid_unparse(uuid, uuid1_str); */
list_for_each(node_ptr, &graph_ptr->ports)
{
port_ptr = list_entry(node_ptr, struct ladish_graph_port, siblings_graph);
/* if (port_ptr->link) */
/* { */
/* uuid_unparse(port_ptr->link_uuid_override, uuid2_str); */
/* log_info("comparing link uuid %s with %s", uuid2_str, uuid1_str); */
/* } */
if (use_link_override_uuids && port_ptr->link && uuid_compare(port_ptr->link_uuid_override, uuid) == 0)
{
/* log_info("found port %p of client '%s'", port_ptr->port, port_ptr->client_ptr->name); */
return port_ptr;
}
ladish_port_get_uuid(port_ptr->port, current_uuid);
/* uuid_unparse(current_uuid, uuid2_str); */
/* log_info("comparing port uuid %s with %s", uuid2_str, uuid1_str); */
if (uuid_compare(current_uuid, uuid) == 0)
{
return port_ptr;
}
}
return NULL;
}
static struct ladish_graph_connection * ladish_graph_find_connection_by_id(struct ladish_graph * graph_ptr, uint64_t connection_id)
{
struct list_head * node_ptr;
@ -1607,38 +1650,12 @@ ladish_client_handle ladish_graph_find_client_by_uuid(ladish_graph_handle graph_
ladish_port_handle ladish_graph_find_port_by_uuid(ladish_graph_handle graph_handle, const uuid_t uuid, bool use_link_override_uuids)
{
struct list_head * node_ptr;
struct ladish_graph_port * port_ptr;
uuid_t current_uuid;
/* char uuid1_str[37]; */
/* char uuid2_str[37]; */
/* log_info("searching by uuid for port in graph %s", ladish_graph_get_description(graph_handle)); */
/* uuid_unparse(uuid, uuid1_str); */
list_for_each(node_ptr, &graph_ptr->ports)
port_ptr = ladish_graph_find_port_by_uuid_internal(graph_ptr, uuid, use_link_override_uuids);
if (port_ptr != NULL)
{
port_ptr = list_entry(node_ptr, struct ladish_graph_port, siblings_graph);
/* if (port_ptr->link) */
/* { */
/* uuid_unparse(port_ptr->link_uuid_override, uuid2_str); */
/* log_info("comparing link uuid %s with %s", uuid2_str, uuid1_str); */
/* } */
if (port_ptr->link && uuid_compare(port_ptr->link_uuid_override, uuid) == 0)
{
/* log_info("found port %p of client '%s'", port_ptr->port, port_ptr->client_ptr->name); */
return port_ptr->port;
}
ladish_port_get_uuid(port_ptr->port, current_uuid);
/* uuid_unparse(current_uuid, uuid2_str); */
/* log_info("comparing port uuid %s with %s", uuid2_str, uuid1_str); */
if (uuid_compare(current_uuid, uuid) == 0)
{
return port_ptr->port;
}
return port_ptr->port;
}
return NULL;
@ -2025,6 +2042,15 @@ const char * ladish_graph_get_port_name(ladish_graph_handle graph_handle, ladish
return port_ptr->name;
}
void ladish_graph_set_link_port_override_uuid(ladish_graph_handle graph_handle, const uuid_t uuid, const uuid_t override_uuid)
{
struct ladish_graph_port * port_ptr;
port_ptr = ladish_graph_find_port_by_uuid_internal(graph_ptr, uuid, false);
ASSERT(ladish_port_is_link(port_ptr->port));
uuid_copy(port_ptr->link_uuid_override, override_uuid);
}
bool
ladish_graph_iterate_nodes(
ladish_graph_handle graph_handle,

View File

@ -159,6 +159,7 @@ void ladish_graph_show_connection(ladish_graph_handle graph_handle, uint64_t con
void ladish_try_connect_hidden_connections(ladish_graph_handle graph_handle);
void ladish_graph_hide_non_virtual(ladish_graph_handle graph_handle);
void ladish_graph_get_port_uuid(ladish_graph_handle graph, ladish_port_handle port, uuid_t uuid_ptr);
void ladish_graph_set_link_port_override_uuid(ladish_graph_handle graph_handle, const uuid_t uuid, const uuid_t override_uuid);
void ladish_graph_dump(ladish_graph_handle graph_handle);

View File

@ -54,22 +54,15 @@ extern const struct dbus_interface_descriptor g_interface_room;
/* implemented in studio.c */
void ladish_on_app_renamed(void * context, const char * old_name, const char * new_app_name);
static bool get_port_direction(uint32_t port_flags, bool * room_input_ptr)
static bool port_is_input(uint32_t flags)
{
if (JACKDBUS_PORT_IS_INPUT(port_flags))
{
*room_input_ptr = true;
return true;
}
bool playback;
if (JACKDBUS_PORT_IS_OUTPUT(port_flags))
{
*room_input_ptr = false;
return true;
}
playback = JACKDBUS_PORT_IS_INPUT(flags);
ASSERT(playback || JACKDBUS_PORT_IS_OUTPUT(flags)); /* playback or capture */
ASSERT(!(playback && JACKDBUS_PORT_IS_OUTPUT(flags))); /* but not both */
log_error("room link port with bad flags %"PRIu32, port_flags);
return false;
return playback;
}
struct ladish_room * ladish_room_create_internal(const uuid_t uuid_ptr, const char * name, const char * object_path)
@ -145,16 +138,9 @@ create_shadow_port(
uint32_t port_type,
uint32_t port_flags)
{
bool room_input;
//log_info("Studio room port \"%s\"", port_name);
if (!get_port_direction(port_flags, &room_input))
{
return false;
}
if (room_input)
if (port_is_input(port_flags))
{
JACKDBUS_PORT_CLEAR_INPUT(port_flags);
JACKDBUS_PORT_SET_OUTPUT(port_flags);
@ -187,24 +173,18 @@ create_port_link(
uuid_t uuid_in_room;
char uuid_in_owner_str[37];
char uuid_in_room_str[37];
bool room_input;
const char * input_port;
const char * output_port;
//log_info("Room port \"%s\"", port_name);
if (!get_port_direction(port_flags, &room_input))
{
return false;
}
ladish_graph_get_port_uuid(room_ptr->graph, port_handle, uuid_in_room);
ladish_graph_get_port_uuid(room_ptr->owner, port_handle, uuid_in_owner);
uuid_unparse(uuid_in_room, uuid_in_room_str);
uuid_unparse(uuid_in_owner, uuid_in_owner_str);
if (room_input)
if (port_is_input(port_flags))
{
input_port = uuid_in_room_str;
output_port = uuid_in_owner_str;
@ -301,13 +281,20 @@ ladish_room_create(
}
room_ptr->index = index;
ladish_room_get_uuid(template, room_ptr->template_uuid);
room_ptr->owner = owner;
room_ptr->started = false;
if (!ladish_graph_copy(ladish_room_get_graph(template), room_ptr->graph, false))
if (template != NULL)
{
goto destroy;
ladish_room_get_uuid(template, room_ptr->template_uuid);
if (!ladish_graph_copy(ladish_room_get_graph(template), room_ptr->graph, false))
{
goto destroy;
}
}
else
{
uuid_clear(room_ptr->template_uuid);
}
if (!ladish_app_supervisor_create(&room_ptr->app_supervisor, object_path, room_ptr->name, room_ptr->graph, ladish_on_app_renamed))
@ -399,11 +386,11 @@ void ladish_room_destroy(ladish_room_handle room_handle)
ladish_graph_remove_client(room_ptr->owner, room_ptr->client);
ladish_client_destroy(room_ptr->client);
ladish_studio_room_disappeared((ladish_room_handle)room_ptr);
ladish_studio_release_room_index(room_ptr->index);
}
ladish_studio_room_disappeared((ladish_room_handle)room_ptr);
ladish_studio_release_room_index(room_ptr->index);
ladish_graph_destroy(room_ptr->graph);
free(room_ptr->name);
free(room_ptr);
@ -603,6 +590,82 @@ bool ladish_room_stopped(ladish_room_handle room_handle)
return true;
}
ladish_port_handle
ladish_room_add_port(
ladish_room_handle room_handle,
const uuid_t uuid_ptr,
const char * name,
uint32_t type,
uint32_t flags)
{
ladish_port_handle port;
bool playback;
ladish_client_handle client;
const char * client_name;
uuid_t client_uuid;
bool new_client;
playback = port_is_input(flags);
ASSERT(!uuid_is_null(uuid_ptr));
if (!ladish_port_create(uuid_ptr, true, &port))
{
log_error("Creation of room port \"%s\" failed.", name);
goto fail;
}
client_name = playback ? "Playback" : "Capture";
uuid_copy(client_uuid, playback ? ladish_wkclient_playback : ladish_wkclient_capture);
/* if client is not found, create it and add it to graph */
client = ladish_graph_find_client_by_uuid(room_ptr->graph, client_uuid);
new_client = client == NULL;
if (new_client)
{
if (!ladish_client_create(client_uuid, &client))
{
log_error("ladish_client_create() failed to create %s room client.", playback ? "playback" : "capture");
goto fail_destroy_port;
}
if (!ladish_graph_add_client(room_ptr->graph, client, client_name, true))
{
log_error("ladish_graph_add_client() failed to add %s room client to room graph.", playback ? "playback" : "capture");
goto fail_destroy_client;
}
}
if (!ladish_graph_add_port(room_ptr->graph, client, port, name, type, flags, true))
{
log_error("ladish_graph_add_port() failed to add %s room port \"%s\" to room graph.", playback ? "playback" : "capture", name);
goto fail_destroy_client;
}
if (!create_shadow_port(room_ptr, port, name, type, flags))
{
log_error("ladish_graph_add_port() failed to add port \"%s\" to room owner graph.", name);
goto fail_remove_port;
}
return port;
fail_remove_port:
ASSERT(client != NULL);
if (ladish_graph_remove_port(room_ptr->graph, port) != client)
{
ASSERT_NO_PASS;
}
fail_destroy_client:
if (new_client)
{
ladish_client_destroy(client);
}
fail_destroy_port:
ladish_port_destroy(port);
fail:
return NULL;
}
#undef room_ptr
ladish_room_handle ladish_room_from_list_node(struct list_head * node_ptr)

View File

@ -78,4 +78,12 @@ bool ladish_room_start(ladish_room_handle room_handle, ladish_virtualizer_handle
void ladish_room_initiate_stop(ladish_room_handle room_handle, bool clear_persist);
bool ladish_room_stopped(ladish_room_handle room_handle);
ladish_port_handle
ladish_room_add_port(
ladish_room_handle room_handle,
const uuid_t uuid_ptr,
const char * name,
uint32_t type,
uint32_t flags);
#endif /* #ifndef ROOM_H__9A1CF253_0A17_402A_BDF8_9BD72B467118__INCLUDED */

View File

@ -229,12 +229,14 @@ void ladish_studio_emit_room_disappeared(ladish_room_handle room)
void ladish_studio_room_appeared(ladish_room_handle room)
{
log_info("Room \"%s\" appeared", ladish_room_get_name(room));
list_add_tail(ladish_room_get_list_node(room), &g_studio.rooms);
ladish_studio_emit_room_appeared(room);
}
void ladish_studio_room_disappeared(ladish_room_handle room)
{
log_info("Room \"%s\" disappeared", ladish_room_get_name(room));
list_del(ladish_room_get_list_node(room));
ladish_studio_emit_room_disappeared(room);
}