Home | History | Annotate | Download | only in common
      1 /**
      2  *******************************************************************************
      3  * Copyright (C) 2001-2006, 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 
     19 EventListener::~EventListener() {}
     20 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EventListener)
     21 
     22 ICUNotifier::ICUNotifier(void)
     23 : notifyLock(0), listeners(NULL)
     24 {
     25     umtx_init(&notifyLock);
     26 }
     27 
     28 ICUNotifier::~ICUNotifier(void) {
     29     {
     30         Mutex lmx(&notifyLock);
     31         delete listeners;
     32         listeners = NULL;
     33     }
     34     umtx_destroy(&notifyLock);
     35 }
     36 
     37 
     38 void
     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(&notifyLock);
     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
     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(&notifyLock);
     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
    101 ICUNotifier::notifyChanged(void)
    102 {
    103     if (listeners != NULL) {
    104         Mutex lmx(&notifyLock);
    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