Peter Uithoven
Peter Uithoven

Reputation: 825

Reusing signal handlers?

Is there a way in Vala to have multiple signal handlers perform the same code, while they have access to the local scope?

Defining a lambda using a delegate works, but requires a delegate definition and gives the warning "copying delegates is not supported":

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);
}

As far as I know there is also no way to pass information to handlers? something like:

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);
}

I could do this, but this requires a lot of extra code, especially when there are many arguments.

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);
}

Is there a way to connect multiple signals to one anonymous function? Something like:

void test () {
 var answer = 42;

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

Upvotes: 2

Views: 122

Answers (1)

Jens Mühlenhoff
Jens Mühlenhoff

Reputation: 14873

How about using this to pass data:

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;
    }
}

Maybe it is more readable with two classes:

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;
}

Upvotes: 2

Related Questions