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
19U_NAMESPACE_BEGIN
20
21EventListener::~EventListener() {}
22UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EventListener)
23
24static UMutex notifyLock;
25
26ICUNotifier::ICUNotifier(void)
27: listeners(NULL)
28{
29}
30
31ICUNotifier::~ICUNotifier(void) {
32 {
33 Mutex lmx(&notifyLock);
34 delete listeners;
35 listeners = NULL;
36 }
37}
38
39
40void
41ICUNotifier::addListener(const EventListener* l, UErrorCode& status)
42{
43 if (U_SUCCESS(status)) {
44 if (l == NULL) {
45 status = U_ILLEGAL_ARGUMENT_ERROR;
46 return;
47 }
48
49 if (acceptsListener(*l)) {
50 Mutex lmx(&notifyLock);
51 if (listeners == NULL) {
52 listeners = new UVector(5, status);
53 } else {
54 for (int i = 0, e = listeners->size(); i < e; ++i) {
55 const EventListener* el = (const EventListener*)(listeners->elementAt(i));
56 if (l == el) {
57 return;
58 }
59 }
60 }
61
62 listeners->addElement((void*)l, status); // cast away const
63 }
64#ifdef NOTIFIER_DEBUG
65 else {
66 fprintf(stderr, "Listener invalid for this notifier.");
67 exit(1);
68 }
69#endif
70 }
71}
72
73void
74ICUNotifier::removeListener(const EventListener *l, UErrorCode& status)
75{
76 if (U_SUCCESS(status)) {
77 if (l == NULL) {
78 status = U_ILLEGAL_ARGUMENT_ERROR;
79 return;
80 }
81
82 {
83 Mutex lmx(&notifyLock);
84 if (listeners != NULL) {
85 // identity equality check
86 for (int i = 0, e = listeners->size(); i < e; ++i) {
87 const EventListener* el = (const EventListener*)listeners->elementAt(i);
88 if (l == el) {
89 listeners->removeElementAt(i);
90 if (listeners->size() == 0) {
91 delete listeners;
92 listeners = NULL;
93 }
94 return;
95 }
96 }
97 }
98 }
99 }
100}
101
102void
103ICUNotifier::notifyChanged(void)
104{
105 if (listeners != NULL) {
106 Mutex lmx(&notifyLock);
107 if (listeners != NULL) {
108 for (int i = 0, e = listeners->size(); i < e; ++i) {
109 EventListener* el = (EventListener*)listeners->elementAt(i);
110 notifyListener(*el);
111 }
112 }
113 }
114}
115
116U_NAMESPACE_END
117
118/* UCONFIG_NO_SERVICE */
119#endif
120
121