libcamera v0.0.0
Supporting cameras in Linux since 2019
Loading...
Searching...
No Matches
signal.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2/*
3 * Copyright (C) 2019, Google Inc.
4 *
5 * signal.h - Signal & slot implementation
6 */
7
8#pragma once
9
10#include <functional>
11#include <list>
12#include <type_traits>
13#include <vector>
14
17
18namespace libcamera {
19
20class SignalBase
21{
22public:
23 void disconnect(Object *object);
24
25protected:
26 using SlotList = std::list<BoundMethodBase *>;
27
28 void connect(BoundMethodBase *slot);
29 void disconnect(std::function<bool(SlotList::iterator &)> match);
30
31 SlotList slots();
32
33private:
34 SlotList slots_;
35};
36
37template<typename... Args>
38class Signal : public SignalBase
39{
40public:
41 ~Signal()
42 {
43 disconnect();
44 }
45
46#ifndef __DOXYGEN__
47 template<typename T, typename R, std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr>
48 void connect(T *obj, R (T::*func)(Args...),
50 {
51 Object *object = static_cast<Object *>(obj);
52 SignalBase::connect(new BoundMethodMember<T, R, Args...>(obj, object, func, type));
53 }
54
55 template<typename T, typename R, std::enable_if_t<!std::is_base_of<Object, T>::value> * = nullptr>
56#else
57 template<typename T, typename R>
58#endif
59 void connect(T *obj, R (T::*func)(Args...))
60 {
61 SignalBase::connect(new BoundMethodMember<T, R, Args...>(obj, nullptr, func));
62 }
63
64#ifndef __DOXYGEN__
65 template<typename T, typename Func,
66 std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr>
67 void connect(T *obj, Func func, ConnectionType type = ConnectionTypeAuto)
68 {
69 Object *object = static_cast<Object *>(obj);
70 SignalBase::connect(new BoundMethodFunctor<T, void, Func, Args...>(obj, object, func, type));
71 }
72
73 template<typename T, typename Func,
74 std::enable_if_t<!std::is_base_of<Object, T>::value> * = nullptr>
75#else
76 template<typename T, typename Func>
77#endif
78 void connect(T *obj, Func func)
79 {
80 SignalBase::connect(new BoundMethodFunctor<T, void, Func, Args...>(obj, nullptr, func));
81 }
82
83 template<typename R>
84 void connect(R (*func)(Args...))
85 {
86 SignalBase::connect(new BoundMethodStatic<R, Args...>(func));
87 }
88
90 {
91 SignalBase::disconnect([]([[maybe_unused]] SlotList::iterator &iter) {
92 return true;
93 });
94 }
95
96 template<typename T>
97 void disconnect(T *obj)
98 {
99 SignalBase::disconnect([obj](SlotList::iterator &iter) {
100 return (*iter)->match(obj);
101 });
102 }
103
104 template<typename T, typename R>
105 void disconnect(T *obj, R (T::*func)(Args...))
106 {
107 SignalBase::disconnect([obj, func](SlotList::iterator &iter) {
108 BoundMethodArgs<R, Args...> *slot =
109 static_cast<BoundMethodArgs<R, Args...> *>(*iter);
110
111 if (!slot->match(obj))
112 return false;
113
114 /*
115 * If the object matches the slot, the slot is
116 * guaranteed to be a member slot, so we can safely
117 * cast it to BoundMethodMember<T, Args...> to match
118 * func.
119 */
120 return static_cast<BoundMethodMember<T, R, Args...> *>(slot)->match(func);
121 });
122 }
123
124 template<typename R>
125 void disconnect(R (*func)(Args...))
126 {
127 SignalBase::disconnect([func](SlotList::iterator &iter) {
128 BoundMethodArgs<R, Args...> *slot =
129 static_cast<BoundMethodArgs<R, Args...> *>(*iter);
130
131 if (!slot->match(nullptr))
132 return false;
133
134 return static_cast<BoundMethodStatic<R, Args...> *>(slot)->match(func);
135 });
136 }
137
138 void emit(Args... args)
139 {
140 /*
141 * Make a copy of the slots list as the slot could call the
142 * disconnect operation, invalidating the iterator.
143 */
144 for (BoundMethodBase *slot : slots())
145 static_cast<BoundMethodArgs<void, Args...> *>(slot)->activate(args...);
146 }
147};
148
149} /* namespace libcamera */
Method bind and invocation.
Base object to support automatic signal disconnection.
Definition: object.h:25
Generic signal and slot communication mechanism.
Definition: signal.h:39
void disconnect(R(*func)(Args...))
Disconnect the signal from the slot static function func.
Definition: signal.h:125
void connect(T *obj, Func func)
Connect the signal to a function object slot.
Definition: signal.h:78
void disconnect(T *obj)
Disconnect the signal from all slots of the object.
Definition: signal.h:97
void disconnect()
Disconnect the signal from all slots.
Definition: signal.h:89
void connect(T *obj, R(T::*func)(Args...))
Connect the signal to a member function slot.
Definition: signal.h:59
void connect(R(*func)(Args...))
Connect the signal to a static function slot.
Definition: signal.h:84
void disconnect(T *obj, R(T::*func)(Args...))
Disconnect the signal from the object slot member function func.
Definition: signal.h:105
void emit(Args... args)
Emit the signal and call all connected slots.
Definition: signal.h:138
Top-level libcamera namespace.
Definition: backtrace.h:17
ConnectionType
Connection type for asynchronous communication.
Definition: bound_method.h:19
@ ConnectionTypeAuto
If the sender and the receiver live in the same thread, ConnectionTypeDirect is used....
Definition: bound_method.h:20
Base object to support automatic signal disconnection.