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
~EventListener()21 EventListener::~EventListener() {}
22 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EventListener)
23
24 static UMutex notifyLock;
25
ICUNotifier()26 ICUNotifier::ICUNotifier()
27 : listeners(nullptr)
28 {
29 }
30
~ICUNotifier()31 ICUNotifier::~ICUNotifier() {
32 {
33 Mutex lmx(¬ifyLock);
34 delete listeners;
35 listeners = nullptr;
36 }
37 }
38
39
40 void
addListener(const EventListener * l,UErrorCode & status)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 = (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
removeListener(const EventListener * l,UErrorCode & status)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 = (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
notifyChanged()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 = (EventListener*)listeners->elementAt(i);
113 notifyListener(*el);
114 }
115 }
116 }
117
118 U_NAMESPACE_END
119
120 /* UCONFIG_NO_SERVICE */
121 #endif
122
123