servnotf.cpp 3.1 KB

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