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> 2005-09-28 Stefan Kost <ensonic@users.sf.net>
* docs/libs/gstreamer-libs-sections.txt: * docs/libs/gstreamer-libs-sections.txt:

View file

@ -68,6 +68,14 @@
#include "gstbus.h" #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_class_init (GstBusClass * klass);
static void gst_bus_init (GstBus * bus); 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); GValue * value, GParamSpec * pspec);
static GstObjectClass *parent_class = NULL; static GstObjectClass *parent_class = NULL;
static guint gst_bus_signals[LAST_SIGNAL] = { 0 };
/* static guint gst_bus_signals[LAST_SIGNAL] = { 0 }; */
GType GType
gst_bus_get_type (void) gst_bus_get_type (void)
@ -106,6 +113,34 @@ gst_bus_get_type (void)
return bus_type; 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 static void
gst_bus_class_init (GstBusClass * klass) 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->dispose = GST_DEBUG_FUNCPTR (gst_bus_dispose);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_bus_set_property); gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_bus_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_bus_get_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 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_BUS (bus), FALSE);
g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE); g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE);
GST_DEBUG_OBJECT (bus, "[msg %p] posting on bus, type %d", GST_DEBUG_OBJECT (bus, "[msg %p] posting on bus, type %s",
message, GST_MESSAGE_TYPE (message)); message, gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
GST_LOCK (bus); GST_LOCK (bus);
/* check if the bus is flushing */ /* check if the bus is flushing */
@ -382,6 +445,7 @@ gst_bus_set_flushing (GstBus * bus, gboolean flushing)
GST_UNLOCK (bus); GST_UNLOCK (bus);
} }
/** /**
* gst_bus_pop: * gst_bus_pop:
* @bus: a #GstBus to 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); poll_data->message = gst_message_ref (message);
GST_DEBUG ("mainloop %p quit", poll_data->loop); GST_DEBUG ("mainloop %p quit", poll_data->loop);
g_main_loop_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 /* we always keep the source alive so that we don't accidentialy
* free the poll_data */ * free the poll_data */
return TRUE; 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 * specify a maximum time to poll with the @timeout parameter. If @timeout is
* negative, this function will block indefinitely. * 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. * This function will enter the default mainloop while polling.
* *
* Returns: The message that was received, or NULL if the poll timed out. * 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; 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; GstObjectClass parent_class;
/* signals */
void (*sync_message) (GstBus *bus, GstMessage *message);
void (*async_message) (GstBus *bus, GstMessage *message);
/*< private > */ /*< private > */
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING];
}; };
@ -117,9 +121,10 @@ GstMessage * gst_bus_peek (GstBus * bus);
GstMessage * gst_bus_pop (GstBus * bus); GstMessage * gst_bus_pop (GstBus * bus);
void gst_bus_set_flushing (GstBus * bus, gboolean flushing); void gst_bus_set_flushing (GstBus * bus, gboolean flushing);
/* synchronous dispatching */
void gst_bus_set_sync_handler (GstBus * bus, GstBusSyncHandler func, void gst_bus_set_sync_handler (GstBus * bus, GstBusSyncHandler func,
gpointer data); gpointer data);
/* GSource based dispatching */
GSource * gst_bus_create_watch (GstBus * bus, GstMessageType events); GSource * gst_bus_create_watch (GstBus * bus, GstMessageType events);
guint gst_bus_add_watch_full (GstBus * bus, guint gst_bus_add_watch_full (GstBus * bus,
gint priority, gint priority,
@ -132,9 +137,16 @@ guint gst_bus_add_watch (GstBus * bus,
GstBusFunc func, GstBusFunc func,
gpointer user_data); gpointer user_data);
/* polling the bus */
GstMessage* gst_bus_poll (GstBus *bus, GstMessageType events, GstMessage* gst_bus_poll (GstBus *bus, GstMessageType events,
GstClockTimeDiff timeout); 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 G_END_DECLS
#endif /* __GST_BUS_H__ */ #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 void gst_message_finalize (GstMessage * message);
static GstMessage *_gst_message_copy (GstMessage * message); static GstMessage *_gst_message_copy (GstMessage * message);
void void
_gst_message_initialize (void) _gst_message_initialize (void)
{ {
@ -64,12 +63,63 @@ _gst_message_initialize (void)
g_type_class_unref (ptr); 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 GType
gst_message_get_type (void) gst_message_get_type (void)
{ {
static GType _gst_message_type; static GType _gst_message_type;
if (G_UNLIKELY (_gst_message_type == 0)) { if (G_UNLIKELY (_gst_message_type == 0)) {
gint i;
static const GTypeInfo message_info = { static const GTypeInfo message_info = {
sizeof (GstMessageClass), sizeof (GstMessageClass),
NULL, NULL,
@ -85,6 +135,11 @@ gst_message_get_type (void)
_gst_message_type = g_type_register_static (GST_TYPE_MINI_OBJECT, _gst_message_type = g_type_register_static (GST_TYPE_MINI_OBJECT,
"GstMessage", &message_info, 0); "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; return _gst_message_type;
} }

View file

@ -127,6 +127,9 @@ void _gst_message_initialize (void);
GType gst_message_get_type (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 */ /* refcounting */
#define gst_message_ref(msg) GST_MESSAGE (gst_mini_object_ref (GST_MINI_OBJECT (msg))) #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)) #define gst_message_unref(msg) gst_mini_object_unref (GST_MINI_OBJECT (msg))