diff options
Diffstat (limited to 'intl/icu/source/common/servnotf.cpp')
-rw-r--r-- | intl/icu/source/common/servnotf.cpp | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/intl/icu/source/common/servnotf.cpp b/intl/icu/source/common/servnotf.cpp new file mode 100644 index 0000000000..b2ad663a48 --- /dev/null +++ b/intl/icu/source/common/servnotf.cpp @@ -0,0 +1,122 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/** + ******************************************************************************* + * Copyright (C) 2001-2012, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_SERVICE + +#include "servnotf.h" +#ifdef NOTIFIER_DEBUG +#include <stdio.h> +#endif + +U_NAMESPACE_BEGIN + +EventListener::~EventListener() {} +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EventListener) + +static UMutex notifyLock; + +ICUNotifier::ICUNotifier() +: listeners(nullptr) +{ +} + +ICUNotifier::~ICUNotifier() { + { + Mutex lmx(¬ifyLock); + delete listeners; + listeners = nullptr; + } +} + + +void +ICUNotifier::addListener(const EventListener* l, UErrorCode& status) +{ + if (U_SUCCESS(status)) { + if (l == nullptr) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return; + } + + if (acceptsListener(*l)) { + Mutex lmx(¬ifyLock); + if (listeners == nullptr) { + LocalPointer<UVector> lpListeners(new UVector(5, status), status); + if (U_FAILURE(status)) { + return; + } + listeners = lpListeners.orphan(); + } else { + for (int i = 0, e = listeners->size(); i < e; ++i) { + const EventListener* el = (const EventListener*)(listeners->elementAt(i)); + if (l == el) { + return; + } + } + } + + listeners->addElement((void*)l, status); // cast away const + } +#ifdef NOTIFIER_DEBUG + else { + fprintf(stderr, "Listener invalid for this notifier."); + exit(1); + } +#endif + } +} + +void +ICUNotifier::removeListener(const EventListener *l, UErrorCode& status) +{ + if (U_SUCCESS(status)) { + if (l == nullptr) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return; + } + + { + Mutex lmx(¬ifyLock); + if (listeners != nullptr) { + // identity equality check + for (int i = 0, e = listeners->size(); i < e; ++i) { + const EventListener* el = (const EventListener*)listeners->elementAt(i); + if (l == el) { + listeners->removeElementAt(i); + if (listeners->size() == 0) { + delete listeners; + listeners = nullptr; + } + return; + } + } + } + } + } +} + +void +ICUNotifier::notifyChanged() +{ + Mutex lmx(¬ifyLock); + if (listeners != nullptr) { + for (int i = 0, e = listeners->size(); i < e; ++i) { + EventListener* el = (EventListener*)listeners->elementAt(i); + notifyListener(*el); + } + } +} + +U_NAMESPACE_END + +/* UCONFIG_NO_SERVICE */ +#endif + |