-
Notifications
You must be signed in to change notification settings - Fork 16
/
libsigc++.txt
216 lines (189 loc) · 10.5 KB
/
libsigc++.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
LIBSIGC++
HEADERS ==> # - <sigc++/sigc++.h>
LIBRARIES ==> # - libsigc-${VERS}
OPTIONS DE COMPILATIONS
==> #Utiliser : $(pkg-config --cflags --libs sigc++-${VERS})
NAMESPACE ==> #sigc:: pour tous.
BUT ==> #Contrairement à un design d'interrupt handler où
#Signal == Slot == Callback
#Permet :
# - découpler les signaux des slots/callbacks : ainsi
# un signal peut avoir plusieurs slots ; on peut
# attribuer un même slot à plusieurs signaux ; etc.
# - découpler slot et callback : possibilité de
# [dé]bloquer les callbacks.
#Design :
# - On déclenche un sigc::signal, associé à un
# plusieurs sigc::slot, déclenchant leur callback
# (PREDIC) associé.
trackable #Base classe abstraite à publiquement hériter aux
#CLASS_VAR dont l'une de de leur CLASSFK est utilisée
#comme callback d'un SLOT.
#Fait que si CLASS_VAR est détruite, les slots associés
#à l'une de ces CLASSFK sont automatiquement
#déconnectés.
slot <...> #Enferme un callback, qu'il peut déconnecter ou bloquer.
#Le premier argument du template est le type de la
#return value, les autres, le type (et donc le nombre)
#des arguments (jusqu'à 7). Si pas d'argument, pas
#de type dans le template (et non "void").
SLOT() #N'associe SLOT à aucun callback. operator() ne fera
#rien (mais pas d'erreur).
SLOT(FUNCTOR) #Associe SLOT au callback FUNCTOR.
#Pour l'associer à un FUNCTOR temporaire, faire :
#SLOT = FUNCTOR().
#Pour utiliser avec un FUNCTOR autre que ceux définis
#dans libsigc++, mais ayant un result_type typedef,
#faire :
# - namespace sigc { SIGC_FUNCTORS_HAVE_RESULT_TYPE }
SLOT([ARGS]) #Invoque le callback de SLOT avec les arguments ARGS.
result_type #Typedef depuis le result_type
argN_type_ #Type de l'argument numéro N
SLOT.disconnect() #SLOT n'est plus associé à son callback.
SLOT.block #Bloque le SLOT associé : il ne provoque plus rien.
([BOOL_VAL]) #Si BOOL_VAL est false, fait le contraire : débloque le
#SLOT.
#Renvoie true si SLOT était blocked avant l'appel
SLOT.unblock() #Equivaut à SLOT.block(false).
( SLOT )
SLOT.connected() #Retourne true si SLOT est associé à un callback.
SLOT.empty() #Contraire.
SLOT.blocked() #Retourne true si le SLOT associé est bloqué.
slot_list <WVAR> #Désigne un deque-like container pour SLOT<...> (WVAR).
#CLASSFK supportées : begin(), end(), rbegin(), rend(),
#front(), back(), insert(), push_back(), push_front(),
#pop_back(), pop_front(), erase()
#et typedefs reference (WVAR&), const_reference,
#[const_][reverse_]iterator
slot_type #Typedef depuis WVAR.
slot_iterator <WVAR> #Désigne le forward iterator renvoyé par
#SLOT_LIST.begin() et SLOT_LIST.end(), de type slot_list
#<WVAR>
slot_type #Typedef depuis WVAR.
connection #A les mêmes fonctions que SLOT, mais est renvoyé par
#SIGNAL.connect().
#Pour accéder aux SLOTS d'un SIGNAL, en ne pouvant
#manipuler que le SIGNAL, deux solutions :
# - SIGNAL.slots() (plus pratique si plusieurs SLOTS)
# - instantier un CONNECTION avec le résultat de
# SIGNAL.connect() (plus pratique si un seul SLOT)
signal <...> #Désigne un générateur d'un signal donné.
#Template : même/convertible avec les SLOTS à invoquer.
#Pour une classe pouvant recevoir un évévement donné et
#devant réagir en conséquence :
# 1) On lui définie comme CLASSDT un SIGNAL.
# 2) On associe ce SIGNAL à un SLOT.
# 3) On déclenche SLOT(), via SIGNAL() (si possible
# via une fonction proxy)
#Le SIGNAL associé peut être un SLOT par défaut.
result_type #Typedef depuis le premier argument du template.
slot_type #Typedef depuis slot <WVAR1, WVAR...>, s'il y a plus
#d'un argument au template.
slot_list_type #Typedef depuis slot_list<...>
iterator #
const_iterator #
reverse_iterator #
const_reverse_iterator #slot_list<...>::[const_][reverse_]iterator
SIGNAL([ARGS]) #Invoque tous les SLOT associés à ce SIGNAL avec les
SIGNAL.emit([ARGS]) #arguments ARGS (dont le nombre et types doit
#correspondre au template de SIGNAL)
#Renvoie la return value de l'appel à SLOT(), s'il y en
#a une.
#S'il y a plusieurs SLOTS associés, retourne la value
#du dernier SLOT pour un SIGNAL normal et le résultat
#de l'ACCUMULATOR pour un SIGNAL::ACCUMULATED
SIGNAL.emit_reverse #Comme emit(), mais s'il y a plusieurs SLOT, ils sont
([ARGS]) #déclenchés en sens inverse.
SIGNAL.connect(SLOT) #Ajoute SLOT aux SLOTS associés à SIGNAL.
#Les template de SLOT et SIGNAL doivent être
#identiques/convertibles.
#Renvoie un SLOT_ITERATOR qui peut instantier un
#CONNECTION, à toujours faire, pour pouvoir
#éventuellement déconnnecter.
SIGNAL.make_slot() #Renvoie un SLOT qui invoque SIGNAL.emit(...)
SIGNAL.slots() #Renvoie l'ensemble des SLOT associés, sous forme de
#SLOT_LIST.
SIGNAL.size() #Renvoie le nombre de SLOTS associés, sous forme de
#SIZE_T_VAL.
SIGNAL.clear() #Supprime tous les SLOTS associés.
SIGNAL.empty() #Renvoie true si aucun SLOT n'est associé.
signal<...>:: #Exactement comme signal (même membres), sauf que si
accumulated<WVAR> #le SIGNAL::ACCUMULATED est connecté à plusieurs SLOT,
#plutôt que de renvoyer, via emit(), la return value
#du dernier SLOT, il invoque un ACCUMULATOR.
#Cela permet de combiner les différentes return value en
#une seule.
#WVAR est le type de cet ACCUMULATOR.
#Un ACCUMULATOR doit :
# - être un fonctor.
# - son operator() doit prendre deux arguments, un
# itérateur de début et de fin, dont le type est
# défini par un template sur l'operator(). Ces
# arguments permettent de parcourir les return values
# des différents SLOT.
# - avoir un membre public nommé result_type, typedef
# depuis le type de la return value de operator().
#Exemple :
# signal<...>::accumulated<mon_accumulateur>
# class mon_accumulateur
# {
# public:
# typedef TYPE result_type;
# template <typename T>
# TYPE operator()(T DEBUT, T FIN)
# {
# TYPE VAR = VAL;
# for ( ; DEBUT != FIN ; DEBUT++ )
# VAR += *DEBUT;
# return VAR;
# }
# };
ptr_fun(FUNC_ADR) #
mem_fun(CLASS_VAR, #
VOID_CLASSFK_ADR) #
bind(SLOT, ARGS) #Préférer utilier std:: ou boost::
EXEMPLE D'IMPLEMENTATION
==> #
class MyCallback : public sigc::trackable
{
public:
void operator()( int const& a )
{ std::cout << a << "\n"; }
};
template <class T, class U>
class MySignal : public sigc::signal<T,U>
{
typedef sigc::slot<T,U> SlotType;
typedef typename sigc::slot_list<SlotType>::iterator IterType;
public:
MySignal( SlotType const& Callback )
{ connect( Callback ); }
void BlockAll( bool const& BlockFlag = true )
{
for ( IterType Iter( this->slots().begin() ) ; Iter != this->slots().end() ; Iter++ )
Iter->block(BlockFlag);
}
void ChangeSlot( SlotType const& Callback )
{
this->slots().begin()->disconnect();
this->connect( Callback );
}
// + Opérations pour les slots isolément, etc.
};
class Widget
{
MySignal<void,int> MySignalVar;
int Data;
public:
Widget( void )
// Callback de MySignal par défaut pour Widget
: MySignalVar( MyCallback() ), Data( 3 ) {};
void PushButton( void )
{ MySignalVar( Data ); }
void BlockMySignal( bool const& BlockFlag = true )
{ MySignalVar.BlockAll( BlockFlag ); }
void ChangeCallback( sigc::slot<void,int> const& Callback )
{ MySignalVar.ChangeSlot( Callback ); }
};