libcamera: base: signal: Support connecting signals to functors

It can be useful to connect a signal to a functor, and in particular a
lambda function, while still operating in the context of a receiver
object (to support both object-based disconnection and queued
connections to Object instances).

Add a BoundMethodFunctor class to bind a functor, and a corresponding
Signal::connect() function. There is no corresponding disconnect()
function, as a lambda passed to connect() can't be later passed to
disconnect(). Disconnection typically uses disconnect(T *object), which
will cover the vast majority of use cases.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
This commit is contained in:
Laurent Pinchart 2021-08-27 04:05:33 +03:00
parent c4e2b00d51
commit 58720e1dc9
5 changed files with 114 additions and 0 deletions

View file

@ -191,6 +191,24 @@ protected:
signalVoid_.connect(slotStaticReturn);
signalVoid_.connect(this, &SignalTest::slotReturn);
/* Test signal connection to a lambda. */
int value = 0;
signalInt_.connect(this, [&](int v) { value = v; });
signalInt_.emit(42);
if (value != 42) {
cout << "Signal connection to lambda failed" << endl;
return TestFail;
}
signalInt_.disconnect(this);
signalInt_.emit(0);
if (value != 42) {
cout << "Signal disconnection from lambda failed" << endl;
return TestFail;
}
/* ----------------- Signal -> Object tests ----------------- */
/*
@ -256,6 +274,27 @@ protected:
delete slotObject;
/* Test signal connection to a lambda. */
slotObject = new SlotObject();
value = 0;
signalInt_.connect(slotObject, [&](int v) { value = v; });
signalInt_.emit(42);
if (value != 42) {
cout << "Signal connection to Object lambda failed" << endl;
return TestFail;
}
signalInt_.disconnect(slotObject);
signalInt_.emit(0);
if (value != 42) {
cout << "Signal disconnection from Object lambda failed" << endl;
return TestFail;
}
delete slotObject;
/* --------- Signal -> Object (multiple inheritance) -------- */
/*