gwenhywfar  4.8.0beta
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 
48 
50  so->signalList=GWEN_Signal_List2_new();
51  so->slotList=GWEN_Slot_List2_new();
52 
53  return so;
54 }
55 
56 
57 
59  if (so) {
60  GWEN_Slot_List2_freeAll(so->slotList);
61  GWEN_Signal_List2_freeAll(so->signalList);
62  GWEN_FREE_OBJECT(so);
63  }
64 }
65 
66 
67 
68 uint32_t GWEN_SignalObject_MkTypeId(const char *typeName) {
69  return GWEN_Inherit_MakeId(typeName);
70 }
71 
72 
73 
75  const char *name,
76  uint32_t typeId1,
77  uint32_t typeId2) {
78  GWEN_SIGNAL_LIST2_ITERATOR *sit;
79 
80  assert(so);
81  assert(name);
82 
83  sit=GWEN_Signal_List2_First(so->signalList);
84  if (sit) {
85  GWEN_SIGNAL *sig;
86 
87  sig=GWEN_Signal_List2Iterator_Data(sit);
88  assert(sig);
89  while(sig) {
90  const char *s;
91 
92  s=sig->name;
93  assert(s);
94  if (strcasecmp(s, name)==0 &&
95  (typeId1==0 || typeId1==sig->typeOfArg1) &&
96  (typeId2==0 || typeId2==sig->typeOfArg2)) {
97  GWEN_Signal_List2Iterator_free(sit);
98  return sig;
99  }
100  sig=GWEN_Signal_List2Iterator_Next(sit);
101  }
102  GWEN_Signal_List2Iterator_free(sit);
103  }
104 
105  return 0;
106 }
107 
108 
109 
111  const char *name,
112  const char *typeOfArg1,
113  const char *typeOfArg2) {
114  uint32_t typeId1=0;
115  uint32_t typeId2=0;
116 
117  if (typeOfArg1)
118  typeId1=GWEN_SignalObject_MkTypeId(typeOfArg1);
119  if (typeOfArg2)
120  typeId2=GWEN_SignalObject_MkTypeId(typeOfArg2);
121  return GWEN_SignalObject__findSignal(so, name, typeId1, typeId2);
122 }
123 
124 
125 
127  const char *name,
128  uint32_t typeId1,
129  uint32_t typeId2) {
130  GWEN_SLOT_LIST2_ITERATOR *sit;
131 
132  assert(so);
133  assert(name);
134 
135  sit=GWEN_Slot_List2_First(so->slotList);
136  if (sit) {
137  GWEN_SLOT *slot;
138 
139  slot=GWEN_Slot_List2Iterator_Data(sit);
140  assert(slot);
141  while(slot) {
142  const char *s;
143 
144  s=slot->name;
145  assert(s);
146  if (strcasecmp(s, name)==0 &&
147  (typeId1==0 || typeId1==slot->typeOfArg1) &&
148  (typeId2==0 || typeId2==slot->typeOfArg2)) {
149  GWEN_Slot_List2Iterator_free(sit);
150  return slot;
151  }
152  slot=GWEN_Slot_List2Iterator_Next(sit);
153  }
154  GWEN_Slot_List2Iterator_free(sit);
155  }
156 
157  return 0;
158 }
159 
160 
161 
163  const char *name,
164  const char *typeOfArg1,
165  const char *typeOfArg2) {
166  uint32_t typeId1=0;
167  uint32_t typeId2=0;
168 
169  if (typeOfArg1)
170  typeId1=GWEN_SignalObject_MkTypeId(typeOfArg1);
171  if (typeOfArg2)
172  typeId2=GWEN_SignalObject_MkTypeId(typeOfArg2);
173  return GWEN_SignalObject__findSlot(so, name, typeId1, typeId2);
174 }
175 
176 
177 
179  if (GWEN_SignalObject__findSignal(so, sig->name,
180  sig->typeOfArg1,
181  sig->typeOfArg2)) {
183  "Signal \"%s\" already exists",
184  sig->name);
185  return GWEN_ERROR_INVALID;
186  }
187 
188  sig->signalObject=so;
189  GWEN_Signal_List2_PushBack(so->signalList, sig);
190  DBG_INFO(GWEN_LOGDOMAIN, "Added signal \"%s\"", sig->name);
191  return 0;
192 }
193 
194 
195 
197  if (GWEN_SignalObject__findSlot(so, slot->name,
198  slot->typeOfArg1,
199  slot->typeOfArg2)) {
201  "Slot \"%s\" already exists",
202  slot->name);
203  return GWEN_ERROR_INVALID;
204  }
205  slot->signalObject=so;
206  GWEN_Slot_List2_PushBack(so->slotList, slot);
207  DBG_INFO(GWEN_LOGDOMAIN, "Added slot \"%s\"", slot->name);
208  return 0;
209 }
210 
211 
212 
214  const char *derivedType) {
215  uint32_t typeId=0;
216  GWEN_SLOT_LIST2_ITERATOR *slotIt;
217  GWEN_SIGNAL_LIST2_ITERATOR *sigIt;
218 
219  assert(so);
220  if (derivedType)
221  typeId=GWEN_SignalObject_MkTypeId(derivedType);
222 
223  slotIt=GWEN_Slot_List2_First(so->slotList);
224  if (slotIt) {
225  GWEN_SLOT *slot;
226 
227  slot=GWEN_Slot_List2Iterator_Data(slotIt);
228  assert(slot);
229  while(slot) {
230  const char *s;
231 
232  s=slot->name;
233  assert(s);
234  if (typeId==0 || slot->derivedParentType==typeId) {
235  GWEN_Slot_List2_Erase(so->slotList, slotIt);
236  GWEN_Slot_free(slot);
237  /* iterator now points to the next entry in any case (or NULL) */
238  slot=GWEN_Slot_List2Iterator_Data(slotIt);
239  }
240  else
241  slot=GWEN_Slot_List2Iterator_Next(slotIt);
242  }
243  GWEN_Slot_List2Iterator_free(slotIt);
244  }
245 
246  sigIt=GWEN_Signal_List2_First(so->signalList);
247  if (sigIt) {
248  GWEN_SIGNAL *sig;
249 
250  sig=GWEN_Signal_List2Iterator_Data(sigIt);
251  assert(sig);
252  while(sig) {
253  const char *s;
254 
255  s=sig->name;
256  assert(s);
257  if (typeId==0 || sig->derivedParentType==typeId) {
258  GWEN_Signal_List2_Erase(so->signalList, sigIt);
259  GWEN_Signal_free(sig);
260  /* iterator now points to the next entry in any case (or NULL) */
261  sig=GWEN_Signal_List2Iterator_Data(sigIt);
262  }
263  else
264  sig=GWEN_Signal_List2Iterator_Next(sigIt);
265  }
266  GWEN_Signal_List2Iterator_free(sigIt);
267  }
268 }
269 
270 
271 
272 
273 
275  const char *derivedType,
276  const char *name,
277  const char *typeOfArg1,
278  const char *typeOfArg2) {
279  GWEN_SIGNAL *sig;
280 
281  assert(so);
282  assert(name);
284  sig->_refCount=1;
285  sig->connectedSlots=GWEN_Slot_List2_new();
286  sig->name=strdup(name);
287  if (typeOfArg1)
288  sig->typeOfArg1=GWEN_SignalObject_MkTypeId(typeOfArg1);
289  if (typeOfArg2)
290  sig->typeOfArg2=GWEN_SignalObject_MkTypeId(typeOfArg2);
291  if (derivedType)
292  sig->derivedParentType=GWEN_SignalObject_MkTypeId(derivedType);
293 
294  if (GWEN_SignalObject_AddSignal(so, sig)) {
295  GWEN_Signal_free(sig);
296  return 0;
297  }
298 
299  return sig;
300 }
301 
302 
303 
305  if (sig) {
306  assert(sig->_refCount);
307  if (sig->_refCount==1) {
308  GWEN_SLOT_LIST2_ITERATOR *sit;
309 
310  /* remove from all connected slots */
311  sit=GWEN_Slot_List2_First(sig->connectedSlots);
312  if (sit) {
313  GWEN_SLOT *slot;
314 
315  slot=GWEN_Slot_List2Iterator_Data(sit);
316  assert(slot);
317  while(slot) {
318  GWEN_SLOT *next;
319 
320  next=GWEN_Slot_List2Iterator_Next(sit);
322  "Disconnecting signal \"%s\" from slot \"%s\"",
323  sig->name, slot->name);
324  GWEN_Signal_List2_Remove(slot->connectedSignals, sig);
325  slot=next;
326  }
327  GWEN_Slot_List2Iterator_free(sit);
328  }
329  GWEN_Slot_List2_free(sig->connectedSlots);
330 
331  free(sig->name);
332  sig->_refCount=0;
333  GWEN_FREE_OBJECT(sig);
334  }
335  else
336  sig->_refCount--;
337  }
338 }
339 
340 
341 
343  assert(sig);
344  assert(sig->_refCount);
345  sig->_refCount++;
346 }
347 
348 
349 
351  GWEN_Signal_free(sig);
352  return 0;
353 }
354 
355 
356 
357 void GWEN_Signal_List2_freeAll(GWEN_SIGNAL_LIST2 *slist) {
358  GWEN_Signal_List2_ForEach(slist, GWEN_Signal__List2_freeAll_cb, 0);
359  GWEN_Signal_List2_free(slist);
360 }
361 
362 
363 
365  void *user_data){
366  if ((void*)sig==user_data)
367  return sig;
368  return 0;
369 }
370 
371 
372 
373 int GWEN_Signal_List2_HasSignal(GWEN_SIGNAL_LIST2 *slist,
374  const GWEN_SIGNAL *sig) {
375  if (GWEN_Signal_List2_ForEach(slist, GWEN_Signal__List2_hasSignal_cb,
376  (void*)sig))
377  return 1;
378  return 0;
379 }
380 
381 
382 
384  assert(sig);
385  return sig->signalObject;
386 }
387 
388 
389 
391  assert(sig);
392  assert(slot);
393  if (sig->typeOfArg1!=slot->typeOfArg1) {
395  "Signal \"%s\" and slot \"%s\" use different types for "
396  "argument 1",
397  sig->name, slot->name);
398  return GWEN_ERROR_INVALID;
399  }
400  if (sig->typeOfArg2!=slot->typeOfArg2) {
402  "Signal \"%s\" and slot \"%s\" use different types for "
403  "argument 2",
404  sig->name, slot->name);
405  return GWEN_ERROR_INVALID;
406  }
407  if (GWEN_Signal_List2_HasSignal(slot->connectedSignals, sig)) {
409  "Signal \"%s\" and slot \"%s\" already connected",
410  sig->name, slot->name);
411  return GWEN_ERROR_INVALID;
412  }
413 
414  if (GWEN_Slot_List2_HasSlot(sig->connectedSlots, slot)) {
416  "Signal \"%s\" and slot \"%s\" already connected",
417  sig->name, slot->name);
418  return GWEN_ERROR_INVALID;
419  }
420 
421  GWEN_Signal_List2_PushBack(slot->connectedSignals, sig);
422  GWEN_Slot_List2_PushBack(sig->connectedSlots, slot);
423 
424  return 0;
425 }
426 
427 
428 
430  assert(sig);
431  assert(slot);
432  if (GWEN_Signal_List2_HasSignal(slot->connectedSignals, sig)==0) {
434  "Signal \"%s\" and slot \"%s\" are not connected",
435  sig->name, slot->name);
436  return GWEN_ERROR_INVALID;
437  }
438 
439  if (GWEN_Slot_List2_HasSlot(sig->connectedSlots, slot)==0) {
441  "Signal \"%s\" and slot \"%s\" are not connected",
442  sig->name, slot->name);
443  return GWEN_ERROR_INVALID;
444  }
445 
446  GWEN_Signal_List2_Remove(slot->connectedSignals, sig);
447  GWEN_Slot_List2_Remove(sig->connectedSlots, slot);
448 
449  return 0;
450 }
451 
452 
453 
455  void *pArg1, void *pArg2, int iArg3, int iArg4) {
456  GWEN_SLOT_LIST2_ITERATOR *sit;
457  int result=0;
458 
459  assert(sig);
460  sit=GWEN_Slot_List2_First(sig->connectedSlots);
461  if (sit) {
462  GWEN_SLOT *slot;
463 
464  slot=GWEN_Slot_List2Iterator_Data(sit);
465  assert(slot);
466  while(slot) {
467  if (slot->func) {
468  int rv;
469 
471  "Sending signal \"%s\" to slot \"%s\" (%p)",
472  sig->name, slot->name, slot);
473  rv=slot->func(slot, slot->userData, pArg1, pArg2, iArg3, iArg4);
474  if (rv>0) {
476  "Slot \"%s\" (%p) returned an error (%d)",
477  slot->name, slot, rv);
478  result=rv;
479  }
480  }
481  slot=GWEN_Slot_List2Iterator_Next(sit);
482  }
483  GWEN_Slot_List2Iterator_free(sit);
484  }
485 
486  return result;
487 }
488 
489 
490 
491 
492 
493 
495  const char *derivedType,
496  const char *name,
497  const char *typeOfArg1,
498  const char *typeOfArg2,
500  void *userData) {
501  GWEN_SLOT *slot;
502 
503  assert(name);
505  slot->_refCount=1;
506  slot->connectedSignals=GWEN_Signal_List2_new();
507  slot->name=strdup(name);
508  if (typeOfArg1)
509  slot->typeOfArg1=GWEN_SignalObject_MkTypeId(typeOfArg1);
510  if (typeOfArg2)
511  slot->typeOfArg2=GWEN_SignalObject_MkTypeId(typeOfArg2);
512  if (derivedType)
513  slot->derivedParentType=GWEN_SignalObject_MkTypeId(derivedType);
514  slot->func=fn;
515  slot->userData=userData;
516 
517  if (GWEN_SignalObject_AddSlot(so, slot)) {
518  GWEN_Slot_free(slot);
519  return 0;
520  }
521 
522  return slot;
523 }
524 
525 
526 
528  if (slot) {
529  assert(slot->_refCount);
530  if (slot->_refCount==1) {
531  GWEN_SIGNAL_LIST2_ITERATOR *sit;
532 
533  /* remove from all connected signals */
534  sit=GWEN_Signal_List2_First(slot->connectedSignals);
535  if (sit) {
536  GWEN_SIGNAL *sig;
537 
538  sig=GWEN_Signal_List2Iterator_Data(sit);
539  assert(sig);
540  while(sig) {
542  "Disconnecting slot \"%s\" from signal \"%s\"",
543  slot->name, sig->name);
544  GWEN_Slot_List2_Remove(sig->connectedSlots, slot);
545  sig=GWEN_Signal_List2Iterator_Next(sit);
546  }
547  GWEN_Signal_List2Iterator_free(sit);
548  }
549  GWEN_Signal_List2_free(slot->connectedSignals);
550 
551  free(slot->name);
552  slot->_refCount=0;
553  GWEN_FREE_OBJECT(slot);
554  }
555  else
556  slot->_refCount--;
557  }
558 }
559 
560 
561 
563  assert(slot);
564  assert(slot->_refCount);
565  slot->_refCount++;
566 }
567 
568 
569 
571  GWEN_Slot_free(slot);
572  return 0;
573 }
574 
575 
576 
577 void GWEN_Slot_List2_freeAll(GWEN_SLOT_LIST2 *slist) {
578  GWEN_Slot_List2_ForEach(slist, GWEN_Slot__List2_freeAll_cb, 0);
579  GWEN_Slot_List2_free(slist);
580 }
581 
582 
583 
585  void *user_data){
586  if ((void*)slot==user_data)
587  return slot;
588  return 0;
589 }
590 
591 
592 
593 int GWEN_Slot_List2_HasSlot(GWEN_SLOT_LIST2 *slist,
594  const GWEN_SLOT *slot) {
595  if (GWEN_Slot_List2_ForEach(slist, GWEN_Slot__List2_hasSlot_cb,
596  (void*)slot))
597  return 1;
598  return 0;
599 }
600 
601 
602 
604  assert(slot);
605  return slot->signalObject;
606 }
607 
608 
609 
610 
611 
612 
613