1 /**
2 *******************************************************************************
3 * Copyright (C) 2001-2012, 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
~EventListener()19 EventListener::~EventListener() {}
20 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EventListener)
21
22 static UMutex notifyLock = U_MUTEX_INITIALIZER;
23
ICUNotifier(void)24 ICUNotifier::ICUNotifier(void)
25 : listeners(NULL)
26 {
27 }
28
~ICUNotifier(void)29 ICUNotifier::~ICUNotifier(void) {
30 {
31 Mutex lmx(¬ifyLock);
32 delete listeners;
33 listeners = NULL;
34 }
35 }
36
37
38 void
addListener(const EventListener * l,UErrorCode & status)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
removeListener(const EventListener * l,UErrorCode & status)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
notifyChanged(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