Повторное использование обработчиков сигналов? - PullRequest
0 голосов
/ 30 октября 2018

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

Определение лямбды с использованием делегата работает, но требует определения делегата и выдает предупреждение «копирование делегатов не поддерживается»:

delegate void ChangeHandler ();
void test () {
 var answer = 42;

 ChangeHandler handler = () => {
   debug("size or position changed. answer: %i", answer);
 };
 size_changed.connect (handler);
 position_changed.connect (handler);
}

Насколько я знаю, также нет способа передать информацию обработчикам? что-то вроде:

void test () {
 var answer = 42;
 size_changed.connect (handler, answer);
 position_changed.connect (handler, answer);
}
void handler (answer) {
 debug("size or position changed. answer: %i", answer);
}

Я мог бы сделать это, но это требует много дополнительного кода, особенно когда есть много аргументов.

void test () {
 var answer = 42;
 size_changed.connect (handler, answer);
 position_changed.connect (() => handler(answer));
}
void handler (answer) {
 debug("size or position changed. answer: %i", answer);
}

Есть ли способ подключить несколько сигналов к одной анонимной функции? Что-то вроде:

void test () {
 var answer = 42;

 multi_connect(size_changed, position_changed, () => {
   debug("size or position changed. answer: %i", answer);
 });
}

1 Ответ

0 голосов
/ 30 октября 2018

Как насчет использования this для передачи данных:

public class Test : GLib.Object {

    public signal void sig_1 ();

    public signal void sig_2 ();

    private int answer = 42;

    private void sig_handler (Test t) {
        stdout.printf("sig_1 or sig_2 triggered. answer: %d\n", answer);
    }

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

        t1.sig_1.connect(t1.sig_handler);
        t1.sig_2.connect(t1.sig_handler);

        t1.sig_1();
        t1.sig_2();

        return 0;
    }
}

Может быть, это более читабельно с двумя классами:

public class SignalRaiser : GLib.Object {
    public signal void sig_1 ();
    public signal void sig_2 ();
}

public class SignalReceiver : GLib.Object {
    private int answer = 42;

    public void sig_handler (SignalRaiser sender) {
        stdout.printf("sig_1 or sig_2 triggered. answer: %d\n", answer);
    }
}

int main(string[] args) {
    var raiser = new SignalRaiser();
    var receiver = new SignalReceiver();

    raiser.sig_1.connect(receiver.sig_handler);
    raiser.sig_2.connect(receiver.sig_handler);

    raiser.sig_1();
    raiser.sig_2();

    return 0;
}
...