在Vala发出详细信号

时间:2016-02-18 10:55:57

标签: 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;但是,我找不到关于发光信号的教程(定义它们多次出现在教程中)。我在文档中找到了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信号?

1 个答案:

答案 0 :(得分:3)

  

我找不到关于发射信号的教程(定义它们多次出现在教程中)。

我怀疑你确实有,但错过了重要性,因为发射信号非常容易。例如,请参阅the Signals section of the Vala Tutorial;显示了发光(t1.sig_1(5);)。

  

我在文档中找到了GLib.Signal.emit(),但是没有关于如何获取GLib.Signal对象的例子。

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

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