1/** 2 ******************************************************************************* 3 * Copyright (C) 2001-2011, 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 17U_NAMESPACE_BEGIN 18 19EventListener::~EventListener() {} 20UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EventListener) 21 22static UMTX notifyLock; 23 24ICUNotifier::ICUNotifier(void) 25: listeners(NULL) 26{ 27} 28 29ICUNotifier::~ICUNotifier(void) { 30 { 31 Mutex lmx(¬ifyLock); 32 delete listeners; 33 listeners = NULL; 34 } 35} 36 37 38void 39ICUNotifier::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 71void 72ICUNotifier::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 100void 101ICUNotifier::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 114U_NAMESPACE_END 115 116/* UCONFIG_NO_SERVICE */ 117#endif 118 119