gwenhywfar 5.14.1
gwensignal.c
Go to the documentation of this file.
1/***************************************************************************
2 $RCSfile$
3 -------------------
4 cvs : $Id: stringlist.c 1067 2006-05-22 15:25:23Z christian $
5 begin : Thu Apr 03 2003
6 copyright : (C) 2003 by Martin Preuss
7 email : martin@libchipcard.de
8
9 ***************************************************************************
10 * *
11 * This library is free software; you can redistribute it and/or *
12 * modify it under the terms of the GNU Lesser General Public *
13 * License as published by the Free Software Foundation; either *
14 * version 2.1 of the License, or (at your option) any later version. *
15 * *
16 * This library is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
19 * Lesser General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU Lesser General Public *
22 * License along with this library; if not, write to the Free Software *
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
24 * MA 02111-1307 USA *
25 * *
26 ***************************************************************************/
27
28#ifdef HAVE_CONFIG_H
29# include <config.h>
30#endif
31
32#include "gwensignal_p.h"
33#include <gwenhywfar/misc.h>
34#include <gwenhywfar/debug.h>
35#include <gwenhywfar/inherit.h>
36#include <stdlib.h>
37#include <assert.h>
38#include <string.h>
39
40
41
44
45
47{
49
51 so->signalList=GWEN_Signal_List2_new();
52 so->slotList=GWEN_Slot_List2_new();
53
54 return so;
55}
56
57
58
60{
61 if (so) {
62 GWEN_Slot_List2_freeAll(so->slotList);
63 GWEN_Signal_List2_freeAll(so->signalList);
65 }
66}
67
68
69
70uint32_t GWEN_SignalObject_MkTypeId(const char *typeName)
71{
72 return GWEN_Inherit_MakeId(typeName);
73}
74
75
76
78 const char *name,
79 uint32_t typeId1,
80 uint32_t typeId2)
81{
82 GWEN_SIGNAL_LIST2_ITERATOR *sit;
83
84 assert(so);
85 assert(name);
86
87 sit=GWEN_Signal_List2_First(so->signalList);
88 if (sit) {
89 GWEN_SIGNAL *sig;
90
91 sig=GWEN_Signal_List2Iterator_Data(sit);
92 assert(sig);
93 while (sig) {
94 const char *s;
95
96 s=sig->name;
97 assert(s);
98 if (strcasecmp(s, name)==0 &&
99 (typeId1==0 || typeId1==sig->typeOfArg1) &&
100 (typeId2==0 || typeId2==sig->typeOfArg2)) {
101 GWEN_Signal_List2Iterator_free(sit);
102 return sig;
103 }
104 sig=GWEN_Signal_List2Iterator_Next(sit);
105 }
106 GWEN_Signal_List2Iterator_free(sit);
107 }
108
109 return 0;
110}
111
112
113
115 const char *name,
116 const char *typeOfArg1,
117 const char *typeOfArg2)
118{
119 uint32_t typeId1=0;
120 uint32_t typeId2=0;
121
122 if (typeOfArg1)
123 typeId1=GWEN_SignalObject_MkTypeId(typeOfArg1);
124 if (typeOfArg2)
125 typeId2=GWEN_SignalObject_MkTypeId(typeOfArg2);
126 return GWEN_SignalObject__findSignal(so, name, typeId1, typeId2);
127}
128
129
130
132 const char *name,
133 uint32_t typeId1,
134 uint32_t typeId2)
135{
136 GWEN_SLOT_LIST2_ITERATOR *sit;
137
138 assert(so);
139 assert(name);
140
141 sit=GWEN_Slot_List2_First(so->slotList);
142 if (sit) {
143 GWEN_SLOT *slot;
144
145 slot=GWEN_Slot_List2Iterator_Data(sit);
146 assert(slot);
147 while (slot) {
148 const char *s;
149
150 s=slot->name;
151 assert(s);
152 if (strcasecmp(s, name)==0 &&
153 (typeId1==0 || typeId1==slot->typeOfArg1) &&
154 (typeId2==0 || typeId2==slot->typeOfArg2)) {
155 GWEN_Slot_List2Iterator_free(sit);
156 return slot;
157 }
158 slot=GWEN_Slot_List2Iterator_Next(sit);
159 }
160 GWEN_Slot_List2Iterator_free(sit);
161 }
162
163 return 0;
164}
165
166
167
169 const char *name,
170 const char *typeOfArg1,
171 const char *typeOfArg2)
172{
173 uint32_t typeId1=0;
174 uint32_t typeId2=0;
175
176 if (typeOfArg1)
177 typeId1=GWEN_SignalObject_MkTypeId(typeOfArg1);
178 if (typeOfArg2)
179 typeId2=GWEN_SignalObject_MkTypeId(typeOfArg2);
180 return GWEN_SignalObject__findSlot(so, name, typeId1, typeId2);
181}
182
183
184
186{
187 if (GWEN_SignalObject__findSignal(so, sig->name,
188 sig->typeOfArg1,
189 sig->typeOfArg2)) {
191 "Signal \"%s\" already exists",
192 sig->name);
193 return GWEN_ERROR_INVALID;
194 }
195
196 sig->signalObject=so;
197 GWEN_Signal_List2_PushBack(so->signalList, sig);
198 DBG_INFO(GWEN_LOGDOMAIN, "Added signal \"%s\"", sig->name);
199 return 0;
200}
201
202
203
205{
206 if (GWEN_SignalObject__findSlot(so, slot->name,
207 slot->typeOfArg1,
208 slot->typeOfArg2)) {
210 "Slot \"%s\" already exists",
211 slot->name);
212 return GWEN_ERROR_INVALID;
213 }
214 slot->signalObject=so;
215 GWEN_Slot_List2_PushBack(so->slotList, slot);
216 DBG_INFO(GWEN_LOGDOMAIN, "Added slot \"%s\"", slot->name);
217 return 0;
218}
219
220
221
223 const char *derivedType)
224{
225 uint32_t typeId=0;
226 GWEN_SLOT_LIST2_ITERATOR *slotIt;
227 GWEN_SIGNAL_LIST2_ITERATOR *sigIt;
228
229 assert(so);
230 if (derivedType)
231 typeId=GWEN_SignalObject_MkTypeId(derivedType);
232
233 slotIt=GWEN_Slot_List2_First(so->slotList);
234 if (slotIt) {
235 GWEN_SLOT *slot;
236
237 slot=GWEN_Slot_List2Iterator_Data(slotIt);
238 assert(slot);
239 while (slot) {
240 const char *s;
241
242 s=slot->name;
243 assert(s);
244 if (typeId==0 || slot->derivedParentType==typeId) {
245 GWEN_Slot_List2_Erase(so->slotList, slotIt);
246 GWEN_Slot_free(slot);
247 /* iterator now points to the next entry in any case (or NULL) */
248 slot=GWEN_Slot_List2Iterator_Data(slotIt);
249 }
250 else
251 slot=GWEN_Slot_List2Iterator_Next(slotIt);
252 }
253 GWEN_Slot_List2Iterator_free(slotIt);
254 }
255
256 sigIt=GWEN_Signal_List2_First(so->signalList);
257 if (sigIt) {
258 GWEN_SIGNAL *sig;
259
260 sig=GWEN_Signal_List2Iterator_Data(sigIt);
261 assert(sig);
262 while (sig) {
263 const char *s;
264
265 s=sig->name;
266 assert(s);
267 if (typeId==0 || sig->derivedParentType==typeId) {
268 GWEN_Signal_List2_Erase(so->signalList, sigIt);
269 GWEN_Signal_free(sig);
270 /* iterator now points to the next entry in any case (or NULL) */
271 sig=GWEN_Signal_List2Iterator_Data(sigIt);
272 }
273 else
274 sig=GWEN_Signal_List2Iterator_Next(sigIt);
275 }
276 GWEN_Signal_List2Iterator_free(sigIt);
277 }
278}
279
280
281
282
283
285 const char *derivedType,
286 const char *name,
287 const char *typeOfArg1,
288 const char *typeOfArg2)
289{
290 GWEN_SIGNAL *sig;
291
292 assert(so);
293 assert(name);
295 sig->_refCount=1;
296 sig->connectedSlots=GWEN_Slot_List2_new();
297 sig->name=strdup(name);
298 if (typeOfArg1)
299 sig->typeOfArg1=GWEN_SignalObject_MkTypeId(typeOfArg1);
300 if (typeOfArg2)
301 sig->typeOfArg2=GWEN_SignalObject_MkTypeId(typeOfArg2);
302 if (derivedType)
303 sig->derivedParentType=GWEN_SignalObject_MkTypeId(derivedType);
304
305 if (GWEN_SignalObject_AddSignal(so, sig)) {
306 GWEN_Signal_free(sig);
307 return 0;
308 }
309
310 return sig;
311}
312
313
314
316{
317 if (sig) {
318 assert(sig->_refCount);
319 if (sig->_refCount==1) {
320 GWEN_SLOT_LIST2_ITERATOR *sit;
321
322 /* remove from all connected slots */
323 sit=GWEN_Slot_List2_First(sig->connectedSlots);
324 if (sit) {
325 GWEN_SLOT *slot;
326
327 slot=GWEN_Slot_List2Iterator_Data(sit);
328 assert(slot);
329 while (slot) {
330 GWEN_SLOT *next;
331
332 next=GWEN_Slot_List2Iterator_Next(sit);
334 "Disconnecting signal \"%s\" from slot \"%s\"",
335 sig->name, slot->name);
336 GWEN_Signal_List2_Remove(slot->connectedSignals, sig);
337 slot=next;
338 }
339 GWEN_Slot_List2Iterator_free(sit);
340 }
341 GWEN_Slot_List2_free(sig->connectedSlots);
342
343 free(sig->name);
344 sig->_refCount=0;
345 GWEN_FREE_OBJECT(sig);
346 }
347 else
348 sig->_refCount--;
349 }
350}
351
352
353
355{
356 assert(sig);
357 assert(sig->_refCount);
358 sig->_refCount++;
359}
360
361
362
364{
365 GWEN_Signal_free(sig);
366 return 0;
367}
368
369
370
371void GWEN_Signal_List2_freeAll(GWEN_SIGNAL_LIST2 *slist)
372{
373 GWEN_Signal_List2_ForEach(slist, GWEN_Signal__List2_freeAll_cb, 0);
374 GWEN_Signal_List2_free(slist);
375}
376
377
378
380{
381 if ((void *)sig==user_data)
382 return sig;
383 return 0;
384}
385
386
387
388int GWEN_Signal_List2_HasSignal(GWEN_SIGNAL_LIST2 *slist, GWEN_SIGNAL *sig)
389{
390 if (GWEN_Signal_List2_ForEach(slist, GWEN_Signal__List2_hasSignal_cb,
391 (void *)sig))
392 return 1;
393 return 0;
394}
395
396
397
399{
400 assert(sig);
401 return sig->signalObject;
402}
403
404
405
407{
408 assert(sig);
409 assert(slot);
410 if (sig->typeOfArg1!=slot->typeOfArg1) {
412 "Signal \"%s\" and slot \"%s\" use different types for "
413 "argument 1",
414 sig->name, slot->name);
415 return GWEN_ERROR_INVALID;
416 }
417 if (sig->typeOfArg2!=slot->typeOfArg2) {
419 "Signal \"%s\" and slot \"%s\" use different types for "
420 "argument 2",
421 sig->name, slot->name);
422 return GWEN_ERROR_INVALID;
423 }
424 if (GWEN_Signal_List2_HasSignal(slot->connectedSignals, sig)) {
426 "Signal \"%s\" and slot \"%s\" already connected",
427 sig->name, slot->name);
428 return GWEN_ERROR_INVALID;
429 }
430
431 if (GWEN_Slot_List2_HasSlot(sig->connectedSlots, slot)) {
433 "Signal \"%s\" and slot \"%s\" already connected",
434 sig->name, slot->name);
435 return GWEN_ERROR_INVALID;
436 }
437
438 GWEN_Signal_List2_PushBack(slot->connectedSignals, sig);
439 GWEN_Slot_List2_PushBack(sig->connectedSlots, slot);
440
441 return 0;
442}
443
444
445
447{
448 assert(sig);
449 assert(slot);
450 if (GWEN_Signal_List2_HasSignal(slot->connectedSignals, sig)==0) {
452 "Signal \"%s\" and slot \"%s\" are not connected",
453 sig->name, slot->name);
454 return GWEN_ERROR_INVALID;
455 }
456
457 if (GWEN_Slot_List2_HasSlot(sig->connectedSlots, slot)==0) {
459 "Signal \"%s\" and slot \"%s\" are not connected",
460 sig->name, slot->name);
461 return GWEN_ERROR_INVALID;
462 }
463
464 GWEN_Signal_List2_Remove(slot->connectedSignals, sig);
465 GWEN_Slot_List2_Remove(sig->connectedSlots, slot);
466
467 return 0;
468}
469
470
471
473 void *pArg1, void *pArg2, int iArg3, int iArg4)
474{
475 GWEN_SLOT_LIST2_ITERATOR *sit;
476 int result=0;
477
478 assert(sig);
479 sit=GWEN_Slot_List2_First(sig->connectedSlots);
480 if (sit) {
481 GWEN_SLOT *slot;
482
483 slot=GWEN_Slot_List2Iterator_Data(sit);
484 assert(slot);
485 while (slot) {
486 if (slot->func) {
487 int rv;
488
490 "Sending signal \"%s\" to slot \"%s\" (%p)",
491 sig->name, slot->name, slot);
492 rv=slot->func(slot, slot->userData, pArg1, pArg2, iArg3, iArg4);
493 if (rv>0) {
495 "Slot \"%s\" (%p) returned an error (%d)",
496 slot->name, slot, rv);
497 result=rv;
498 }
499 }
500 slot=GWEN_Slot_List2Iterator_Next(sit);
501 }
502 GWEN_Slot_List2Iterator_free(sit);
503 }
504
505 return result;
506}
507
508
509
510
511
512
514 const char *derivedType,
515 const char *name,
516 const char *typeOfArg1,
517 const char *typeOfArg2,
519 void *userData)
520{
521 GWEN_SLOT *slot;
522
523 assert(name);
525 slot->_refCount=1;
526 slot->connectedSignals=GWEN_Signal_List2_new();
527 slot->name=strdup(name);
528 if (typeOfArg1)
529 slot->typeOfArg1=GWEN_SignalObject_MkTypeId(typeOfArg1);
530 if (typeOfArg2)
531 slot->typeOfArg2=GWEN_SignalObject_MkTypeId(typeOfArg2);
532 if (derivedType)
533 slot->derivedParentType=GWEN_SignalObject_MkTypeId(derivedType);
534 slot->func=fn;
535 slot->userData=userData;
536
537 if (GWEN_SignalObject_AddSlot(so, slot)) {
538 GWEN_Slot_free(slot);
539 return 0;
540 }
541
542 return slot;
543}
544
545
546
548{
549 if (slot) {
550 assert(slot->_refCount);
551 if (slot->_refCount==1) {
552 GWEN_SIGNAL_LIST2_ITERATOR *sit;
553
554 /* remove from all connected signals */
555 sit=GWEN_Signal_List2_First(slot->connectedSignals);
556 if (sit) {
557 GWEN_SIGNAL *sig;
558
559 sig=GWEN_Signal_List2Iterator_Data(sit);
560 assert(sig);
561 while (sig) {
563 "Disconnecting slot \"%s\" from signal \"%s\"",
564 slot->name, sig->name);
565 GWEN_Slot_List2_Remove(sig->connectedSlots, slot);
566 sig=GWEN_Signal_List2Iterator_Next(sit);
567 }
568 GWEN_Signal_List2Iterator_free(sit);
569 }
570 GWEN_Signal_List2_free(slot->connectedSignals);
571
572 free(slot->name);
573 slot->_refCount=0;
574 GWEN_FREE_OBJECT(slot);
575 }
576 else
577 slot->_refCount--;
578 }
579}
580
581
582
584{
585 assert(slot);
586 assert(slot->_refCount);
587 slot->_refCount++;
588}
589
590
591
593{
594 GWEN_Slot_free(slot);
595 return 0;
596}
597
598
599
600void GWEN_Slot_List2_freeAll(GWEN_SLOT_LIST2 *slist)
601{
602 GWEN_Slot_List2_ForEach(slist, GWEN_Slot__List2_freeAll_cb, 0);
603 GWEN_Slot_List2_free(slist);
604}
605
606
607
609 void *user_data)
610{
611 if ((void *)slot==user_data)
612 return slot;
613 return 0;
614}
615
616
617
618int GWEN_Slot_List2_HasSlot(GWEN_SLOT_LIST2 *slist, GWEN_SLOT *slot)
619{
620 if (GWEN_Slot_List2_ForEach(slist, GWEN_Slot__List2_hasSlot_cb, (void *)slot))
621 return 1;
622 return 0;
623}
624
625
626
628{
629 assert(slot);
630 return slot->signalObject;
631}
632
633
634
635
636
637
638
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define DBG_DEBUG(dbg_logger, format,...)
Definition debug.h:214
#define GWEN_ERROR_INVALID
Definition error.h:67
#define GWEN_UNUSED
int GWEN_SignalObject_AddSlot(GWEN_SIGNALOBJECT *so, GWEN_SLOT *slot)
Definition gwensignal.c:204
GWEN_SLOT * GWEN_SignalObject__findSlot(const GWEN_SIGNALOBJECT *so, const char *name, uint32_t typeId1, uint32_t typeId2)
Definition gwensignal.c:131
int GWEN_Slot_List2_HasSlot(GWEN_SLOT_LIST2 *slist, GWEN_SLOT *slot)
Definition gwensignal.c:618
GWEN_SLOT * GWEN_Slot__List2_hasSlot_cb(GWEN_SLOT *slot, void *user_data)
Definition gwensignal.c:608
void GWEN_SignalObject_free(GWEN_SIGNALOBJECT *so)
Definition gwensignal.c:59
int GWEN_Signal_Connect(GWEN_SIGNAL *sig, GWEN_SLOT *slot)
Definition gwensignal.c:406
GWEN_SLOT * GWEN_SignalObject_FindSlot(const GWEN_SIGNALOBJECT *so, const char *name, const char *typeOfArg1, const char *typeOfArg2)
Definition gwensignal.c:168
int GWEN_Signal_Emit(GWEN_SIGNAL *sig, void *pArg1, void *pArg2, int iArg3, int iArg4)
Definition gwensignal.c:472
GWEN_SIGNALOBJECT * GWEN_Signal_GetSignalObject(const GWEN_SIGNAL *sig)
Definition gwensignal.c:398
void GWEN_Slot_List2_freeAll(GWEN_SLOT_LIST2 *slist)
Definition gwensignal.c:600
GWEN_SLOT * GWEN_Slot__List2_freeAll_cb(GWEN_SLOT *slot, GWEN_UNUSED void *user_data)
Definition gwensignal.c:592
void GWEN_Signal_free(GWEN_SIGNAL *sig)
Definition gwensignal.c:315
int GWEN_Signal_List2_HasSignal(GWEN_SIGNAL_LIST2 *slist, GWEN_SIGNAL *sig)
Definition gwensignal.c:388
GWEN_SIGNAL * GWEN_Signal__List2_hasSignal_cb(GWEN_SIGNAL *sig, void *user_data)
Definition gwensignal.c:379
void GWEN_Signal_List2_freeAll(GWEN_SIGNAL_LIST2 *slist)
Definition gwensignal.c:371
GWEN_SIGNAL * GWEN_SignalObject__findSignal(const GWEN_SIGNALOBJECT *so, const char *name, uint32_t typeId1, uint32_t typeId2)
Definition gwensignal.c:77
uint32_t GWEN_SignalObject_MkTypeId(const char *typeName)
Definition gwensignal.c:70
GWEN_SIGNALOBJECT * GWEN_SignalObject_new(void)
Definition gwensignal.c:46
GWEN_SIGNAL * GWEN_Signal_new(GWEN_SIGNALOBJECT *so, const char *derivedType, const char *name, const char *typeOfArg1, const char *typeOfArg2)
Definition gwensignal.c:284
void GWEN_Signal_Attach(GWEN_SIGNAL *sig)
Definition gwensignal.c:354
GWEN_SIGNAL * GWEN_Signal__List2_freeAll_cb(GWEN_SIGNAL *sig, GWEN_UNUSED void *user_data)
Definition gwensignal.c:363
void GWEN_Slot_Attach(GWEN_SLOT *slot)
Definition gwensignal.c:583
GWEN_SIGNAL * GWEN_SignalObject_FindSignal(const GWEN_SIGNALOBJECT *so, const char *name, const char *typeOfArg1, const char *typeOfArg2)
Definition gwensignal.c:114
void GWEN_Slot_free(GWEN_SLOT *slot)
Definition gwensignal.c:547
GWEN_SIGNALOBJECT * GWEN_Slot_GetSignalObject(const GWEN_SLOT *slot)
Definition gwensignal.c:627
GWEN_SLOT * GWEN_Slot_new(GWEN_SIGNALOBJECT *so, const char *derivedType, const char *name, const char *typeOfArg1, const char *typeOfArg2, GWEN_SLOT_FUNCTION fn, void *userData)
Definition gwensignal.c:513
void GWEN_SignalObject_RemoveForDerivedType(GWEN_SIGNALOBJECT *so, const char *derivedType)
Definition gwensignal.c:222
int GWEN_Signal_Disconnect(GWEN_SIGNAL *sig, GWEN_SLOT *slot)
Definition gwensignal.c:446
int GWEN_SignalObject_AddSignal(GWEN_SIGNALOBJECT *so, GWEN_SIGNAL *sig)
Definition gwensignal.c:185
struct GWEN_SIGNALOBJECT GWEN_SIGNALOBJECT
Definition gwensignal.h:65
struct GWEN_SIGNAL GWEN_SIGNAL
Definition gwensignal.h:67
int GWENHYWFAR_CB(* GWEN_SLOT_FUNCTION)(GWEN_SLOT *slot, void *userData, void *pArg1, void *pArg2, int iArg3, int iArg4)
Definition gwensignal.h:76
struct GWEN_SLOT GWEN_SLOT
Definition gwensignal.h:69
uint32_t GWEN_Inherit_MakeId(const char *typeName)
Definition inherit.c:140
#define GWEN_LIST2_FUNCTIONS(t, pr)
Definition list2.h:99
#define GWEN_LOGDOMAIN
Definition logger.h:32
#define GWEN_FREE_OBJECT(varname)
Definition memory.h:61
#define GWEN_NEW_OBJECT(typ, varname)
Definition memory.h:55