Излучайте детальный сигнал в Вале

У меня есть следующий исходный код C:

static guint event_signal_id;

struct _MatrixClientIface {
    void (*event)(MatrixClient *client, const gchar *room_id, const JsonNode *raw_event, MatrixEvent *event);
}

static void
matrix_client_default_init(MatrixClientIface *iface)
{
    event_signal_id = g_signal_new("event",
                                   MATRIX_TYPE_CLIENT,
                                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
                                   G_STRUCT_OFFSET(MatrixClientIface, event),
                                   NULL, NULL, _matrix_marshal_VOID__STRING_BOXED_OBJECT,
                                   G_TYPE_NONE, 3,
                                   G_TYPE_STRING,
                                   JSON_TYPE_NODE,
                                   MATRIX_TYPE_EVENT);
}

void
matrix_client_incoming_event(MatrixClient *client,
                             const gchar *room_id,
                             const JsonNode *raw_event,
                             MatrixEvent *event)
{
    GQuark equark;

    equark = g_type_qname(G_TYPE_FROM_INSTANCE(event));

    g_signal_emit(client,
                  event_signal_id, equark,
                  room_id, raw_event, event);
}

Теперь я хочу превратить это в Валу; однако я не могу найти руководство по испусканию сигналов (определение их появляется в руководствах много раз). Я нашел GLib.Signal.emit() в документах, но там нет примера того, как получить объект GLib.Signal.

Мой текущий интерфейс выглядит так:

namespace Matrix {
public interface Client : GLib.Object {
    public virtual signal void
    @event(string? room_id, Json.Node raw_event, Matrix.Event matrix_event)
    {
        Quark equark = @event.get_type().qname();

        @event.emit(room_id, raw_event, matrix_event);
    }
}

Это явно не работает. Вопросы:

  • Я вообще определяю эмиттер так, как должен?
  • Если да, то как мне на самом деле излучать сигнал event с equark в качестве детали?

person GergelyPolonkai    schedule 18.02.2016    source источник


Ответы (1)


Я не могу найти учебник по излучению сигналов (определение их много раз встречается в учебниках).

Я подозреваю, что вы действительно слышали, но упустили значение, потому что подавать сигналы так просто. Например, см. раздел "Сигналы" руководства по Vala; показано излучение (t1.sig_1(5);).

Я нашел GLib.Signal.emit() в документации, но там нет примера того, как получить объект GLib.Signal.

GLib.Signal.emit — это низкоуровневый способ передачи сигналов, и в принципе нет причин использовать его из Валы.

Обратите внимание, что первый аргумент emit является указателем. Есть несколько исключений (прежде всего libxml), но в большинстве случаев, если вы когда-либо сталкиваетесь с указателем в Vala, вы делаете что-то не так. По большей части это верно и для кварков; практически все, для чего вы использовали бы кварки, имеет синтаксическую поддержку в Vala.

Я вообще определяю эмиттер так, как должен?

Неа. Для начала избавьтесь от тела метода и «виртуала».

Если да, то как мне на самом деле передать сигнал события с помощью equark в качестве детали?

Все, что вам нужно, это что-то вроде этого:

namespace Matrix {
  public class Client : GLib.Object {
    [Signal (detailed = true)]
    public signal void @event (string? room_id, Json.Node raw_event, Matrix.Event evt);
  }

Чтобы испустить его, вы можете сделать что-то вроде:

client.@event[evt.get_type().name()](room_id, raw_event, evt);

Для подключения:

client.@event[evt.get_type().name()].connect((room_id, raw_event, evt) => {
    // Signal with a matching detail received
  });
[email protected]((room_id, raw_event, evt) => {
    // Signal received with *any* value for the detail
  });
person nemequ    schedule 18.02.2016