在 Vala 中发出详细的信号

Emit detailed signal in Vala

我有以下原始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);
}

现在我想把它转换成Vala;但是,我找不到关于 emitting 信号的教程(定义它们多次出现在教程中)。我在文档中找到 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);
    }
}

这显然不行。问题是:

I cannot find a tutorial about emitting signals (defining them appears in tutorials many times).

我怀疑你确实有,但忽略了意义,因为发射信号太容易了。例如,参见 the Signals section of the Vala Tutorial;显示发射 (t1.sig_1(5);).

I found GLib.Signal.emit() in the docs, but there is no example there on how to get a GLib.Signal object.

GLib.Signal.emit 是发射信号的低级方式,基本上没有理由从 Vala 使用它。

注意 emit 的第一个参数是一个指针。很少有例外(最显着的是 libxml),但在大多数情况下,如果您在 Vala 中遇到指针,则说明您做错了什么。在大多数情况下,这也适用于夸克;几乎所有你会使用夸克的东西在 Vala 中都有语法支持。

Am I defining the emitter as I should, at all?

没有。对于初学者,去掉方法体和 "virtual".

If so, how do I actually emit the event signal with equark as a detail?

你只需要这样的东西:

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
  });
client.@event.connect((room_id, raw_event, evt) => {
    // Signal received with *any* value for the detail
  });