+2005-09-29 Wim Taymans <wim@fluendo.com>
+
+ * check/gst/gstbin.c: (GST_START_TEST):
+ Change for new bus API.
+
+ * check/gst/gstbus.c: (message_func_eos), (message_func_app),
+ (send_messages), (GST_START_TEST), (gstbus_suite):
+ Change for new bus signal API.
+
+ * gst/gstbus.c: (gst_bus_class_init), (gst_bus_have_pending),
+ (gst_bus_source_prepare), (gst_bus_source_check),
+ (gst_bus_create_watch), (gst_bus_add_watch_full),
+ (gst_bus_add_watch), (gst_bus_poll), (gst_bus_async_signal_func),
+ (gst_bus_sync_signal_handler), (gst_bus_add_signal_watch):
+ * gst/gstbus.h:
+ Remove support for multiple GSources operating on different
+ message types as it is too complex and unneeded when using
+ signals.
+ Added support for receiving signals from the bus.
+
2005-09-29 Thomas Vander Stichele <thomas at apestaart dot org>
* docs/libs/tmpl/gstdataprotocol.sgml:
pop_messages (bus, 5);
- fail_unless (gst_bus_have_pending (bus, GST_MESSAGE_ANY) == FALSE,
+ fail_unless (gst_bus_have_pending (bus) == FALSE,
"Unexpected messages on bus");
gst_bin_watch_for_state_change (GST_BIN (bin));
/* should get the bin's state change message now */
pop_messages (bus, 1);
- fail_unless (gst_bus_have_pending (bus, GST_MESSAGE_ANY) == FALSE,
+ fail_unless (gst_bus_have_pending (bus) == FALSE,
"Unexpected messages on bus");
fail_unless (gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING)
pop_messages (bus, 3);
- fail_unless (gst_bus_have_pending (bus, GST_MESSAGE_ANY) == FALSE,
+ fail_unless (gst_bus_have_pending (bus) == FALSE,
"Unexpected messages on bus");
/* setting bin to NULL flushes the bus automatically */
return FALSE;
}
-/* test id adding two watches for different message types calls the
+/* test if adding a signal watch for different message types calls the
* respective callbacks. */
GST_START_TEST (test_watch)
{
- guint id1, id2;
+ guint id;
test_bus = gst_bus_new ();
main_loop = g_main_loop_new (NULL, FALSE);
- id2 = gst_bus_add_watch (test_bus, GST_MESSAGE_EOS, message_func_eos, NULL);
- id1 =
- gst_bus_add_watch (test_bus, GST_MESSAGE_APPLICATION, message_func_app,
+ id = gst_bus_add_watch (test_bus, gst_bus_async_signal_func, NULL);
+ g_signal_connect (test_bus, "message::eos", (GCallback) message_func_eos,
NULL);
+ g_signal_connect (test_bus, "message::application",
+ (GCallback) message_func_app, NULL);
g_idle_add ((GSourceFunc) send_messages, NULL);
while (g_main_context_pending (NULL))
g_main_context_iteration (NULL, FALSE);
- g_source_remove (id1);
- g_source_remove (id2);
+ g_source_remove (id);
g_main_loop_unref (main_loop);
gst_object_unref ((GstObject *) test_bus);
marshal_VOID__MINIOBJECT, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
/**
- * GstBus::async-message:
+ * GstBus::message:
* @bus: the object which received the signal
* @message: the message that has been posted asynchronously
*
* GSource added to the mainloop.
*/
gst_bus_signals[ASYNC_MESSAGE] =
- g_signal_new ("async-message", G_TYPE_FROM_CLASS (klass),
+ g_signal_new ("message", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
- G_STRUCT_OFFSET (GstBusClass, async_message), NULL, NULL,
+ G_STRUCT_OFFSET (GstBusClass, message), NULL, NULL,
marshal_VOID__MINIOBJECT, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
}
/**
* gst_bus_have_pending:
* @bus: a #GstBus to check
- * @events: a mask of #GstMessageType, representing the set of message types to
- * watch for.
*
- * Check if there are pending messages on the bus of the given types that
+ * Check if there are pending messages on the bus that
* should be handled.
*
* Returns: TRUE if there are messages on the bus to be handled.
* MT safe.
*/
gboolean
-gst_bus_have_pending (GstBus * bus, GstMessageType events)
+gst_bus_have_pending (GstBus * bus)
{
- GstMessage *message;
gboolean result;
g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
g_mutex_lock (bus->queue_lock);
- /* see if there is a message on the bus that satisfies the
- * event mask */
- message = g_queue_peek_head (bus->queue);
- if (message)
- result = (GST_MESSAGE_TYPE (message) & events) != 0;
- else
- result = FALSE;
+ /* see if there is a message on the bus */
+ result = !g_queue_is_empty (bus->queue);
g_mutex_unlock (bus->queue_lock);
return result;
{
GSource source;
GstBus *bus;
- GstMessageType events;
} GstBusSource;
static gboolean
GstBusSource *bsrc = (GstBusSource *) source;
*timeout = -1;
- return gst_bus_have_pending (bsrc->bus, bsrc->events);
+ return gst_bus_have_pending (bsrc->bus);
}
static gboolean
{
GstBusSource *bsrc = (GstBusSource *) source;
- return gst_bus_have_pending (bsrc->bus, bsrc->events);
+ return gst_bus_have_pending (bsrc->bus);
}
static gboolean
/**
* gst_bus_create_watch:
* @bus: a #GstBus to create the watch for
- * @events: a mask of #GstMessageType, representing the set of message types to
- * watch for.
*
- * Create watch for this bus. The source will only act on messages of the
- * given types, messages of other types will simply remain on the bus and
- * this GSource will not be dispatched again before the message is popped off
- * the bus. For this reason one typically has a low priority GSource that
- * pops all remaining messages from the bus not handled by the other GSources.
+ * Create watch for this bus. The GSource will be dispatched whenever
+ * a message is on the bus. After the GSource is dispatched, the
+ * message is popped off the bus and unreffed.
*
* Returns: A #GSource that can be added to a mainloop.
*/
GSource *
-gst_bus_create_watch (GstBus * bus, GstMessageType events)
+gst_bus_create_watch (GstBus * bus)
{
GstBusSource *source;
sizeof (GstBusSource));
gst_object_ref (bus);
source->bus = bus;
- source->events = events;
return (GSource *) source;
}
* gst_bus_add_watch_full:
* @bus: a #GstBus to create the watch for.
* @priority: The priority of the watch.
- * @events: a mask of #GstMessageType, representing the set of message types to
- * watch for.
* @func: A function to call when a message is received.
* @user_data: user data passed to @func.
* @notify: the function to call when the source is removed.
* MT safe.
*/
guint
-gst_bus_add_watch_full (GstBus * bus, gint priority, GstMessageType events,
+gst_bus_add_watch_full (GstBus * bus, gint priority,
GstBusFunc func, gpointer user_data, GDestroyNotify notify)
{
guint id;
g_return_val_if_fail (GST_IS_BUS (bus), 0);
- source = gst_bus_create_watch (bus, events);
+ source = gst_bus_create_watch (bus);
if (priority != G_PRIORITY_DEFAULT)
g_source_set_priority (source, priority);
/**
* gst_bus_add_watch:
* @bus: a #GstBus to create the watch for
- * @events: a mask of #GstMessageType, representing the set of message types to
- * watch for.
* @func: A function to call when a message is received.
* @user_data: user data passed to @func.
*
* MT safe.
*/
guint
-gst_bus_add_watch (GstBus * bus, GstMessageType events, GstBusFunc func,
- gpointer user_data)
+gst_bus_add_watch (GstBus * bus, GstBusFunc func, gpointer user_data)
{
- return gst_bus_add_watch_full (bus, G_PRIORITY_DEFAULT, events, func,
+ return gst_bus_add_watch_full (bus, G_PRIORITY_DEFAULT, func,
user_data, NULL);
}
else
poll_data->timeout_id = 0;
- id = gst_bus_add_watch_full (bus, G_PRIORITY_DEFAULT, GST_MESSAGE_ANY,
+ id = gst_bus_add_watch_full (bus, G_PRIORITY_DEFAULT,
(GstBusFunc) poll_func, poll_data, (GDestroyNotify) poll_destroy);
GST_DEBUG ("running mainloop %p", poll_data->loop);
{
GQuark detail = 0;
+ g_return_val_if_fail (GST_IS_BUS (bus), TRUE);
+ g_return_val_if_fail (message != NULL, TRUE);
+
detail = gst_message_type_to_quark (GST_MESSAGE_TYPE (message));
g_signal_emit (bus, gst_bus_signals[ASYNC_MESSAGE], detail, message);
{
GQuark detail = 0;
+ g_return_val_if_fail (GST_IS_BUS (bus), GST_BUS_DROP);
+ g_return_val_if_fail (message != NULL, GST_BUS_DROP);
+
detail = gst_message_type_to_quark (GST_MESSAGE_TYPE (message));
g_signal_emit (bus, gst_bus_signals[SYNC_MESSAGE], detail, message);
return GST_BUS_PASS;
}
+
+/**
+ * gst_bus_add_signal_watch:
+ * @bus: a #GstBus to create the watch for
+ *
+ * Adds a bus signal watch to the default main context with the default priority.
+ * After calling this statement, the bus will emit the message signal for each
+ * message posted on the bus.
+ *
+ * The watch can be removed using #g_source_remove().
+ *
+ * Returns: The event source id.
+ *
+ * MT safe.
+ */
+guint
+gst_bus_add_signal_watch (GstBus * bus)
+{
+ g_return_val_if_fail (GST_IS_BUS (bus), 0);
+
+ return gst_bus_add_watch (bus, gst_bus_async_signal_func, NULL);
+}
GstObjectClass parent_class;
/* signals */
- void (*sync_message) (GstBus *bus, GstMessage *message);
- void (*async_message) (GstBus *bus, GstMessage *message);
+ void (*message) (GstBus *bus, GstMessage *message);
+ void (*sync_message) (GstBus *bus, GstMessage *message);
/*< private > */
gpointer _gst_reserved[GST_PADDING];
gboolean gst_bus_post (GstBus * bus, GstMessage * message);
-gboolean gst_bus_have_pending (GstBus * bus, GstMessageType events);
+gboolean gst_bus_have_pending (GstBus * bus);
GstMessage * gst_bus_peek (GstBus * bus);
GstMessage * gst_bus_pop (GstBus * bus);
void gst_bus_set_flushing (GstBus * bus, gboolean flushing);
void gst_bus_set_sync_handler (GstBus * bus, GstBusSyncHandler func,
gpointer data);
/* GSource based dispatching */
-GSource * gst_bus_create_watch (GstBus * bus, GstMessageType events);
+GSource * gst_bus_create_watch (GstBus * bus);
guint gst_bus_add_watch_full (GstBus * bus,
gint priority,
- GstMessageType events,
GstBusFunc func,
gpointer user_data,
GDestroyNotify notify);
guint gst_bus_add_watch (GstBus * bus,
- GstMessageType events,
GstBusFunc func,
gpointer user_data);
gpointer data);
GstBusSyncReply gst_bus_sync_signal_handler (GstBus *bus, GstMessage *message,
gpointer data);
+/* add watch that dispatches signals */
+guint gst_bus_add_signal_watch (GstBus * bus);
G_END_DECLS
pop_messages (bus, 5);
- fail_unless (gst_bus_have_pending (bus, GST_MESSAGE_ANY) == FALSE,
+ fail_unless (gst_bus_have_pending (bus) == FALSE,
"Unexpected messages on bus");
gst_bin_watch_for_state_change (GST_BIN (bin));
/* should get the bin's state change message now */
pop_messages (bus, 1);
- fail_unless (gst_bus_have_pending (bus, GST_MESSAGE_ANY) == FALSE,
+ fail_unless (gst_bus_have_pending (bus) == FALSE,
"Unexpected messages on bus");
fail_unless (gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING)
pop_messages (bus, 3);
- fail_unless (gst_bus_have_pending (bus, GST_MESSAGE_ANY) == FALSE,
+ fail_unless (gst_bus_have_pending (bus) == FALSE,
"Unexpected messages on bus");
/* setting bin to NULL flushes the bus automatically */
return FALSE;
}
-/* test id adding two watches for different message types calls the
+/* test if adding a signal watch for different message types calls the
* respective callbacks. */
GST_START_TEST (test_watch)
{
- guint id1, id2;
+ guint id;
test_bus = gst_bus_new ();
main_loop = g_main_loop_new (NULL, FALSE);
- id2 = gst_bus_add_watch (test_bus, GST_MESSAGE_EOS, message_func_eos, NULL);
- id1 =
- gst_bus_add_watch (test_bus, GST_MESSAGE_APPLICATION, message_func_app,
+ id = gst_bus_add_watch (test_bus, gst_bus_async_signal_func, NULL);
+ g_signal_connect (test_bus, "message::eos", (GCallback) message_func_eos,
NULL);
+ g_signal_connect (test_bus, "message::application",
+ (GCallback) message_func_app, NULL);
g_idle_add ((GSourceFunc) send_messages, NULL);
while (g_main_context_pending (NULL))
g_main_context_iteration (NULL, FALSE);
- g_source_remove (id1);
- g_source_remove (id2);
+ g_source_remove (id);
g_main_loop_unref (main_loop);
gst_object_unref ((GstObject *) test_bus);