gst/gstbus.*: Added async-message and sync-message signals to the bus.

Original commit message from CVS:
* gst/gstbus.c: (marshal_VOID__MINIOBJECT), (gst_bus_class_init),
(gst_bus_post), (poll_func), (gst_bus_async_signal_func),
(gst_bus_sync_signal_handler):
* gst/gstbus.h:
Added async-message and sync-message signals to the bus.
Added helper BusFunc to emit signals for all posted messages.

* gst/gstmessage.c: (gst_message_type_get_name),
(gst_message_type_to_quark), (gst_message_get_type):
* gst/gstmessage.h:
Register quarks for message names.
This commit is contained in:
Wim Taymans 2005-09-28 16:43:20 +00:00
parent d6b67a4dd8
commit bf443a4639
5 changed files with 204 additions and 8 deletions

View file

@ -1,3 +1,17 @@
2005-09-28 Wim Taymans <wim@fluendo.com>
* gst/gstbus.c: (marshal_VOID__MINIOBJECT), (gst_bus_class_init),
(gst_bus_post), (poll_func), (gst_bus_async_signal_func),
(gst_bus_sync_signal_handler):
* gst/gstbus.h:
Added async-message and sync-message signals to the bus.
Added helper BusFunc to emit signals for all posted messages.
* gst/gstmessage.c: (gst_message_type_get_name),
(gst_message_type_to_quark), (gst_message_get_type):
* gst/gstmessage.h:
Register quarks for message names.
2005-09-28 Stefan Kost <ensonic@users.sf.net>
* docs/libs/gstreamer-libs-sections.txt:

View file

@ -68,6 +68,14 @@
#include "gstbus.h"
/* bus signals */
enum
{
SYNC_MESSAGE,
ASYNC_MESSAGE,
/* add more above */
LAST_SIGNAL
};
static void gst_bus_class_init (GstBusClass * klass);
static void gst_bus_init (GstBus * bus);
@ -79,8 +87,7 @@ static void gst_bus_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstObjectClass *parent_class = NULL;
/* static guint gst_bus_signals[LAST_SIGNAL] = { 0 }; */
static guint gst_bus_signals[LAST_SIGNAL] = { 0 };
GType
gst_bus_get_type (void)
@ -106,6 +113,34 @@ gst_bus_get_type (void)
return bus_type;
}
/* fixme: do something about this */
static void
marshal_VOID__MINIOBJECT (GClosure * closure, GValue * return_value,
guint n_param_values, const GValue * param_values, gpointer invocation_hint,
gpointer marshal_data)
{
typedef void (*marshalfunc_VOID__MINIOBJECT) (gpointer obj, gpointer arg1,
gpointer data2);
register marshalfunc_VOID__MINIOBJECT callback;
register GCClosure *cc = (GCClosure *) closure;
register gpointer data1, data2;
g_return_if_fail (n_param_values == 2);
if (G_CCLOSURE_SWAP_DATA (closure)) {
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
} else {
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
callback =
(marshalfunc_VOID__MINIOBJECT) (marshal_data ? marshal_data : cc->
callback);
callback (data1, gst_value_get_mini_object (param_values + 1), data2);
}
static void
gst_bus_class_init (GstBusClass * klass)
{
@ -123,6 +158,34 @@ gst_bus_class_init (GstBusClass * klass)
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_bus_dispose);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_bus_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_bus_get_property);
/**
* GstBus::sync-message:
* @bus: the object which received the signal
* @message: the message that has been posted synchronously
*
* A message has been posted on the bus. This signal is emited from the
* thread that posted the message so one has to be carefull with locking.
*/
gst_bus_signals[SYNC_MESSAGE] =
g_signal_new ("sync-message", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
G_STRUCT_OFFSET (GstBusClass, sync_message), NULL, NULL,
marshal_VOID__MINIOBJECT, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
/**
* GstBus::async-message:
* @bus: the object which received the signal
* @message: the message that has been posted asynchronously
*
* A message has been posted on the bus. This signal is emited from a
* GSource added to the mainloop.
*/
gst_bus_signals[ASYNC_MESSAGE] =
g_signal_new ("async-message", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
G_STRUCT_OFFSET (GstBusClass, async_message), NULL, NULL,
marshal_VOID__MINIOBJECT, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
}
static void
@ -231,8 +294,8 @@ gst_bus_post (GstBus * bus, GstMessage * message)
g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE);
GST_DEBUG_OBJECT (bus, "[msg %p] posting on bus, type %d",
message, GST_MESSAGE_TYPE (message));
GST_DEBUG_OBJECT (bus, "[msg %p] posting on bus, type %s",
message, gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
GST_LOCK (bus);
/* check if the bus is flushing */
@ -382,6 +445,7 @@ gst_bus_set_flushing (GstBus * bus, gboolean flushing)
GST_UNLOCK (bus);
}
/**
* gst_bus_pop:
* @bus: a #GstBus to pop
@ -671,9 +735,8 @@ poll_func (GstBus * bus, GstMessage * message, GstBusPollData * poll_data)
poll_data->message = gst_message_ref (message);
GST_DEBUG ("mainloop %p quit", poll_data->loop);
g_main_loop_quit (poll_data->loop);
} else {
/* don't remove the source. */
}
/* we always keep the source alive so that we don't accidentialy
* free the poll_data */
return TRUE;
@ -721,6 +784,8 @@ poll_destroy_timeout (GstBusPollData * poll_data)
* specify a maximum time to poll with the @timeout parameter. If @timeout is
* negative, this function will block indefinitely.
*
* All messages not in @events will be popped off the bus and will be ignored.
*
* This function will enter the default mainloop while polling.
*
* Returns: The message that was received, or NULL if the poll timed out.
@ -765,3 +830,50 @@ gst_bus_poll (GstBus * bus, GstMessageType events, GstClockTimeDiff timeout)
return ret;
}
/**
* gst_bus_async_signal_func:
* @bus: a #GstBus
* @message: the message received
* @data: user data
*
* A helper GstBusFunc that can be used to convert all asynchronous messages
* into signals.
*
* Returns: TRUE
*/
gboolean
gst_bus_async_signal_func (GstBus * bus, GstMessage * message, gpointer data)
{
GQuark detail = 0;
detail = gst_message_type_to_quark (GST_MESSAGE_TYPE (message));
g_signal_emit (bus, gst_bus_signals[ASYNC_MESSAGE], detail, message);
/* we never remove this source based on signal emission return values */
return TRUE;
}
/**
* gst_bus_sync_signal_handler:
* @bus: a #GstBus
* @message: the message received
* @data: user data
*
* A helper GstBusSyncHandler that can be used to convert all synchronous
* messages into signals.
*
* Returns: GST_BUS_PASS
*/
GstBusSyncReply
gst_bus_sync_signal_handler (GstBus * bus, GstMessage * message, gpointer data)
{
GQuark detail = 0;
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;
}

View file

@ -102,6 +102,10 @@ struct _GstBusClass
{
GstObjectClass parent_class;
/* signals */
void (*sync_message) (GstBus *bus, GstMessage *message);
void (*async_message) (GstBus *bus, GstMessage *message);
/*< private > */
gpointer _gst_reserved[GST_PADDING];
};
@ -117,9 +121,10 @@ GstMessage * gst_bus_peek (GstBus * bus);
GstMessage * gst_bus_pop (GstBus * bus);
void gst_bus_set_flushing (GstBus * bus, gboolean flushing);
/* synchronous dispatching */
void gst_bus_set_sync_handler (GstBus * bus, GstBusSyncHandler func,
gpointer data);
/* GSource based dispatching */
GSource * gst_bus_create_watch (GstBus * bus, GstMessageType events);
guint gst_bus_add_watch_full (GstBus * bus,
gint priority,
@ -132,9 +137,16 @@ guint gst_bus_add_watch (GstBus * bus,
GstBusFunc func,
gpointer user_data);
/* polling the bus */
GstMessage* gst_bus_poll (GstBus *bus, GstMessageType events,
GstClockTimeDiff timeout);
/* signal based dispatching helper functions. */
gboolean gst_bus_async_signal_func (GstBus *bus, GstMessage *message,
gpointer data);
GstBusSyncReply gst_bus_sync_signal_handler (GstBus *bus, GstMessage *message,
gpointer data);
G_END_DECLS
#endif /* __GST_BUS_H__ */

View file

@ -47,7 +47,6 @@ static void gst_message_class_init (gpointer g_class, gpointer class_data);
static void gst_message_finalize (GstMessage * message);
static GstMessage *_gst_message_copy (GstMessage * message);
void
_gst_message_initialize (void)
{
@ -64,12 +63,63 @@ _gst_message_initialize (void)
g_type_class_unref (ptr);
}
typedef struct
{
gint type;
gchar *name;
GQuark quark;
} GstMessageQuarks;
static GstMessageQuarks message_quarks[] = {
{GST_MESSAGE_UNKNOWN, "unknown", 0},
{GST_MESSAGE_EOS, "eos", 0},
{GST_MESSAGE_ERROR, "error", 0},
{GST_MESSAGE_WARNING, "warning", 0},
{GST_MESSAGE_INFO, "info", 0},
{GST_MESSAGE_TAG, "tag", 0},
{GST_MESSAGE_BUFFERING, "buffering", 0},
{GST_MESSAGE_STATE_CHANGED, "state-changed", 0},
{GST_MESSAGE_STEP_DONE, "step-done", 0},
{GST_MESSAGE_NEW_CLOCK, "new-clock", 0},
{GST_MESSAGE_STRUCTURE_CHANGE, "structure-change", 0},
{GST_MESSAGE_STREAM_STATUS, "stream-status", 0},
{GST_MESSAGE_APPLICATION, "application", 0},
{GST_MESSAGE_SEGMENT_START, "segment-start", 0},
{GST_MESSAGE_SEGMENT_DONE, "segment-done", 0},
{0, NULL, 0}
};
const gchar *
gst_message_type_get_name (GstMessageType type)
{
gint i;
for (i = 0; message_quarks[i].name; i++) {
if (type == message_quarks[i].type)
return message_quarks[i].name;
}
return "unknown";
}
GQuark
gst_message_type_to_quark (GstMessageType type)
{
gint i;
for (i = 0; message_quarks[i].name; i++) {
if (type == message_quarks[i].type)
return message_quarks[i].quark;
}
return 0;
}
GType
gst_message_get_type (void)
{
static GType _gst_message_type;
if (G_UNLIKELY (_gst_message_type == 0)) {
gint i;
static const GTypeInfo message_info = {
sizeof (GstMessageClass),
NULL,
@ -85,6 +135,11 @@ gst_message_get_type (void)
_gst_message_type = g_type_register_static (GST_TYPE_MINI_OBJECT,
"GstMessage", &message_info, 0);
for (i = 0; message_quarks[i].name; i++) {
message_quarks[i].quark =
g_quark_from_static_string (message_quarks[i].name);
}
}
return _gst_message_type;
}

View file

@ -127,6 +127,9 @@ void _gst_message_initialize (void);
GType gst_message_get_type (void);
const gchar* gst_message_type_get_name (GstMessageType type);
GQuark gst_message_type_to_quark (GstMessageType type);
/* refcounting */
#define gst_message_ref(msg) GST_MESSAGE (gst_mini_object_ref (GST_MINI_OBJECT (msg)))
#define gst_message_unref(msg) gst_mini_object_unref (GST_MINI_OBJECT (msg))