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