]> git.alsa-project.org Git - alsa-gobject.git/commitdiff
timer: user_instance: use two signals to dispatch events explicitly
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sun, 5 Jun 2022 03:39:24 +0000 (12:39 +0900)
committer坂本 貴史 <o-takashi@sakamocchi.jp>
Mon, 6 Jun 2022 02:14:34 +0000 (11:14 +0900)
Current implementation uses one signal to dispatch events. The user
application should distinguish actual type of event when handling the
evet. Nevertheless the type of event is decided by call of choose API,
before starting timer instance, therefore the application knows the
type of event in advance.

This commit adds two signals to dispatch the events to obsolete the
existent one signal.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
samples/timer
src/timer/user-instance.c
src/timer/user-instance.h
tests/alsatimer-user-instance

index 5f1ba574fda7f436cea42f745d352a6de6b169ab..8c50f8a4b2a604a6f7687ef434670da65ad4c8dc 100755 (executable)
@@ -14,13 +14,12 @@ instance.open(0)
 
 # Choose tstamp type of data for event and register event handler.
 instance.choose_event_data_type(ALSATimer.EventDataType.TSTAMP)
-def handle_event(instance, event):
-    data = event.get_tstamp_data()
-    tstamp = data.get_tstamp([0, 0])
+def handle_tstamp_event(instance, event):
+    tstamp = event.get_tstamp([0, 0])
     print('\nEvent at', tstamp)
-    print('  ', data.get_event().value_nick)
-    print('  ', data.get_val())
-instance.connect('handle-event', handle_event)
+    print('  ', event.get_event().value_nick)
+    print('  ', event.get_val())
+instance.connect('handle-tstamp-event', handle_tstamp_event)
 
 # Decide ALSA timer device to which the instance is attached.
 targets = (
index f3593419fabf401bd1bc3965f1292f75f6c23e9b..dd95bc352c8182c11797435811ecda78f1ee69ca 100644 (file)
@@ -59,7 +59,8 @@ typedef struct {
 } TimerUserInstanceSource;
 
 enum timer_user_instance_sig_type {
-    TIMER_USER_INSTANCE_SIG_HANDLE_EVENT = 0,
+    TIMER_USER_INSTANCE_SIG_HANDLE_TICK_EVENT = 0,
+    TIMER_USER_INSTANCE_SIG_HANDLE_TSTAMP_EVENT,
     TIMER_USER_INSTANCE_SIG_HANDLE_DISCONNECTION,
     TIMER_USER_INSTANCE_SIG_COUNT,
 };
@@ -84,20 +85,36 @@ static void alsatimer_user_instance_class_init(ALSATimerUserInstanceClass *klass
     gobject_class->finalize = timer_user_instance_finalize;
 
     /**
-     * ALSATimerUserInstance::handle-event:
+     * ALSATimerUserInstance::handle-tick-event:
      * @self: A [class@UserInstance].
-     * @event: (transfer none): The instance of [struct@Event].
+     * @event: (transfer none): The instance of [struct@EventDataTick].
      *
-     * Emitted when event occurs.
+     * Emitted when tick event occurs.
      */
-    timer_user_instance_sigs[TIMER_USER_INSTANCE_SIG_HANDLE_EVENT] =
-        g_signal_new("handle-event",
+    timer_user_instance_sigs[TIMER_USER_INSTANCE_SIG_HANDLE_TICK_EVENT] =
+        g_signal_new("handle-tick-event",
                      G_OBJECT_CLASS_TYPE(klass),
                      G_SIGNAL_RUN_LAST,
-                     G_STRUCT_OFFSET(ALSATimerUserInstanceClass, handle_event),
+                     G_STRUCT_OFFSET(ALSATimerUserInstanceClass, handle_tick_event),
                      NULL, NULL,
                      g_cclosure_marshal_VOID__BOXED,
-                     G_TYPE_NONE, 1, ALSATIMER_TYPE_EVENT);
+                     G_TYPE_NONE, 1, ALSATIMER_TYPE_EVENT_DATA_TICK);
+
+    /**
+     * ALSATimerUserInstance::handle-tstamp-event:
+     * @self: A [class@UserInstance].
+     * @event: (transfer none): The instance of [struct@EventDataTstamp].
+     *
+     * Emitted when timestamp event occurs.
+     */
+    timer_user_instance_sigs[TIMER_USER_INSTANCE_SIG_HANDLE_TSTAMP_EVENT] =
+        g_signal_new("handle-tstamp-event",
+                     G_OBJECT_CLASS_TYPE(klass),
+                     G_SIGNAL_RUN_LAST,
+                     G_STRUCT_OFFSET(ALSATimerUserInstanceClass, handle_tstamp_event),
+                     NULL, NULL,
+                     g_cclosure_marshal_VOID__BOXED,
+                     G_TYPE_NONE, 1, ALSATIMER_TYPE_EVENT_DATA_TSTAMP);
 
     /**
      * ALSATimerUserInstance::handle-disconnection:
@@ -477,6 +494,36 @@ static gboolean timer_user_instance_check_src(GSource *gsrc)
     return !!(condition & (G_IO_IN | G_IO_ERR));
 }
 
+static void dispatch_tick_events(ALSATimerUserInstance *self, const guint8 *buf, gsize length)
+{
+    const struct snd_timer_read *ev;
+
+    while (length >= sizeof(*ev)) {
+        ev = (const struct snd_timer_read *)buf;
+
+        g_signal_emit(self, timer_user_instance_sigs[TIMER_USER_INSTANCE_SIG_HANDLE_TICK_EVENT],
+                      0, ev);
+
+        length -= sizeof(*ev);
+        buf += sizeof(*ev);
+    }
+}
+
+static void dispatch_tstamp_events(ALSATimerUserInstance *self, const guint8 *buf, gsize length)
+{
+    const struct snd_timer_tread *ev;
+
+    while (length >= sizeof(*ev)) {
+        const struct snd_timer_tread *ev = (const struct snd_timer_tread *)buf;
+
+        g_signal_emit(self, timer_user_instance_sigs[TIMER_USER_INSTANCE_SIG_HANDLE_TSTAMP_EVENT],
+                      0, ev);
+
+        length -= sizeof(*ev);
+        buf += sizeof(*ev);
+    }
+}
+
 static gboolean timer_user_instance_dispatch_src(GSource *gsrc, GSourceFunc cb,
                                       gpointer user_data)
 {
@@ -484,9 +531,7 @@ static gboolean timer_user_instance_dispatch_src(GSource *gsrc, GSourceFunc cb,
     ALSATimerUserInstance *self = src->self;
     ALSATimerUserInstancePrivate *priv;
     GIOCondition condition;
-    size_t event_size;
-    int len;
-    guint8 *buf;
+    ssize_t len;
 
     priv = alsatimer_user_instance_get_instance_private(self);
     if (priv->fd < 0)
@@ -510,25 +555,13 @@ static gboolean timer_user_instance_dispatch_src(GSource *gsrc, GSourceFunc cb,
 
     switch (priv->event_data_type) {
     case ALSATIMER_EVENT_DATA_TYPE_TICK:
-        event_size = sizeof(struct snd_timer_read);
+        dispatch_tick_events(self, src->buf, (size_t)len);
         break;
     case ALSATIMER_EVENT_DATA_TYPE_TSTAMP:
-        event_size = sizeof(struct snd_timer_tread);
+        dispatch_tstamp_events(self, src->buf, (size_t)len);
         break;
     default:
-        return G_SOURCE_CONTINUE;
-    }
-
-    buf = src->buf;
-    while (len > 0) {
-        ALSATimerEvent *ev = (ALSATimerEvent *)buf;
-
-        g_signal_emit(src->self,
-                      timer_user_instance_sigs[TIMER_USER_INSTANCE_SIG_HANDLE_EVENT],
-                      0, ev);
-
-        buf += event_size;
-        len -= event_size;
+        break;
     }
 
     // Just be sure to continue to process this source.
@@ -551,8 +584,9 @@ static void timer_user_instance_finalize_src(GSource *gsrc)
  *
  * Allocate [struct@GLib.Source] structure to handle events from ALSA timer character device. In
  * each iteration of [struct@GLib.MainContext], the `read(2)` system call is executed to dispatch
- * timer event for [signal@UserInstance::handle-event] signal, according to the result of `poll(2)`
- * system call.
+ * timer event for either [signal@UserInstance::handle-tick-event] or
+ * [signal@UserInstance::handle-tstamp-event] signals, according to the result of `poll(2)` system
+ * call.
  *
  * Returns: %TRUE when the overall operation finishes successfully, else %FALSE.
  */
index 44a21e3826a010b7639c0d11474f5e90a3762acf..8645869a9017e5977a334333a415930c4b904907 100644 (file)
@@ -19,14 +19,22 @@ struct _ALSATimerUserInstanceClass {
     GObjectClass parent_class;
 
     /**
-     * ALSATimerUserInstanceClass::handle_event:
+     * ALSATimerUserInstanceClass::handle_tick_event:
      * @self: A [class@UserInstance].
-     * @event: (transfer none): An object derived from [struct@Event].
+     * @event: (transfer none): An object derived from [struct@EventDataTick].
      *
-     * Class closure for the [signal@UserInstance::handle-event] signal.
+     * Class closure for the [signal@UserInstance::handle-tick-event] signal.
      */
-    void (*handle_event)(ALSATimerUserInstance *self,
-                         const ALSATimerEvent *event);
+    void (*handle_tick_event)(ALSATimerUserInstance *self, const ALSATimerEventDataTick *event);
+
+    /**
+     * ALSATimerUserInstanceClass::handle_tstamp_event:
+     * @self: A [class@UserInstance].
+     * @event: (transfer none): An object derived from [struct@EventDataTstamp].
+     *
+     * Class closure for the [signal@UserInstance::handle-tstamp-event] signal.
+     */
+    void (*handle_tstamp_event)(ALSATimerUserInstance *self, const ALSATimerEventDataTstamp *event);
 
     /**
      * ALSATimerUserInstanceClass::handle_disconnection:
index fb34eedeec624b4a0692b41e3c5214a18c98024a..3ab54df5ec5e92205b03fbcc9c40ebba1856fed2 100644 (file)
@@ -22,7 +22,8 @@ methods = (
     'set_params',
     'get_status',
     'create_source',
-    'do_handle_event',
+    'do_handle_tick_event',
+    'do_handle_tstamp_event',
     'do_handle_disconnection',
     'start',
     'stop',
@@ -30,7 +31,8 @@ methods = (
     'continue_',
 )
 signals = (
-    'handle-event',
+    'handle-tick-event',
+    'handle-tstamp-event',
     'handle-disconnection',
 )