Сигналы

Сигналы предоставляются классом Оbject из GLib, и их можно легко использовать в наследующих от него классах. Сигналы знакомы программистам С# в виде событий или Java программистам как альтернативный способ реализации слушателя событий. Короче говоря, сигнал это простой способ выполнения идентичных методов (т.е. с одинаковыми сигнатурами) одновременно. Вся внутренняя реализация находится в gobject и не так важна в самой Vala программе.

Сигнал объявляется как поле класса и выглядит как метод без тела. Обработчики сигнала могут быть к нему добавлены с помощью метода connect(). Для полного понимания вопроса рассмотрим код на Vala, где так же присутствуют лямбда-выражения, которые удобны при обработке сигналов.

public class Test : GLib.Object {

    public signal void sig_1(int a);

    public static int main(string[] args) {
        Test t1 = new Test();

        t1.sig_1.connect((t, a) => {
            stdout.printf("%d\n", a);
        });

        t1.sig_1(5);

        return 0;
    }
}

В коде объявляется класс с названием Test. Первое поле класса - это сигнал с названием sig_1, который принимает целочисленный аргумент. В методе main сперва создается экземпляр класса и это обязательно, т.к. сигналы принадлежат экземпляру. Следующим к сигналу назначается обработчик, который объявлен в той же строке как лямбда-выражение. Объявление гласит, что метод принимает два аргумента, которые называются t и а, но не указываются типы. Vala уже знает объявление сигнала и может понять какого типа аргументы ожидаются.

Причина использования двух параметров в том, что при подаче сигнала первым аргументом передается ссылка на объект, который стал его источником. Второй аргумент - это то, в чем будет хранится сгенерированное сигналом значение.

Наконец, мы уже начали скучать и подаем сигнал. Мы делаем это так, будто сигнал является обычным методом нашего класса, а gobject позаботиться, чтобы сигнал был получен в нужном обработчике. Знать внутренний механизм при этом не обязательно.

В настоящий момент сигналы могут быть только public - все сигналы могут быть приняты или поданы с любого места в коде.

Примечание: Начиная с апреля 2010 сигналы могут быть помечены любой комбинацией флагов:

[Signal (action=true, detailed=true, run=true, no_recurse=true, no_hooks=true)]
public signal void sig_1 ();

Last updated