1 /** 2 ******************************************************************************* 3 * Copyright (C) 2001-2006, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7 8 #include "unicode/utypes.h" 9 10 #if !UCONFIG_NO_SERVICE 11 12 #include "servnotf.h" 13 #ifdef NOTIFIER_DEBUG 14 #include <stdio.h> 15 #endif 16 17 U_NAMESPACE_BEGIN 18 19 EventListener::~EventListener() {} 20 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EventListener) 21 22 ICUNotifier::ICUNotifier(void) 23 : notifyLock(0), listeners(NULL) 24 { 25 umtx_init(¬ifyLock); 26 } 27 28 ICUNotifier::~ICUNotifier(void) { 29 { 30 Mutex lmx(¬ifyLock); 31 delete listeners; 32 listeners = NULL; 33 } 34 umtx_destroy(¬ifyLock); 35 } 36 37 38 void 39 ICUNotifier::addListener(const EventListener* l, UErrorCode& status) 40 { 41 if (U_SUCCESS(status)) { 42 if (l == NULL) { 43 status = U_ILLEGAL_ARGUMENT_ERROR; 44 return; 45 } 46 47 if (acceptsListener(*l)) { 48 Mutex lmx(¬ifyLock); 49 if (listeners == NULL) { 50 listeners = new UVector(5, status); 51 } else { 52 for (int i = 0, e = listeners->size(); i < e; ++i) { 53 const EventListener* el = (const EventListener*)(listeners->elementAt(i)); 54 if (l == el) { 55 return; 56 } 57 } 58 } 59 60 listeners->addElement((void*)l, status); // cast away const 61 } 62 #ifdef NOTIFIER_DEBUG 63 else { 64 fprintf(stderr, "Listener invalid for this notifier."); 65 exit(1); 66 } 67 #endif 68 } 69 } 70 71 void 72 ICUNotifier::removeListener(const EventListener *l, UErrorCode& status) 73 { 74 if (U_SUCCESS(status)) { 75 if (l == NULL) { 76 status = U_ILLEGAL_ARGUMENT_ERROR; 77 return; 78 } 79 80 { 81 Mutex lmx(¬ifyLock); 82 if (listeners != NULL) { 83 // identity equality check 84 for (int i = 0, e = listeners->size(); i < e; ++i) { 85 const EventListener* el = (const EventListener*)listeners->elementAt(i); 86 if (l == el) { 87 listeners->removeElementAt(i); 88 if (listeners->size() == 0) { 89 delete listeners; 90 listeners = NULL; 91 } 92 return; 93 } 94 } 95 } 96 } 97 } 98 } 99 100 void 101 ICUNotifier::notifyChanged(void) 102 { 103 if (listeners != NULL) { 104 Mutex lmx(¬ifyLock); 105 if (listeners != NULL) { 106 for (int i = 0, e = listeners->size(); i < e; ++i) { 107 EventListener* el = (EventListener*)listeners->elementAt(i); 108 notifyListener(*el); 109 } 110 } 111 } 112 } 113 114 U_NAMESPACE_END 115 116 /* UCONFIG_NO_SERVICE */ 117 #endif 118 119